コンテンツにスキップ

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のロゴ)を使用していることがわかります。