コンテンツにスキップ

カスタムドキュメント UI の静的アセット(セルフホスティング)

🌐 AI と人間による翻訳

この翻訳は、人間のガイドに基づいて AI によって作成されました。🤝

原文の意図を取り違えていたり、不自然な表現になっている可能性があります。🤖

AI LLM をより適切に誘導するのを手伝う ことで、この翻訳を改善できます。

英語版

API ドキュメントは Swagger UIReDoc を使用しており、それぞれにいくつかの JavaScript と CSS ファイルが必要です。

既定では、これらのファイルは CDN から配信されます。

しかし、カスタマイズすることも可能で、特定の CDN を指定したり、自分でファイルを配信したりできます。

JavaScript と CSS のカスタム CDN

別の CDN を使いたいとします。例えば https://unpkg.com/ を使いたい場合です。

例えば、一部の URL が制限されている国に住んでいる場合に役立ちます。

自動ドキュメントの無効化

最初の手順は自動ドキュメントを無効化することです。デフォルトではそれらは既定の CDN を使用します。

無効化するには、FastAPI アプリ作成時にそれらの URL を 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@2/bundles/redoc.standalone.js",
    )


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

カスタムドキュメントの追加

これで、カスタムドキュメント用の path operations を作成できます。

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。これはカスタム CDN の URL です。
  • swagger_css_url: Swagger UI ドキュメント用の HTML が取得する CSS ファイルの URL。これはカスタム CDN の URL です。

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@2/bundles/redoc.standalone.js",
    )


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

豆知識

swagger_ui_redirect 用の path operation は、OAuth2 を使用する場合の補助です。

API を OAuth2 プロバイダと統合すると、認証を実行して取得したクレデンシャルを持った状態で API ドキュメントに戻れます。そして実際の OAuth2 認証を用いてドキュメント上から API と対話できます。

Swagger UI がこの処理を裏側で行いますが、そのためにこの「redirect」の補助が必要です。

テスト用の path operation を作成

すべてが動作するかをテストできるように、path operation を作成します:

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@2/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 ファイルが表示されるはずです。

先頭は次のようになっているかもしれません:

/*! For license information please see redoc.standalone.js.LICENSE.txt */
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("null")):
...

これで、アプリから静的ファイルを配信できていること、そしてドキュメント用の静的ファイルを正しい場所に配置できていることが確認できます。

次に、ドキュメントでそれらの静的ファイルを使用するようにアプリを設定します。

静的ファイル用に自動ドキュメントを無効化

カスタム CDN を使う場合と同様、最初の手順は自動ドキュメントを無効化することです。既定では CDN を使用します。

無効化するには、FastAPI アプリ作成時にそれらの URL を 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 と同様の方法で、カスタムドキュメント用の path operations を作成できます。

再び、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 用の path operation は、OAuth2 を使用する場合の補助です。

API を OAuth2 プロバイダと統合すると、認証を実行して取得したクレデンシャルを持った状態で API ドキュメントに戻れます。そして実際の OAuth2 認証を用いてドキュメント上から API と対話できます。

Swagger UI がこの処理を裏側で行いますが、そのためにこの「redirect」の補助が必要です。

静的ファイルをテストするための path operation を作成

すべてが動作するかをテストできるように、path operation を作成します:

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 のドキュメントを表示し、API と対話できます。