Saltar a contenido

Extender OpenAPI

Hay algunos casos en los que podr铆as necesitar modificar el esquema de OpenAPI generado.

En esta secci贸n ver谩s c贸mo hacerlo.

El proceso normal

El proceso normal (por defecto) es el siguiente.

Una aplicaci贸n (instance) de FastAPI tiene un m茅todo .openapi() que se espera que devuelva el esquema de OpenAPI.

Como parte de la creaci贸n del objeto de la aplicaci贸n, se registra una path operation para /openapi.json (o para lo que sea que configures tu openapi_url).

Simplemente devuelve un response JSON con el resultado del m茅todo .openapi() de la aplicaci贸n.

Por defecto, lo que hace el m茅todo .openapi() es revisar la propiedad .openapi_schema para ver si tiene contenido y devolverlo.

Si no lo tiene, lo genera usando la funci贸n de utilidad en fastapi.openapi.utils.get_openapi.

Y esa funci贸n get_openapi() recibe como par谩metros:

  • title: El t铆tulo de OpenAPI, mostrado en la documentaci贸n.
  • version: La versi贸n de tu API, por ejemplo 2.5.0.
  • openapi_version: La versi贸n de la especificaci贸n OpenAPI utilizada. Por defecto, la m谩s reciente: 3.1.0.
  • summary: Un breve resumen de la API.
  • description: La descripci贸n de tu API, esta puede incluir markdown y se mostrar谩 en la documentaci贸n.
  • routes: Una list de rutas, estas son cada una de las path operations registradas. Se toman de app.routes.

Informaci贸n

El par谩metro summary est谩 disponible en OpenAPI 3.1.0 y versiones superiores, soportado por FastAPI 0.99.0 y superiores.

Sobrescribir los valores por defecto

Usando la informaci贸n anterior, puedes usar la misma funci贸n de utilidad para generar el esquema de OpenAPI y sobrescribir cada parte que necesites.

Por ejemplo, vamos a a帽adir la extensi贸n OpenAPI de ReDoc para incluir un logo personalizado.

FastAPI normal

Primero, escribe toda tu aplicaci贸n FastAPI como normalmente:

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.tiangolo.com/img/logo-margin/logo-teal.png"
    }
    app.openapi_schema = openapi_schema
    return app.openapi_schema


app.openapi = custom_openapi

Generar el esquema de OpenAPI

Luego, usa la misma funci贸n de utilidad para generar el esquema de OpenAPI, dentro de una funci贸n custom_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.tiangolo.com/img/logo-margin/logo-teal.png"
    }
    app.openapi_schema = openapi_schema
    return app.openapi_schema


app.openapi = custom_openapi

Modificar el esquema de OpenAPI

Ahora puedes a帽adir la extensi贸n de ReDoc, agregando un x-logo personalizado al "objeto" info en el esquema de 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.tiangolo.com/img/logo-margin/logo-teal.png"
    }
    app.openapi_schema = openapi_schema
    return app.openapi_schema


app.openapi = custom_openapi

Cachear el esquema de OpenAPI

Puedes usar la propiedad .openapi_schema como un "cache", para almacenar tu esquema generado.

De esa forma, tu aplicaci贸n no tendr谩 que generar el esquema cada vez que un usuario abra la documentaci贸n de tu API.

Se generar谩 solo una vez, y luego se usar谩 el mismo esquema cacheado para las siguientes requests.

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.tiangolo.com/img/logo-margin/logo-teal.png"
    }
    app.openapi_schema = openapi_schema
    return app.openapi_schema


app.openapi = custom_openapi

Sobrescribir el m茅todo

Ahora puedes reemplazar el m茅todo .openapi() por tu nueva funci贸n.

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.tiangolo.com/img/logo-margin/logo-teal.png"
    }
    app.openapi_schema = openapi_schema
    return app.openapi_schema


app.openapi = custom_openapi

Revisa

Una vez que vayas a http://127.0.0.1:8000/redoc ver谩s que est谩s usando tu logo personalizado (en este ejemplo, el logo de FastAPI):