FastApi教程|擴展OpenAPI


 

這是一個相當高級的功能。 您可能可以跳過它。

如果您只是在遵循教程-用戶指南,則可以跳過本節。

如果您已經知道需要修改生成的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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM