跳到内容

扩展 OpenAPI

在某些情况下,你可能需要修改生成的 OpenAPI 模式。

本节将介绍如何操作。

正常流程

正常(默认)流程如下:

一个 FastAPI 应用程序(实例)有一个 .openapi() 方法,该方法应返回 OpenAPI 模式。

作为应用程序对象创建的一部分,会注册一个用于 /openapi.json(或你设置的任何 openapi_url)的 *路径操作*。

它只返回一个 JSON 响应,其中包含应用程序 .openapi() 方法的结果。

默认情况下,.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 描述,可以包含 Markdown,并将在文档中显示。
  • 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.org.cn/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.org.cn/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.org.cn/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.org.cn/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.org.cn/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 的徽标)