這是一個相當高級的功能。 您可能可以跳過它。
如果您只是在遵循教程-用戶指南,則可以跳過本節。
如果您已經知道需要修改生成的OpenAPI模式,請繼續閱讀。
在某些情況下,您可能需要修改生成的OpenAPI模式。
在本節中,您將看到如何。
正常的過程
正常(默認)過程如下。
甲 FastAPI
應用(例如)具有 .openapi()
被預期返回的OpenAPI模式方法。
由於應用程序創建對象,一個部分 路徑運行 的 /openapi.json
(或者你設置你的 openapi_url
)被注冊。
它只是返回帶有應用程序 .openapi()
方法 結果的JSON響應 。
默認情況下,該方法的 .openapi()
作用是檢查屬性 .openapi_schema
以查看其是否包含內容並返回它們。
如果不是,它將使用處的實用程序功能生成它們 fastapi.openapi.utils.get_openapi
。
該函數 get_openapi()
接收作為參數:
title
:文檔中顯示的OpenAPI標題。version
:您的API版本,例如2.5.0
。openapi_version
:使用的OpenAPI規范的版本。 默認情況下,最新的:3.0.2
。description
:您的API的描述。routes
:路由列表,它們是每個已注冊 路徑操作 。 它們取自app.routes
。openapi_prefix
:要在您的OpenAPI中使用的URL前綴。
重寫默認
使用以上信息,您可以使用相同的實用程序功能來生成OpenAPI架構並覆蓋所需的每個部分。
例如,讓我們添加 ReDoc的OpenAPI擴展以包括自定義徽標 。
普通 FastAPI
首先, 照常 編寫所有 FastAPI 應用程序:
from fastapi import FastAPI
from fastapi.openapi.utils import get_openapi
app = FastAPI()
@app.get("/items/")
async def read_items():
return [{"name": "Foo"}]
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title="Custom title",
version="2.5.0",
description="This is a very custom OpenAPI schema",
routes=app.routes,
)
openapi_schema["info"]["x-logo"] = {
"url": "https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png"
}
app.openapi_schema = openapi_schema
return app.openapi_schema
app.openapi = custom_openapi
生成的OpenAPI模式
然后,使用相同的實用程序函數在 custom_openapi()
函數 內部生成OpenAPI架構 :
from fastapi import FastAPI
from fastapi.openapi.utils import get_openapi
app = FastAPI()
@app.get("/items/")
async def read_items():
return [{"name": "Foo"}]
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title="Custom title",
version="2.5.0",
description="This is a very custom OpenAPI schema",
routes=app.routes,
)
openapi_schema["info"]["x-logo"] = {
"url": "https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png"
}
app.openapi_schema = openapi_schema
return app.openapi_schema
app.openapi = custom_openapi
修改OpenAPI架構
現在,您可以添加ReDoc擴展,向 OpenAPI模式中 x-logo
的 info
“對象” 添加自定義 :
from fastapi import FastAPI
from fastapi.openapi.utils import get_openapi
app = FastAPI()
@app.get("/items/")
async def read_items():
return [{"name": "Foo"}]
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title="Custom title",
version="2.5.0",
description="This is a very custom OpenAPI schema",
routes=app.routes,
)
openapi_schema["info"]["x-logo"] = {
"url": "https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png"
}
app.openapi_schema = openapi_schema
return app.openapi_schema
app.openapi = custom_openapi
緩存OpenAPI架構
您可以將該屬性 .openapi_schema
用作“緩存”,以存儲生成的模式。
這樣,您的應用程序不必在用戶每次打開API文檔時都生成架構。
它只會生成一次,然后相同的緩存模式將用於下一個請求。
from fastapi import FastAPI
from fastapi.openapi.utils import get_openapi
app = FastAPI()
@app.get("/items/")
async def read_items():
return [{"name": "Foo"}]
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title="Custom title",
version="2.5.0",
description="This is a very custom OpenAPI schema",
routes=app.routes,
)
openapi_schema["info"]["x-logo"] = {
"url": "https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png"
}
app.openapi_schema = openapi_schema
return app.openapi_schema
app.openapi = custom_openapi
覆蓋的方法
現在,您可以用 .openapi()
新功能 替換該 方法。
from fastapi import FastAPI
from fastapi.openapi.utils import get_openapi
app = FastAPI()
@app.get("/items/")
async def read_items():
return [{"name": "Foo"}]
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title="Custom title",
version="2.5.0",
description="This is a very custom OpenAPI schema",
routes=app.routes,
)
openapi_schema["info"]["x-logo"] = {
"url": "https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png"
}
app.openapi_schema = openapi_schema
return app.openapi_schema
app.openapi = custom_openapi
檢查它
轉到 http://127.0.0.1:8000/redoc之后, 您將看到您正在使用自定義徽標(在本示例中為 FastAPI 的徽標):
用於文檔的自托管JavaScript和 CSS
API文檔使用 Swagger UI 和 ReDoc ,每個 文檔 都需要一些JavaScript和CSS文件。
默認情況下,這些文件從 CDN提供 。
但是可以對其進行自定義,可以設置特定的CDN,也可以自己提供文件。
例如,如果您需要您的應用程序即使在脫機,無法打開Internet訪問或在本地網絡中仍能正常工作的情況下,這很有用。
在這里,您將看到如何在同一FastAPI應用程序中自行提供這些文件,以及如何配置文檔以使用它們。
項目文件結構
假設您的項目文件結構如下所示:
.
├── app
│ ├── __init__.py
│ ├── main.py
現在創建一個目錄來存儲那些靜態文件。
您的新文件結構可能如下所示:
.
├── app
│ ├── __init__.py
│ ├── main.py
└── static/
下載文件
下載文檔所需的靜態文件,並將其放在該 static/
目錄中。
您可能可以右鍵單擊每個鏈接,然后選擇類似於的選項 Save link as...
。
Swagger UI 使用以下文件:
swagger-ui-bundle.js
swagger-ui.css
而 ReDoc 使用文件:
redoc.standalone.js
之后,您的文件結構可能如下所示:
.
├── app
│ ├── __init__.py
│ ├── main.py
└── static
├── redoc.standalone.js
├── swagger-ui-bundle.js
└── swagger-ui.css
安裝 aiofiles
現在您需要安裝 aiofiles
:
pip install aiofiles
服務於靜態文件
- 導入
StaticFiles
。 StaticFiles()
在特定路徑中 “掛載” 實例。
from fastapi import FastAPI
from fastapi.openapi.docs import (
get_redoc_html,
get_swagger_ui_html,
get_swagger_ui_oauth2_redirect_html,
)
from fastapi.staticfiles import StaticFiles
app = FastAPI(docs_url=None, redoc_url=None)
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
return get_swagger_ui_html(
openapi_url=app.openapi_url,
title=app.title + " - Swagger UI",
oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
swagger_js_url="/static/swagger-ui-bundle.js",
swagger_css_url="/static/swagger-ui.css",
)
@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
return get_swagger_ui_oauth2_redirect_html()
@app.get("/redoc", include_in_schema=False)
async def redoc_html():
return get_redoc_html(
openapi_url=app.openapi_url,
title=app.title + " - ReDoc",
redoc_js_url="/static/redoc.standalone.js",
)
@app.get("/users/{username}")
async def read_user(username: str):
return {"message": f"Hello {username}"}
測試靜態文件
啟動您的應用程序,然后轉到 http://127.0.0.1:8000/static/redoc.standalone.js 。
您應該看到 ReDoc的 JavaScript文件非常長 。
它可以從以下內容開始:
/*!
* ReDoc - OpenAPI/Swagger-generated API Reference Documentation
* -------------------------------------------------------------
* Version: "2.0.0-rc.18"
* Repo: https://github.com/Redocly/redoc
*/
!function(e,t){"object"==typeof exports&&"object"==typeof m
...
這確認您能夠從您的應用程序提供靜態文件,並且已將文檔的靜態文件放置在正確的位置。
現在,我們可以配置應用程序以將這些靜態文件用於文檔。
禁用自動文檔
第一步是禁用自動文檔,因為默認情況下會使用CDN。
要禁用它們,請 None
在創建 FastAPI
應用程序 時 將其URL設置為 :
from fastapi import FastAPI
from fastapi.openapi.docs import (
get_redoc_html,
get_swagger_ui_html,
get_swagger_ui_oauth2_redirect_html,
)
from fastapi.staticfiles import StaticFiles
app = FastAPI(docs_url=None, redoc_url=None)
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
return get_swagger_ui_html(
openapi_url=app.openapi_url,
title=app.title + " - Swagger UI",
oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
swagger_js_url="/static/swagger-ui-bundle.js",
swagger_css_url="/static/swagger-ui.css",
)
@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
return get_swagger_ui_oauth2_redirect_html()
@app.get("/redoc", include_in_schema=False)
async def redoc_html():
return get_redoc_html(
openapi_url=app.openapi_url,
title=app.title + " - ReDoc",
redoc_js_url="/static/redoc.standalone.js",
)
@app.get("/users/{username}")
async def read_user(username: str):
return {"message": f"Hello {username}"}
包括自定義文檔
現在,您可以 為自定義文檔 創建 路徑操作 。
您可以重復使用FastAPI的內部函數來為文檔創建HTML頁面,並將所需的參數傳遞給它們:
openapi_url
:文檔HTML頁面可在其中獲取API的OpenAPI架構的URL。 您可以在此處使用屬性app.openapi_url
。title
:您的API的標題。oauth2_redirect_url
:您可以app.swagger_ui_oauth2_redirect_url
在此處使用默認值。swagger_js_url
:Swagger UI文檔的HTML可以從中獲取 JavaScript 文件 的URL 。 這是您自己的應用程序現在正在提供的應用程序。swagger_css_url
:Swagger UI文檔的HTML可以從中獲取 CSS 文件 的URL 。 這是您自己的應用程序現在正在提供的應用程序。
對於ReDoc同樣如此...
from fastapi import FastAPI
from fastapi.openapi.docs import (
get_redoc_html,
get_swagger_ui_html,
get_swagger_ui_oauth2_redirect_html,
)
from fastapi.staticfiles import StaticFiles
app = FastAPI(docs_url=None, redoc_url=None)
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
return get_swagger_ui_html(
openapi_url=app.openapi_url,
title=app.title + " - Swagger UI",
oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
swagger_js_url="/static/swagger-ui-bundle.js",
swagger_css_url="/static/swagger-ui.css",
)
@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
return get_swagger_ui_oauth2_redirect_html()
@app.get("/redoc", include_in_schema=False)
async def redoc_html():
return get_redoc_html(
openapi_url=app.openapi_url,
title=app.title + " - ReDoc",
redoc_js_url="/static/redoc.standalone.js",
)
@app.get("/users/{username}")
async def read_user(username: str):
return {"message": f"Hello {username}"}
小費
該 路徑運行 的 swagger_ui_redirect
是當你使用了OAuth2一個幫手。
如果您將API與OAuth2提供程序集成,則將能夠進行身份驗證,並使用獲取的憑據返回API文檔。 並使用真正的OAuth2身份驗證與其進行交互。
Swagger UI將在后台為您處理它,但是它需要此“重定向”幫助程序。
創建一個 路徑操作 來測試它
現在,為了能夠測試一切正常,創建一個 path操作 :
from fastapi import FastAPI
from fastapi.openapi.docs import (
get_redoc_html,
get_swagger_ui_html,
get_swagger_ui_oauth2_redirect_html,
)
from fastapi.staticfiles import StaticFiles
app = FastAPI(docs_url=None, redoc_url=None)
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
return get_swagger_ui_html(
openapi_url=app.openapi_url,
title=app.title + " - Swagger UI",
oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
swagger_js_url="/static/swagger-ui-bundle.js",
swagger_css_url="/static/swagger-ui.css",
)
@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
return get_swagger_ui_oauth2_redirect_html()
@app.get("/redoc", include_in_schema=False)
async def redoc_html():
return get_redoc_html(
openapi_url=app.openapi_url,
title=app.title + " - ReDoc",
redoc_js_url="/static/redoc.standalone.js",
)
@app.get("/users/{username}")
async def read_user(username: str):
return {"message": f"Hello {username}"}
測試
現在,您應該可以斷開WiFi了,轉到 http://127.0.0.1:8000/docs 上的文檔 ,然后重新加載頁面。
即使沒有Internet,您也可以查看API的文檔並與之交互。
轉:https://www.pythonf.cn/read/56964