自動文檔化外部回調 API)
FastAPI 中的 OpenAPI Callbacks用callbacks參數(shù)自動文檔化外部回調 API【免費下載鏈接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production項目地址: https://gitcode.com/GitHub_Trending/fa/fastapi本文圍繞 FastAPI 官方教程docs/de/docs/advanced/openapi-callbacks.mdOpenAPI-Callbacks展開當你的 API 在處理請求后會反過來調用外部開發(fā)者的 API即回調時如何用一個APIRouter加上路徑操作裝飾器的callbacks參數(shù)把這條回調契約完整寫入 OpenAPI 規(guī)范并自動展示在 Swagger UI 的 Callbacks 標簽頁中。讀完后你將能夠定義帶回調文檔的 FastAPI 應用、使用 OpenAPI 3 表達式讓回調路徑動態(tài)引用原始請求中的參數(shù)與 Body 字段并在/docs中驗證外部開發(fā)者應實現(xiàn)的接口形態(tài)。什么是 OpenAPI Callbacks先理解回調場景你可以構建一種 API其中某個路徑操作path operation在處理過程中會觸發(fā)對外部 API的請求——這個外部 API 由別人創(chuàng)建通常正是那個正在使用你 API 的開發(fā)者。這個過程被稱為Callback回調外部開發(fā)者編寫的軟件先向你的 API 發(fā)送請求隨后你的 API 再回撥calls back向該外部 API 發(fā)送一個請求。此時你往往希望文檔化這條外部 API 應有的樣子它應包含哪個路徑操作哪個方法、哪個路徑它應接收什么樣的請求 Body它應返回什么樣的響應。FastAPI 借助 OpenAPI 規(guī)范原生的callbacks字段讓你復用寫 FastAPI 路徑操作的全部經驗來描述這條外部 API——包括參數(shù)聲明、Pydantic 請求體模型和response_model。示例場景一個帶回調的發(fā)票應用用一個具體例子貫穿全文假設你開發(fā)了一個發(fā)票創(chuàng)建應用。每張發(fā)票包含id、title可選、customer、total。你的 API 使用者一個外部開發(fā)者通過 POST 請求在你的 API 中創(chuàng)建一張發(fā)票。隨后你的 API假設性地會把發(fā)票發(fā)送給該外部開發(fā)者的某個客戶收齊款項向 API 使用者外部開發(fā)者發(fā)回一條通知——這一步是通過你的 API 向外部開發(fā)者提供的外部 API 發(fā)送一個 POST 請求實現(xiàn)的這就是回調。下面的教程代碼位于 docs_src/openapi_callbacks/tutorial001_py310.py完整文件僅 51 行本文會逐段講解。普通的 FastAPI 應用部分先看在加入回調之前常規(guī) API 應用長什么樣。它有一個路徑操作接收Invoice請求體并帶一個攜帶回調 URL 的查詢參數(shù)callback_urlfrom fastapi import APIRouter, FastAPI from pydantic import BaseModel, HttpUrl app FastAPI() class Invoice(BaseModel): id: str title: str | None None customer: str total: floatapp.post(/invoices/, callbacksinvoices_callback_router.routes) def create_invoice(invoice: Invoice, callback_url: HttpUrl | None None): Create an invoice. ... # Send the invoice, collect the money, send the notification (the callback) return {msg: Invoice received}這里有一個值得注意的細節(jié)callback_url查詢參數(shù)使用了 Pydantic 的HttpUrl類型見 docs_src/openapi_callbacks/tutorial001_py310.py。從生成的 OpenAPI 測試快照可以看到該參數(shù)被渲染為format: uri、minLength: 1、maxLength: 2083的字符串 schema且因HttpUrl | None而變?yōu)榭蛇xrequired: False見 tests/test_sub_callbacks.py。上面代碼中唯一新的東西是傳給路徑操作裝飾器的參數(shù)callbacksinvoices_callback_router.routes下面詳解。文檔化回調本身真正的回調代碼有多簡單實際的回調實現(xiàn)代碼強烈依賴于你自己的業(yè)務因應用而異可能只是短短一兩行例如callback_url https://example.com/api/v1/invoices/events/ httpx.post(callback_url, json{description: Invoice paid, paid: True})但回調中最關鍵的部分是確保你的 API 使用者外部開發(fā)者正確實現(xiàn)了那條外部 API——按照你的 API 將在回調請求體中發(fā)送的數(shù)據(jù)格式來實現(xiàn)。本教程示例不實現(xiàn)回調本身它可能只有一行代碼只演示文檔化的部分。提示實際的回調本質上就是一個 HTTP 請求。實現(xiàn)時可以使用httpx、requests等任意 HTTP 客戶端庫。這一點也被 FastAPI 源碼的官方文檔字符串明確確認callbacks參數(shù)的 Doc 寫著 List ofpath operationsthat will be used as OpenAPI callbacks.This is only for OpenAPI documentation, the callbacks wont be used directly.It will be added to the generated OpenAPI (e.g. visible at/docs)見 fastapi/applications.py 中include_router的callbacks參數(shù)說明。也就是說回調路由永遠不會被你的應用執(zhí)行它們只用于生成 OpenAPI 文檔。編寫回調文檔代碼把自己想象成外部開發(fā)者用來文檔化回調的代碼不會在你的應用中執(zhí)行你只是需要它來描述那條外部 API 應長什么樣。但你已經知道如何用 FastAPI 輕松創(chuàng)建自動文檔——于是用同樣的方法把外部 API 應實現(xiàn)的路徑操作寫出來即可。提示編寫回調文檔代碼時不妨想象自己就是那個外部開發(fā)者此刻正在實現(xiàn)的不是你的 API而是外部 API。暫時切換到這個視角后參數(shù)放在哪里、Body 用哪個 Pydantic 模型、Response 是什么都會變得直觀。第 1 步創(chuàng)建一個回調APIRouter先新建一個APIRouter用來裝一個或多個回調from fastapi import APIRouter, FastAPI invoices_callback_router APIRouter()見 docs_src/openapi_callbacks/tutorial001_py310.py。第 2 步創(chuàng)建回調路徑操作使用上面創(chuàng)建的APIRouter來定義回調路徑操作它看起來就像一條普通的 FastAPI路徑操作聲明它應接收的 Body如body: InvoiceEvent可以聲明它應返回的響應如response_modelInvoiceEventReceivedclass InvoiceEvent(BaseModel): description: str paid: bool class InvoiceEventReceived(BaseModel): ok: bool invoices_callback_router APIRouter() invoices_callback_router.post( {$callback_url}/invoices/{$request.body.id}, response_modelInvoiceEventReceived ) def invoice_notification(body: InvoiceEvent): pass見 docs_src/openapi_callbacks/tutorial001_py310.py。與普通路徑操作相比有兩個主要區(qū)別函數(shù)體不需要真實代碼因為你的應用永遠不會調用它它只用于文檔化外部 API所以函數(shù)體可以只有pass。路徑可以包含 OpenAPI 3 表達式可以引用發(fā)送到你 API 的原始請求中的變量參數(shù)和請求體部分?;卣{路徑表達式OpenAPI 3 expression回調路徑可以是一個OpenAPI 3 表達式str字符串其中可以內嵌對原始請求內容的引用。本例中是{$callback_url}/invoices/{$request.body.id}表達式的語義{$callback_url}取自原始請求的查詢參數(shù)callback_url{$request.body.id}取自原始請求 JSON Body 中的id字段。完整走一遍數(shù)據(jù)流外部開發(fā)者向你的 API發(fā)送請求https://yourapi.com/invoices/?callback_urlhttps://www.external.org/eventsJSON Body 為{ id: 2expen51ve, customer: Mr. Richie Rich, total: 9999 }你的 API 處理完發(fā)票后在某個時刻會向callback_url即外部 API發(fā)送回調請求https://www.external.org/events/invoices/2expen51ve回調的 JSON Body 大致為{ description: Payment celebration, paid: true }并期望從該外部 API收到如下 JSON 響應{ ok: true }注意最終使用的回調 URL 同時包含了兩處信息——作為查詢參數(shù)傳入的callback_urlhttps://www.external.org/events和 JSON Body 中的發(fā)票id2expen51ve。這正是 OpenAPI 表達式相對靜態(tài)路徑的價值所在。第 3 步把回調 Router 掛到裝飾器上此時所需的回調路徑操作即外部開發(fā)者應在外部 API中實現(xiàn)的接口已經放在回調 Router 里?,F(xiàn)在在你的API 的路徑操作裝飾器上通過callbacks參數(shù)傳入該回調 Router 的.routes屬性app.post(/invoices/, callbacksinvoices_callback_router.routes) def create_invoice(invoice: Invoice, callback_url: HttpUrl | None None): ...見 docs_src/openapi_callbacks/tutorial001_py310.py。提示傳給callbacks的不是 Router 本身invoices_callback_router而是它的.routes屬性即invoices_callback_router.routes。FastAPI 會用這些路由來生成回調的 OpenAPI 文檔。從源碼看callbacks的類型就是list[BaseRoute] | None在路由初始化時被原樣存儲到路由對象上見 fastapi/routing.py 中_populate_api_route_state的callbacks參數(shù)與 fastapi/routing.py 的route.callbacks callbacks。回調如何被寫入 OpenAPI源碼視角OpenAPI 生成時FastAPI 遍歷route.callbacks對每條APIRoute遞歸生成完整的 operation并以回調函數(shù)名為鍵組織成callbacks字典掛到對應 operation 下if route.callbacks: callbacks {} for callback in route.callbacks: if isinstance(callback, routing.APIRoute): ( cb_path, cb_security_schemes, cb_definitions, ) get_openapi_path(route..., ...) callbacks[callback.name] {callback.path: cb_path} operation[callbacks] callbacks見 fastapi/openapi/utils.py。這解釋了兩件事回調 operation 會像普通操作一樣生成operationId、requestBody、responses且回調中引用的 Pydantic 模型InvoiceEvent、InvoiceEventReceived也會進入components/schemas該處同時收集回調路由的模型定義見 fastapi/openapi/utils.py 的get_fields_from_routes(api_route.callbacks)回調的鍵是回調函數(shù)的name如invoice_notification值是以表達式路徑字符串{$callback_url}/invoices/{$request.body.id}注意不是編譯后的正則而是你寫的原始字符串為鍵的 PathItem。測試快照完整印證了這段實現(xiàn)在 tests/test_sub_callbacks.py 中/invoices/的 POST operation 下生成了callbacks對象包含event_callbackGET表達式{$callback_url}/events/{$request.body.title}與invoice_notificationPOST表達式{$callback_url}/invoices/{$request.body.id}兩個回調且requestBody分別引用#/components/schemas/Event與#/components/schemas/InvoiceEvent。進階include_router也可以附加回調除了逐條掛在路徑操作裝飾器上app.include_router(...)和APIRouter本身也接受callbacks參數(shù)可為 Router 內的所有路徑操作附加回調文檔源碼 Doc 說明為 OpenAPI callbacks that should apply to allpath operationsin this router見 fastapi/routing.py 中APIRouter.include_router的參數(shù)定義。上文的 tests/test_sub_callbacks.py 正是這個用法POST /invoices/自帶callbacksinvoices_callback_router.routes而app.include_router(subrouter, callbacksevents_callback_router.routes)又追加了一個event_callback——兩個來源的回調最終合并出現(xiàn)在同一 operation 的callbacks中。從源碼結構看_RouterIncludeContext在 include 鏈路上會持續(xù)合并父級與子級的 callbacks見 fastapi/routing.py 的callbacks: list[BaseRoute]字段及 fastapi/routing.py 的合并邏輯。在/docs中驗證啟動應用并訪問http://127.0.0.1:8000/docs你會看到 Swagger UI 中該路徑操作多出一個Callbacks標簽頁展示外部 API應有的樣子從截圖中可以看到Callbacks 區(qū)塊以回調函數(shù)名invoice_notification為標題方法為POST路徑顯示為表達式原文{$callback_url}/invoices/{$request.body.id}Request body標記為 required內容為InvoiceEvent的示例值description: string、paid: trueResponses列出 200 等狀態(tài)碼。這正是給外部開發(fā)者看的契約照著這個結構實現(xiàn)一個接收InvoiceEvent并返回InvoiceEventReceived的接口即可正確接收你的回調。小結關鍵要點回顧要點說明依據(jù)callbacks參數(shù)傳入list[BaseRoute]通常為某callback_router.routes而非 Router 本身fastapi/routing.py、docs_src/openapi_callbacks/tutorial001_py310.py回調只為文檔回調路徑操作不會被應用執(zhí)行僅用于生成 OpenAPI 文檔函數(shù)體可passfastapi/applications.py表達式路徑回調路徑可用{$參數(shù)名}與{$request.body.字段}引用原始請求fastapi/openapi/utils.py、tests/test_sub_callbacks.py掛接位置路徑操作裝飾器app.post(..., callbacks...)與include_router(..., callbacks...)均可fastapi/routing.pycallback_url類型用 PydanticHttpUrl聲明查詢參數(shù)OpenAPI 中渲染為format: uri且可選tests/test_sub_callbacks.py驗證方式訪問/docs查看 Callbacks 標簽頁或對比/openapi.json中 operation 的callbacks字段tests/test_sub_callbacks.py參考文件教程文檔 docs/de/docs/advanced/openapi-callbacks.md、示例代碼 docs_src/openapi_callbacks/tutorial001_py310.py、核心實現(xiàn) fastapi/openapi/utils.py 與 fastapi/routing.py、測試 tests/test_sub_callbacks.py。【免費下載鏈接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production項目地址: https://gitcode.com/GitHub_Trending/fa/fastapi創(chuàng)作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考