使用 fumadocs-python 为 Python 库自动生成 API 文档:从两条命令到运行时内容源

发布时间:2026/9/15 17:55:58
使用 fumadocs-python 为 Python 库自动生成 API 文档:从两条命令到运行时内容源 使用 fumadocs-python 为 Python 库自动生成 API 文档从两条命令到运行时内容源【免费下载链接】fumadocsThe beautiful flexible React.js docs framework.项目地址: https://gitcode.com/GitHub_Trending/fu/fumadocs本篇技术指南围绕 Fumadocs 仓库中的examples/python示例与packages/pythonfumadocs-python扩展包展开完整讲解如何用一条 CLI 命令把 Python 模块的源码与 docstring 提取为结构化的httpx.json再通过createPython()在 Next.js 应用中把 JSON 渲染成一整套带 Tabs、参数卡片、源码折叠与搜索索引的 API 文档页面。读完本文你将掌握 fumadocs-python 的生成命令、JSON 数据结构、运行时内容源配置与页面渲染管线并能在自己的文档项目中复现这一套两步上手的 Python API 文档方案。一个只有两步的文档生成流程examples/python是一个最小化的 Next.js 示例应用它的 README.md 用两行命令概括了整个流程运行pnpm python:generate用 Python 在本地生成httpx.json运行pnpm dev启动文档站点。第一行命令实际上是一个二合一脚本定义在 examples/python/package.json 中pnpm python:generate # 等价于 pip3 install ./node_modules/fumadocs-python fumapy-generate httpxpip3 install ./node_modules/fumadocs-python把fumadocs-python包内含 Python 工具fumapy安装到当前 Python 环境中fumapy-generate httpx调用 CLI 扫描httpx模块并在当前目录输出httpx.json。生成完成后createPython({ file: ./httpx.json })会读取该 JSON将其作为 Fumadocs 的内容源驱动/docs下的所有页面见 examples/python/lib/source.ts。fumapy-generate从 Python 源码到结构化 JSONfumapy-generate是fumapy包通过 pyproject.toml 暴露的命令行入口[project.scripts] fumapy-generate fumapy:generate它的实现位于 packages/python/fumapy/init.py底层使用 Griffegriffe 1.13.0, 2.0.0做静态解析并加载griffe_typingdoc扩展增强类型信息。CLI 支持三个参数参数短选项默认值说明module—必填要生成文档的模块名例如httpx--dir/-d-d.JSON 输出目录默认当前目录--docstring-style/-s-sgoogledocstring 解析风格可选google、numpy、sphinx例如把结果输出到docs/api目录并使用 NumPy 风格解析fumapy-generate httpx -d docs/api -s numpygenerate()的核心调用链为griffe.load(module, docstring_parserstyle, store_sourceTrue, extensions...)解析模块 →parse_module()递归提取模块、类、函数 →json.dump(..., clsCustomEncoder, indent2, fullTrue)写出 JSON。STORE_SOURCE True意味着原始源码会被保存进 JSON供页面上的Source Code折叠面板使用。JSON 结构与页面一一对应的数据模型生成的httpx.json遵循 packages/python/fumapy/mksource/models.py 定义的 TypedDict 结构顶层Module包含name/path/filepath模块名、点分隔路径、源文件路径description/docstring模块摘要与按 kind 分段的 docstring 内容attributes模块级属性名称、注解、描述、值modules/classes/functions递归的子树结构version对包package尝试通过importlib.metadata.version()获取版本号拿不到则省略。Class额外记录构造参数parameters、inherited_members继承成员按父路径分组与完整sourceFunction则记录signature、parameters、returns与source。Docstring是一组带kind的段落常见的kind包括text、parameters、returns、attributes、admonition、examples、raises、yields等。你可以直接查看仓库中的真实样例 packages/python/test/fixtures/demo.json一个名为demo的包包含GitInfo类、logger子模块内含Logger类与utils模块覆盖了属性描述、__init__构造器、上下文管理器、admonition/examples等几乎所有段落类型是理解数据结构的绝佳参考。docstring 如何被规整成页面数据parse_module/parse_class/parse_function见 packages/python/fumapy/mksource/document_module.py把 Griffe 的解析结果转换为上述模型其中 simplify_docstring.py 负责关键的分拣逻辑首个text段落作为descriptionparameters段落会按真实函数签名顺序重新排序并用 docstring 中记录的描述、注解补齐签名参数returns、attributes同理优先使用 docstring 中的信息缺失时回退到签名/属性本身其余段落原样保留到docstring的remainder。此外 utils.py 的build_signature()会重建签名文本跳过隐式的self/cls静态方法除外、正确处理/仅位置参数、*仅关键字参数、*args/**kwargs与默认值并追加- 返回注解。把 JSON 变成 Fumadocs 内容源fumadocs-python的 TypeScript 侧入口是 packages/python/src/index.ts它导出createPython、convert、write以及相关类型。最核心的createPython()定义在 packages/python/src/source.tsexport interface PythonConfig { /** path to the JSON file generated by fumapy-generate */ file: string; /** * group generated pages in a directory: * - module: the name of the root module * - none: place them at the root of the source * defaultValue module */ groupBy?: PythonGroupBy; remarkPlugins?: PluggableList; rehypePlugins?: PluggableList; rehypeCodeOptions?: RehypeCodeOptions | false; }examples/python中的应用是这样接入的examples/python/lib/source.tsimport { dynamicLoader } from fumadocs-core/source; import { createPython } from fumadocs-python; const python createPython({ file: ./httpx.json, // serve pages at the root of /docs, instead of grouped under /docs/httpx groupBy: none, }); const pythonLoader dynamicLoader(python.dynamicSource(), { baseUrl: /docs, plugins: [python.loaderPlugin()], }); export function getSource() { return pythonLoader.get(); }几点关键配置说明filefumapy-generate生成的 JSON 路径运行时通过fs.readFile读取source.tsgroupBymodule默认会把所有页面放进以根模块名命名的目录如/docs/httpx/...none则把页面放在/docs根下根模块页面变成index.mdx。该选项在convert()中同样可用convert.tsdynamicSource()/staticSource()分别返回 Fumadocs 的 DynamicSource 与 StaticSource前者按需懒加载、后者一次性构建二者的页面构建逻辑完全一致source.tsloaderPlugin()为页面树中的生成页面添加module/class徽标plugin.tsx文件夹节点如logger保持原样不加徽标。页面如何生成module 页、class 页与 TabsJSON 并不是直接被渲染的。createPython内部会把 ModuleInterface 交给 build.ts 的buildPages()每个模块和每个类各生成一页路径由path.replaceAll(., /)转换而来如httpx._client→httpx/_client。模块页先输出模块描述与属性然后用Tabs组织三个标签页——Class卡片列表、Functions函数卡片、Modules子模块卡片卡片间通过href互链build.ts类页__init__构造器被排在函数列表最前承担参数展示的职责build.ts函数由PyFunction卡片承载包含函数名、PyFunctionReturn返回块、参数列表PyParameter以及可折叠的PySourceCode源码build.ts。docstring 中的admonition会映射为Calloutexamples段落会被拆成python代码块由于 docstring 并非 HTML解析时还特意禁用了 HTML 流防止等字符被误解析build.ts。渲染器不执行 JS 的安全渲染页面编译通过 unified 管线完成remarkHeading → remarkStructure → remarkRehypepassThrough MDX JSX 节点→ rehypeCodeShiki 高亮fallbackLanguage 为 plaintext→ rehypeTocsource.ts。值得注意的设计在 renderer.ts生成的 HAST 树只包含组件名与字符串字面量渲染时通过自定义Evaluater把Identifier映射为真实组件、ArrayExpression/Literal求值为数据不执行任何 JavaScript 程序因此生成内容不会带来代码执行风险。render(components?)的组件合并顺序为Fumadocs UI 默认 MDX 组件 →fumadocs-python/components→ 你传入的自定义组件后者优先级最高。内置的 Python 专属组件都定义在 packages/python/src/components/index.tsxPyFunction、PyParameter、PyAttributes/PyAttribute、PySourceCodeBase UI Collapsible 折叠、PyFunctionReturn并复导出Tabs/Tab。徽标配色由 packages/python/src/badge.ts 统一管理func/attribute/class/module四色。在 Next.js 中组装页面examples/python的页面结构展示了完整的接入方式app/docs/[[...slug]]/page.tsxsource.getPage(params.slug)查找页面不存在时notFound()通过(await page.data.load()).render()拿到body与toc交给DocsPage同时实现generateStaticParams与generateMetadata做静态导出与标题元数据app/docs/layout.tsx用source.getPageTree()生成左侧目录树交给DocsLayoutapp/api/search/route.ts一行代码接入全文搜索——createFromSource(getSource)基于structuredData由remarkStructure收集构建搜索接口。由于页面是懒编译的page.data.load()会把编译结果缓存起来同一页面在多次访问与搜索索引生成中只编译一次模块/类之间的链接则在编译时通过 loader 解析出真实 URLsource.ts。备选方案把 JSON 落盘为静态 MDX除了运行时内容源fumadocs-python还提供convert()与write()convert.ts可以把 JSON 一次性转换为磁盘上的 MDX 文件再走 Fumadocs 常规的文件内容源import { convert, write } from fumadocs-python; const files convert(content, { baseUrl: /docs }); await write(files, content/docs);convert()与createPython共享同一套buildPages页面构建器因此两种方式产出的页面结构完全一致write()会为每个文件补上--- title: ... ---frontmatter 后写入convert.ts。测试 packages/python/test/index.test.ts 验证了这两种路径convert生成的 MDX 文件快照、staticSource的页面列表、groupBy: none的根目录化、懒编译只执行一次、链接可通过getPageByHref解析、loaderPlugin 徽标以及 docstring 中 Markdown 与尖括号的转义行为。版本演进三个里程碑从 packages/python/CHANGELOG.md 可以看到该包的演进脉络1.0.0引入运行时内容源createPython()不再需要先生成 MDX 文件convert()与它共享页面构建器1.0.1新增groupBy选项控制页面是否按根模块名分组1.0.2内部重构用cn替换cnfast。结合示例中的package.jsonexamples/python/package.json当前版本还要求fumadocs-core、fumadocs-ui作为 peerDependenciesfumadocs-core ^16.8.0、fumadocs-ui 15.x || 16.x、react 19.xPython 侧则要求Python 3.10。快速上手清单在文档项目中安装fumadocs-pythonworkspace 内可参考 packages/python/package.json 的依赖声明外部项目请按 npm 安装常规流程引入运行fumapy-generate module或像示例一样封装成pnpm python:generate得到httpx.json在lib/source.ts中用createPython({ file: ./httpx.json })创建内容源用dynamicLoader/loader挂到/docs路由在app/docs/[[...slug]]/page.tsx中调用page.data.load().then(r r.render())渲染用getPageTree()生成侧边栏通过createFromSource一键接入站内搜索。整个流程无需手写任何 MDX 文件Python 代码与 docstring 就是文档的单一事实来源——这也正是examples/python用两行命令所演示的核心价值。【免费下载链接】fumadocsThe beautiful flexible React.js docs framework.项目地址: https://gitcode.com/GitHub_Trending/fu/fumadocs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考