Una aplicación FastAPI (instancia) tiene un método .openapi() que se espera que devuelva el esquema 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 hayas configurado en tu openapi_url).
Simplemente devuelve una respuesta JSON con el resultado del método .openapi() de la aplicación.
Por defecto, lo que hace el método .openapi() es verificar la propiedad .openapi_schema para ver si tiene contenido y devolverlo.
Si no, los 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 usada. Por defecto, la más reciente: 3.1.0.
summary: Un resumen corto de la API.
description: La descripción de tu API, esta puede incluir markdown y se mostrará en la documentación.
routes: Las rutas de la aplicación, tomadas de app.routes. FastAPI las usa para recolectar las path operations registradas, incluyendo las de los routers incluidos.
Detalles Técnicos
app.routes es un árbol de rutas de más bajo nivel. Puede incluir candidatos de rutas que FastAPI usa internamente para los routers incluidos, no solo objetos APIRoute finales.
Aún puedes pasar app.routes a get_openapi(). FastAPI recorrerá ese árbol de rutas para recolectar las path operations efectivas.
Nota
El parámetro summary está disponible en OpenAPI 3.1.0 y superior, soportado por FastAPI 0.99.0 y superior.
Primero, escribe toda tu aplicación FastAPI como de costumbre:
fromfastapiimportFastAPIfromfastapi.openapi.utilsimportget_openapiapp=FastAPI()@app.get("/items/")asyncdefread_items():return[{"name":"Foo"}]defcustom_openapi():ifapp.openapi_schema:returnapp.openapi_schemaopenapi_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_schemareturnapp.openapi_schemaapp.openapi=custom_openapi
Luego, usa la misma función de utilidad para generar el esquema OpenAPI, dentro de una función custom_openapi():
fromfastapiimportFastAPIfromfastapi.openapi.utilsimportget_openapiapp=FastAPI()@app.get("/items/")asyncdefread_items():return[{"name":"Foo"}]defcustom_openapi():ifapp.openapi_schema:returnapp.openapi_schemaopenapi_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_schemareturnapp.openapi_schemaapp.openapi=custom_openapi
Ahora puedes añadir la extensión de ReDoc, añadiendo un x-logo personalizado al "objeto" info en el esquema OpenAPI:
fromfastapiimportFastAPIfromfastapi.openapi.utilsimportget_openapiapp=FastAPI()@app.get("/items/")asyncdefread_items():return[{"name":"Foo"}]defcustom_openapi():ifapp.openapi_schema:returnapp.openapi_schemaopenapi_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_schemareturnapp.openapi_schemaapp.openapi=custom_openapi
Puedes usar la propiedad .openapi_schema como "caché", para almacenar tu esquema generado.
De esa manera, 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 peticiones.
fromfastapiimportFastAPIfromfastapi.openapi.utilsimportget_openapiapp=FastAPI()@app.get("/items/")asyncdefread_items():return[{"name":"Foo"}]defcustom_openapi():ifapp.openapi_schema:returnapp.openapi_schemaopenapi_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_schemareturnapp.openapi_schemaapp.openapi=custom_openapi
Ahora puedes reemplazar el método .openapi() con tu nueva función.
fromfastapiimportFastAPIfromfastapi.openapi.utilsimportget_openapiapp=FastAPI()@app.get("/items/")asyncdefread_items():return[{"name":"Foo"}]defcustom_openapi():ifapp.openapi_schema:returnapp.openapi_schemaopenapi_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_schemareturnapp.openapi_schemaapp.openapi=custom_openapi