
FastAPI 扩展 OpenAPI自定义 /openapi.json 生成流程的完整指南【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi导读本文围绕 FastAPI 中如何修改自动生成的 OpenAPI Schema 展开先剖析/openapi.json的默认生成链路.openapi()→.openapi_schema缓存 →fastapi.openapi.utils.get_openapi再以“给 ReDoc 文档注入自定义 Logo”为例演示如何用同一个工具函数重新生成 Schema、按需覆盖字段并缓存与替换默认方法。读完本文你将能够在不改动框架源码的前提下为任何 FastAPI 应用定制 OpenAPI 输出例如注入厂商扩展、调整info元数据、控制servers与tags等。默认的 OpenAPI 生成流程The normal process每一个FastAPI应用实例都带有一个.openapi()方法它负责返回应用的 OpenAPI Schema。默认流程如下在创建应用对象时setup()阶段FastAPI 会为/openapi.json或你在openapi_url中配置的其他路径注册一个路径操作path operation见 applications.py。该路径操作只是把应用.openapi()方法的返回值包装成JSONResponse返回并在存在反向代理root_path时自动补充servers前缀。默认的.openapi()方法先检查属性.openapi_schema是否已有内容有则直接返回没有则调用fastapi.openapi.utils.get_openapi生成并把结果缓存到.openapi_schema。从源码看这一缓存并不是无条件的applications.py中.openapi()会比对路由版本self.router._get_routes_version()只有「缓存为空」或「路由版本已变化」时才重新生成applications.py。也就是说即使你注册了新路由下一次请求/openapi.json时 Schema 也会自动刷新缓存始终与当前路由保持一致。get_openapi()的关键参数get_openapi()定义在 utils.py其核心参数如下参数说明默认值titleOpenAPI 标题显示在文档中必填versionAPI 版本例如2.5.0必填openapi_version使用的 OpenAPI 规范版本3.1.0最新summaryAPI 的简短摘要NonedescriptionAPI 描述可包含 Markdown会渲染在文档中Noneroutes应用路由取自app.routes用于收集已注册的路径操作含被 include 的 Router必填webhooksWebhook 路由取自app.webhooks.routesNonetags顶层tags数组NoneserversOpenAPIservers服务器列表Noneterms_of_service服务条款 URL写入info.termsOfServiceNonecontact联系人信息写入info.contactNonelicense_info许可证信息写入info.licenseNoneseparate_input_output_schemas是否为输入/输出模型生成独立的 SchemaTrueexternal_docs外部文档链接写入顶层externalDocsNone技术细节tipapp.routes是更低层的路由树其中可能包含 FastAPI 为被 include 的 Router 内部使用的路由候选route candidates并非只有最终的APIRoute对象。你仍然可以直接把app.routes传给get_openapi()——FastAPI 会遍历这棵路由树收集真正生效的路径操作。注意notesummary参数需要 OpenAPI 3.1.0 及以上版本并由 FastAPI 0.99.0 及以上版本支持。get_openapi()内部的组装逻辑utils.py大致为先构建info对象title/version必填summary、description、termsOfService、contact、license按需写入再遍历路由收集paths、securitySchemes与组件定义最后把paths、webhooks、tags、externalDocs等组装成完整字典经jsonable_encoder(OpenAPI(**output))序列化后返回。覆盖默认值注入 ReDoc 的自定义 Logo 扩展理解了默认流程后就可以用同一个工具函数重新生成 Schema并覆盖其中任意部分。官方示例以 ReDoc 的x-logo厂商扩展为例为文档页注入自定义 Logo。第一步照常编写 FastAPI 应用先按平时的习惯写好整个应用例如在 tutorial001_py310.py 中定义一个GET /items/接口from fastapi import FastAPI from fastapi.openapi.utils import get_openapi app FastAPI() app.get(/items/) async def read_items(): return [{name: Foo}]第二步生成 OpenAPI Schema定义一个custom_openapi()函数在其中调用同一个工具函数生成 Schemadef custom_openapi(): if app.openapi_schema: return app.openapi_schema openapi_schema get_openapi( titleCustom title, version2.5.0, summaryThis is a very custom OpenAPI schema, descriptionHeres a longer description of the custom **OpenAPI** schema, routesapp.routes, ) ...注意这里重写了title、version、summary、description你可以按需传入前面表格中的任意参数例如servers[{url: https://api.example.com}]或tags[{name: items, description: Item operations}]。第三步修改 OpenAPI Schemaget_openapi()返回的是普通字典直接操作即可。这里在info对象上加入x-logo扩展让 ReDoc 显示自定义 Logoopenapi_schema[info][x-logo] { url: https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png }x-logo是 ReDoc 的厂商扩展vendor extensionOpenAPI 规范允许所有x-前缀的字段存在因此这种覆盖方式是规范兼容的。你同样可以扩展其他任何info子字段或顶层字段。第四步缓存 Schema把生成结果写回.openapi_schema属性作为“缓存”避免每次用户打开 API 文档时都重新生成一遍app.openapi_schema openapi_schema return app.openapi_schema这样 Schema 只在首次请求时生成一次后续请求直接复用缓存。前面提到默认实现中.openapi()还带路由版本比对而这里的自定义实现做了简化——如果你后续动态注册了新路由且希望 Schema 自动更新可以在函数里自行加入类似的版本判断逻辑。第五步替换.openapi()方法最后把应用的方法替换为你的新函数FastAPI 内部的/openapi.json路径操作与 Swagger UI / ReDoc 都会自动走新实现app.openapi custom_openapi验证效果运行应用后访问 http://127.0.0.1:8000/redoc可以看到文档页使用了自定义 Logo本例中是 FastAPI 的 Logo而不是默认样式。源码与测试层面的印证这套用法在仓库中有完整的实现与测试支撑get_openapi()的实现位于 fastapi/openapi/utils.py其中对路由的遍历通过routing.iter_route_contexts(routes)完成逐一调用get_openapi_path()生成每个路径操作的 OpenAPI 描述并统一收集securitySchemes与模型定义最终排序写入components.schemas。.openapi()默认实现位于 fastapi/applications.py它把应用构造参数title、version、summary、servers、webhooks、tags、separate_input_output_schemas等一一透传给get_openapi()这就是为什么替换方法后需要自行把需要的参数重新传进去。注册/openapi.json路由位于 fastapi/applications.py 的setup()方法它会以include_in_schemaFalse注册该路由并在有root_path反向代理前缀时把根路径写入servers。测试用例位于 tests/test_tutorial/test_extending_openapi/test_tutorial001.py它通过TestClient断言/openapi.json返回的 Schema 精确匹配快照——info中包含了自定义的title、summary、description、version以及x-logo同时路径/items/下的GET操作也被完整收集测试还连续请求两次/openapi.json验证了自定义缓存生效两次返回完全一致。这证明“生成 → 修改 → 缓存 → 替换方法”的整套流程是可运行、可回归验证的。常见应用场景与注意事项注入厂商扩展除x-logo外还可按需注入x-codeSamples、x-tagGroups等 ReDoc/Swagger UI 扩展操作方式与上文完全一致。定制文档元数据动态修改info.description、info.contact、info.license或按部署环境切换servers列表。统一调整操作 ID 或标签可以在custom_openapi()里对生成后的paths字典做二次遍历改写例如规范化operationIdpaths的键即为路由路径模板如/items/值内是各 HTTP 方法的操作对象。缓存与动态路由自定义实现返回.openapi_schema时要注意它不再像默认实现那样自动比对路由版本若你的应用会在运行期动态添加路由建议在函数内保留类似_openapi_routes_version的比对逻辑。文档页面不受影响替换.openapi()方法后/docsSwagger UI与/redoc的 HTML 页面本身不需要任何改动它们都从同一个 OpenAPI Schema 渲染因此自定义内容会同步出现在两种文档中。小结FastAPI 的 OpenAPI 生成链路设计得高度可替换默认实现把「生成get_openapi— 缓存.openapi_schema— 输出/openapi.json」三个环节解耦开发者只需覆盖.openapi()方法即可完全接管 Schema 的生成与定制。以x-logo为例的完整流程——复用工具函数生成、字典式修改、写回缓存、替换方法——既简单又规范兼容是扩展 API 文档能力的通用模板。相关参考文件示例源码 docs_src/extending_openapi/tutorial001_py310.py、核心实现 fastapi/openapi/utils.py 与 fastapi/applications.py、测试用例 tests/test_tutorial/test_extending_openapi/test_tutorial001.py。【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考