コンテンツへスキップ

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.1.0 です。
  • summary: API の短い要約。
  • description: API の説明。マークダウンを含めることができ、ドキュメントに表示されます。
  • routes: ルートのリスト。これらは登録された各パス操作です。これらは app.routes から取得されます。

情報

パラメーター summary は OpenAPI 3.1.0 以降で利用可能で、FastAPI 0.99.0 以降でサポートされています。

デフォルトのオーバーライド

上記の情報を使用して、同じユーティリティ関数で 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",
        summary="This is a very custom OpenAPI schema",
        description="Here's a longer description of the custom **OpenAPI** schema",
        routes=app.routes,
    )
    openapi_schema["info"]["x-logo"] = {
        "url": "https://fastapi.dokyumento.jp/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",
        summary="This is a very custom OpenAPI schema",
        description="Here's a longer description of the custom **OpenAPI** schema",
        routes=app.routes,
    )
    openapi_schema["info"]["x-logo"] = {
        "url": "https://fastapi.dokyumento.jp/img/logo-margin/logo-teal.png"
    }
    app.openapi_schema = openapi_schema
    return app.openapi_schema


app.openapi = custom_openapi

OpenAPI スキーマの変更

これで、ReDoc 拡張機能を追加し、OpenAPI スキーマの info "オブジェクト" にカスタムの x-logo を追加できます

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",
        summary="This is a very custom OpenAPI schema",
        description="Here's a longer description of the custom **OpenAPI** schema",
        routes=app.routes,
    )
    openapi_schema["info"]["x-logo"] = {
        "url": "https://fastapi.dokyumento.jp/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",
        summary="This is a very custom OpenAPI schema",
        description="Here's a longer description of the custom **OpenAPI** schema",
        routes=app.routes,
    )
    openapi_schema["info"]["x-logo"] = {
        "url": "https://fastapi.dokyumento.jp/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",
        summary="This is a very custom OpenAPI schema",
        description="Here's a longer description of the custom **OpenAPI** schema",
        routes=app.routes,
    )
    openapi_schema["info"]["x-logo"] = {
        "url": "https://fastapi.dokyumento.jp/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 のロゴ) が使用されていることがわかります