Devolver una respuesta directamente¶
Cuando creas una operación de path normalmente puedes devolver cualquier dato: un dict
, una list
, un modelo Pydantic, un modelo de base de datos, etc.
Por defecto, FastAPI convertiría automáticamente ese valor devuelto a JSON usando el jsonable_encoder
explicado en Codificador Compatible JSON.
Luego, tras bastidores, pondría esos datos compatibles con JSON (por ejemplo, un dict
) dentro de una JSONResponse
que se usaría para enviar la respuesta al cliente.
Pero puedes devolver una JSONResponse
directamente de tu operación de path.
Esto puede ser útil, por ejemplo, para devolver cookies o headers personalizados.
Devolver una Response
¶
De hecho, puedes devolver cualquier Response
o cualquier subclase de la misma.
Consejo
JSONResponse
en sí misma es una subclase de Response
.
Y cuando devuelves una Response
, FastAPI la pasará directamente.
No hará ninguna conversión de datos con modelos Pydantic, no convertirá el contenido a ningún tipo, etc.
Esto te da mucha flexibilidad. Puedes devolver cualquier tipo de dato, sobrescribir cualquer declaración de datos o validación, etc.
Usando el jsonable_encoder
en una Response
¶
Como FastAPI no realiza ningún cambio en la Response
que devuelves, debes asegurarte de que el contenido está listo.
Por ejemplo, no puedes poner un modelo Pydantic en una JSONResponse
sin primero convertirlo a un dict
con todos los tipos de datos (como datetime
, UUID
, etc) convertidos a tipos compatibles con JSON.
Para esos casos, puedes usar el jsonable_encoder
para convertir tus datos antes de pasarlos a la respuesta:
from datetime import datetime
from typing import Union
from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from pydantic import BaseModel
class Item(BaseModel):
title: str
timestamp: datetime
description: Union[str, None] = None
app = FastAPI()
@app.put("/items/{id}")
def update_item(id: str, item: Item):
json_compatible_item_data = jsonable_encoder(item)
return JSONResponse(content=json_compatible_item_data)
Detalles Técnicos
También puedes usar from starlette.responses import JSONResponse
.
FastAPI provee starlette.responses
como fastapi.responses
, simplemente como una conveniencia para ti, el desarrollador. Pero la mayoría de las respuestas disponibles vienen directamente de Starlette.
Devolviendo una Response
personalizada¶
El ejemplo anterior muestra las partes que necesitas, pero no es muy útil todavía, dado que podrías simplemente devolver el item
directamente, y FastAPI lo pondría en una JSONResponse
por ti, convirtiéndolo en un dict
, etc. Todo esto por defecto.
Ahora, veamos cómo puedes usarlo para devolver una respuesta personalizada.
Digamos que quieres devolver una respuesta XML.
Podrías poner tu contenido XML en un string, ponerlo en una Response
y devolverlo:
from fastapi import FastAPI, Response
app = FastAPI()
@app.get("/legacy/")
def get_legacy_data():
data = """<?xml version="1.0"?>
<shampoo>
<Header>
Apply shampoo here.
</Header>
<Body>
You'll have to use soap here.
</Body>
</shampoo>
"""
return Response(content=data, media_type="application/xml")
Notas¶
Cuando devuelves una Response
directamente, los datos no son validados, convertidos (serializados), ni documentados automáticamente.
Pero todavía es posible documentarlo como es descrito en Respuestas adicionales en OpenAPI.
Puedes ver en secciones posteriores como usar/declarar esas Response
s personalizadas aún teniendo conversión automática de datos, documentación, etc.