展 OpenAPI:自定義 /openapi.json 生成流程的完整指南)
FastAPI 擴(kuò)展 OpenAPI自定義 /openapi.json 生成流程的完整指南【免費(fèi)下載鏈接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production項(xiàng)目地址: https://gitcode.com/GitHub_Trending/fa/fastapi導(dǎo)讀本文圍繞 FastAPI 中如何修改自動(dòng)生成的 OpenAPI Schema 展開先剖析/openapi.json的默認(rèn)生成鏈路.openapi()→.openapi_schema緩存 →fastapi.openapi.utils.get_openapi再以“給 ReDoc 文檔注入自定義 Logo”為例演示如何用同一個(gè)工具函數(shù)重新生成 Schema、按需覆蓋字段并緩存與替換默認(rèn)方法。讀完本文你將能夠在不改動(dòng)框架源碼的前提下為任何 FastAPI 應(yīng)用定制 OpenAPI 輸出例如注入廠商擴(kuò)展、調(diào)整info元數(shù)據(jù)、控制servers與tags等。默認(rèn)的 OpenAPI 生成流程The normal process每一個(gè)FastAPI應(yīng)用實(shí)例都帶有一個(gè).openapi()方法它負(fù)責(zé)返回應(yīng)用的 OpenAPI Schema。默認(rèn)流程如下在創(chuàng)建應(yīng)用對(duì)象時(shí)setup()階段FastAPI 會(huì)為/openapi.json或你在openapi_url中配置的其他路徑注冊(cè)一個(gè)路徑操作path operation見 applications.py。該路徑操作只是把應(yīng)用.openapi()方法的返回值包裝成JSONResponse返回并在存在反向代理root_path時(shí)自動(dòng)補(bǔ)充servers前綴。默認(rèn)的.openapi()方法先檢查屬性.openapi_schema是否已有內(nèi)容有則直接返回沒(méi)有則調(diào)用fastapi.openapi.utils.get_openapi生成并把結(jié)果緩存到.openapi_schema。從源碼看這一緩存并不是無(wú)條件的applications.py中.openapi()會(huì)比對(duì)路由版本self.router._get_routes_version()只有「緩存為空」或「路由版本已變化」時(shí)才重新生成applications.py。也就是說(shuō)即使你注冊(cè)了新路由下一次請(qǐng)求/openapi.json時(shí) Schema 也會(huì)自動(dòng)刷新緩存始終與當(dāng)前路由保持一致。get_openapi()的關(guān)鍵參數(shù)get_openapi()定義在 utils.py其核心參數(shù)如下參數(shù)說(shuō)明默認(rèn)值titleOpenAPI 標(biāo)題顯示在文檔中必填versionAPI 版本例如2.5.0必填openapi_version使用的 OpenAPI 規(guī)范版本3.1.0最新summaryAPI 的簡(jiǎn)短摘要NonedescriptionAPI 描述可包含 Markdown會(huì)渲染在文檔中Noneroutes應(yīng)用路由取自app.routes用于收集已注冊(cè)的路徑操作含被 include 的 Router必填webhooksWebhook 路由取自app.webhooks.routesNonetags頂層tags數(shù)組NoneserversOpenAPIservers服務(wù)器列表Noneterms_of_service服務(wù)條款 URL寫入info.termsOfServiceNonecontact聯(lián)系人信息寫入info.contactNonelicense_info許可證信息寫入info.licenseNoneseparate_input_output_schemas是否為輸入/輸出模型生成獨(dú)立的 SchemaTrueexternal_docs外部文檔鏈接寫入頂層externalDocsNone技術(shù)細(xì)節(jié)tipapp.routes是更低層的路由樹其中可能包含 FastAPI 為被 include 的 Router 內(nèi)部使用的路由候選route candidates并非只有最終的APIRoute對(duì)象。你仍然可以直接把a(bǔ)pp.routes傳給get_openapi()——FastAPI 會(huì)遍歷這棵路由樹收集真正生效的路徑操作。注意notesummary參數(shù)需要 OpenAPI 3.1.0 及以上版本并由 FastAPI 0.99.0 及以上版本支持。get_openapi()內(nèi)部的組裝邏輯utils.py大致為先構(gòu)建info對(duì)象title/version必填summary、description、termsOfService、contact、license按需寫入再遍歷路由收集paths、securitySchemes與組件定義最后把paths、webhooks、tags、externalDocs等組裝成完整字典經(jīng)jsonable_encoder(OpenAPI(**output))序列化后返回。覆蓋默認(rèn)值注入 ReDoc 的自定義 Logo 擴(kuò)展理解了默認(rèn)流程后就可以用同一個(gè)工具函數(shù)重新生成 Schema并覆蓋其中任意部分。官方示例以 ReDoc 的x-logo廠商擴(kuò)展為例為文檔頁(yè)注入自定義 Logo。第一步照常編寫 FastAPI 應(yīng)用先按平時(shí)的習(xí)慣寫好整個(gè)應(yīng)用例如在 tutorial001_py310.py 中定義一個(gè)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定義一個(gè)custom_openapi()函數(shù)在其中調(diào)用同一個(gè)工具函數(shù)生成 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你可以按需傳入前面表格中的任意參數(shù)例如servers[{url: https://api.example.com}]或tags[{name: items, description: Item operations}]。第三步修改 OpenAPI Schemaget_openapi()返回的是普通字典直接操作即可。這里在info對(duì)象上加入x-logo擴(kuò)展讓 ReDoc 顯示自定義 Logoopenapi_schema[info][x-logo] { url: https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png }x-logo是 ReDoc 的廠商擴(kuò)展vendor extensionOpenAPI 規(guī)范允許所有x-前綴的字段存在因此這種覆蓋方式是規(guī)范兼容的。你同樣可以擴(kuò)展其他任何info子字段或頂層字段。第四步緩存 Schema把生成結(jié)果寫回.openapi_schema屬性作為“緩存”避免每次用戶打開 API 文檔時(shí)都重新生成一遍app.openapi_schema openapi_schema return app.openapi_schema這樣 Schema 只在首次請(qǐng)求時(shí)生成一次后續(xù)請(qǐng)求直接復(fù)用緩存。前面提到默認(rèn)實(shí)現(xiàn)中.openapi()還帶路由版本比對(duì)而這里的自定義實(shí)現(xiàn)做了簡(jiǎn)化——如果你后續(xù)動(dòng)態(tài)注冊(cè)了新路由且希望 Schema 自動(dòng)更新可以在函數(shù)里自行加入類似的版本判斷邏輯。第五步替換.openapi()方法最后把應(yīng)用的方法替換為你的新函數(shù)FastAPI 內(nèi)部的/openapi.json路徑操作與 Swagger UI / ReDoc 都會(huì)自動(dòng)走新實(shí)現(xiàn)app.openapi custom_openapi驗(yàn)證效果運(yùn)行應(yīng)用后訪問(wèn) http://127.0.0.1:8000/redoc可以看到文檔頁(yè)使用了自定義 Logo本例中是 FastAPI 的 Logo而不是默認(rèn)樣式。源碼與測(cè)試層面的印證這套用法在倉(cāng)庫(kù)中有完整的實(shí)現(xiàn)與測(cè)試支撐get_openapi()的實(shí)現(xiàn)位于 fastapi/openapi/utils.py其中對(duì)路由的遍歷通過(guò)routing.iter_route_contexts(routes)完成逐一調(diào)用get_openapi_path()生成每個(gè)路徑操作的 OpenAPI 描述并統(tǒng)一收集securitySchemes與模型定義最終排序?qū)懭隿omponents.schemas。.openapi()默認(rèn)實(shí)現(xiàn)位于 fastapi/applications.py它把應(yīng)用構(gòu)造參數(shù)title、version、summary、servers、webhooks、tags、separate_input_output_schemas等一一透?jìng)鹘oget_openapi()這就是為什么替換方法后需要自行把需要的參數(shù)重新傳進(jìn)去。注冊(cè)/openapi.json路由位于 fastapi/applications.py 的setup()方法它會(huì)以include_in_schemaFalse注冊(cè)該路由并在有root_path反向代理前綴時(shí)把根路徑寫入servers。測(cè)試用例位于 tests/test_tutorial/test_extending_openapi/test_tutorial001.py它通過(guò)TestClient斷言/openapi.json返回的 Schema 精確匹配快照——info中包含了自定義的title、summary、description、version以及x-logo同時(shí)路徑/items/下的GET操作也被完整收集測(cè)試還連續(xù)請(qǐng)求兩次/openapi.json驗(yàn)證了自定義緩存生效兩次返回完全一致。這證明“生成 → 修改 → 緩存 → 替換方法”的整套流程是可運(yùn)行、可回歸驗(yàn)證的。常見應(yīng)用場(chǎng)景與注意事項(xiàng)注入廠商擴(kuò)展除x-logo外還可按需注入x-codeSamples、x-tagGroups等 ReDoc/Swagger UI 擴(kuò)展操作方式與上文完全一致。定制文檔元數(shù)據(jù)動(dòng)態(tài)修改info.description、info.contact、info.license或按部署環(huán)境切換servers列表。統(tǒng)一調(diào)整操作 ID 或標(biāo)簽可以在custom_openapi()里對(duì)生成后的paths字典做二次遍歷改寫例如規(guī)范化operationIdpaths的鍵即為路由路徑模板如/items/值內(nèi)是各 HTTP 方法的操作對(duì)象。緩存與動(dòng)態(tài)路由自定義實(shí)現(xiàn)返回.openapi_schema時(shí)要注意它不再像默認(rèn)實(shí)現(xiàn)那樣自動(dòng)比對(duì)路由版本若你的應(yīng)用會(huì)在運(yùn)行期動(dòng)態(tài)添加路由建議在函數(shù)內(nèi)保留類似_openapi_routes_version的比對(duì)邏輯。文檔頁(yè)面不受影響替換.openapi()方法后/docsSwagger UI與/redoc的 HTML 頁(yè)面本身不需要任何改動(dòng)它們都從同一個(gè) OpenAPI Schema 渲染因此自定義內(nèi)容會(huì)同步出現(xiàn)在兩種文檔中。小結(jié)FastAPI 的 OpenAPI 生成鏈路設(shè)計(jì)得高度可替換默認(rèn)實(shí)現(xiàn)把「生成get_openapi— 緩存.openapi_schema— 輸出/openapi.json」三個(gè)環(huán)節(jié)解耦開發(fā)者只需覆蓋.openapi()方法即可完全接管 Schema 的生成與定制。以x-logo為例的完整流程——復(fù)用工具函數(shù)生成、字典式修改、寫回緩存、替換方法——既簡(jiǎn)單又規(guī)范兼容是擴(kuò)展 API 文檔能力的通用模板。相關(guān)參考文件示例源碼 docs_src/extending_openapi/tutorial001_py310.py、核心實(shí)現(xiàn) fastapi/openapi/utils.py 與 fastapi/applications.py、測(cè)試用例 tests/test_tutorial/test_extending_openapi/test_tutorial001.py?!久赓M(fèi)下載鏈接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production項(xiàng)目地址: https://gitcode.com/GitHub_Trending/fa/fastapi創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考