コンテンツへスキップ

カスタムDocs UI静的アセット(セルフホスティング)

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

デフォルトでは、これらのファイルはCDNから配信されます。

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

JavaScriptとCSS用のカスタムCDN

例えば、https://unpkg.com/など、別のCDNを使用したいとします。

これは、例えば特定の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}"}

カスタムドキュメントを組み込む

これで、カスタムドキュメント用の*パスオペレーション*を作成できます。

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の*パスオペレーション*は、OAuth2を使用する際のヘルパーです。

APIをOAuth2プロバイダーと統合すると、認証して取得したクレデンシャルでAPIドキュメントに戻ることができます。そして、実際のOAuth2認証を使用してAPIと対話できます。

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@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の場合と同様に、これでカスタムドキュメント用の*パスオペレーション*を作成できます。

繰り返しになりますが、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認証を使用してAPIと対話できます。

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をテストする

これで、Wi-Fiをオフにし、http://127.0.0.1:8000/docs にアクセスしてページをリロードしてみてください。

インターネットがなくても、APIのドキュメントを表示し、操作できるようになります。