跳至內容

自訂文件 UI 靜態資源(自行託管)

API 文件使用 Swagger UIReDoc,而它們都需要一些 JavaScript 和 CSS 檔案。

預設情況下,這些檔案是由 CDN 提供的。

但可以自訂它,您可以設定特定的 CDN 或自行提供檔案。

自訂 JavaScript 和 CSS 的 CDN

假設您想使用不同的 CDN,例如您想使用 https://unpkg.com/

如果您居住在限制某些網址的國家/地區,這可能會很有用。

停用自動文件

第一步是停用自動文件,因為預設情況下,這些文件使用預設的 CDN。

要停用它們,請在建立 FastAPI 應用程式時將其網址設定為 None

from fastapi import FastAPI
from fastapi.openapi.docs import (
    get_redoc_html,
    get_swagger_ui_html,
    get_swagger_ui_oauth2_redirect_html,
)

app = FastAPI(docs_url=None, redoc_url=None)


@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="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js",
        swagger_css_url="https://unpkg.com/swagger-ui-dist@5/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="https://unpkg.com/redoc@next/bundles/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 綱要的網址。您可以在這裡使用屬性 app.openapi_url
  • title:API 的標題。
  • oauth2_redirect_url:您可以在這裡使用 app.swagger_ui_oauth2_redirect_url 來使用預設值。
  • swagger_js_url:Swagger UI 文件的 HTML 可以取得 **JavaScript** 檔案的網址。這是自訂 CDN 網址。
  • swagger_css_url:Swagger UI 文件的 HTML 可以取得 **CSS** 檔案的網址。這是自訂 CDN 網址。

ReDoc 也類似…

from fastapi import FastAPI
from fastapi.openapi.docs import (
    get_redoc_html,
    get_swagger_ui_html,
    get_swagger_ui_oauth2_redirect_html,
)

app = FastAPI(docs_url=None, redoc_url=None)


@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="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js",
        swagger_css_url="https://unpkg.com/swagger-ui-dist@5/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="https://unpkg.com/redoc@next/bundles/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 將在幕後為您處理它,但它需要這個「重新導向」輔助工具。

建立*路徑操作*來測試它

現在,為了能夠測試一切是否正常,請建立一個*路徑操作*

from fastapi import FastAPI
from fastapi.openapi.docs import (
    get_redoc_html,
    get_swagger_ui_html,
    get_swagger_ui_oauth2_redirect_html,
)

app = FastAPI(docs_url=None, redoc_url=None)


@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="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js",
        swagger_css_url="https://unpkg.com/swagger-ui-dist@5/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="https://unpkg.com/redoc@next/bundles/redoc.standalone.js",
    )


@app.get("/users/{username}")
async def read_user(username: str):
    return {"message": f"Hello {username}"}

測試它

現在,您應該可以前往 http://127.0.0.1:8000/docs 的文件,並重新載入頁面,它將從新的 CDN 載入這些資源。

自行託管文件的 JavaScript 和 CSS

如果您需要應用程式即使在離線、沒有網路連線或是在區域網路中也能正常運作,那麼自行託管 JavaScript 和 CSS 檔案就很有用。

這裡將會說明如何在同一個 FastAPI 應用程式中自行提供這些檔案,並設定文件使用它們。

專案檔案結構

假設您的專案檔案結構如下:

.
├── app
│   ├── __init__.py
│   ├── main.py

現在建立一個目錄來存放這些靜態檔案。

您的新檔案結構可能如下:

.
├── app
│   ├── __init__.py
│   ├── main.py
└── static/

下載檔案

下載文件所需的靜態檔案,並將它們放到 static/ 目錄中。

您可以滑鼠右鍵點擊每個連結,然後選擇類似「另存連結為...」的選項。

Swagger UI 使用以下檔案:

ReDoc 使用以下檔案:

之後,您的檔案結構可能如下:

.
├── app
│   ├── __init__.py
│   ├── main.py
└── static
    ├── redoc.standalone.js
    ├── swagger-ui-bundle.js
    └── swagger-ui.css

提供靜態檔案

  • 匯入 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 時相同,第一步是停用自動文件,因為這些文件預設使用 CDN。

要停用它們,請在建立 FastAPI 應用程式時將其網址設定為 None

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}"}

包含靜態檔案的自訂文件

與使用自訂 CDN 的方式相同,現在您可以建立自訂文件的*路徑操作*。

同樣地,您可以重複使用 FastAPI 的內部函式來建立文件的 HTML 頁面,並傳遞所需的參數

  • openapi_url:文件 HTML 頁面可以取得 API 的 OpenAPI 綱要的網址。您可以在這裡使用屬性 app.openapi_url
  • title:API 的標題。
  • oauth2_redirect_url:您可以在這裡使用 app.swagger_ui_oauth2_redirect_url 來使用預設值。
  • swagger_js_url:Swagger UI 文件的 HTML 可以取得 **JavaScript** 檔案的網址。**這是您自己的應用程式現在提供的網址。**
  • swagger_css_url:Swagger UI 文件的 HTML 可以取得 **CSS** 檔案的網址。**這是您自己的應用程式現在提供的網址。**

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 將在幕後為您處理它,但它需要這個「重新導向」輔助工具。

建立*路徑操作*以測試靜態檔案

現在,為了能夠測試一切是否正常,請建立一個*路徑操作*

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}"}

測試靜態檔案 UI

現在,您應該可以斷開 WiFi 連線,前往 http://127.0.0.1:8000/docs 的文件頁面,並重新載入頁面。

即使沒有網路,您也可以看到 API 的文件並與之互動。