Aller au contenu

Renvoyer directement une réponse

🌐 Translation by AI and humans

This translation was made by AI guided by humans. 🤝

It could have mistakes of misunderstanding the original meaning, or looking unnatural, etc. 🤖

You can improve this translation by helping us guide the AI LLM better.

English version

Lorsque vous créez un chemin d'accès FastAPI, vous pouvez normalement retourner n'importe quelle donnée : un dict, une list, un modèle Pydantic, un modèle de base de données, etc.

Par défaut, FastAPI convertirait automatiquement cette valeur de retour en JSON en utilisant le jsonable_encoder expliqué dans Encodeur compatible JSON.

Ensuite, en arrière-plan, il mettra ces données JSON-compatible (par exemple un dict) à l'intérieur d'un JSONResponse qui sera utilisé pour envoyer la réponse au client.

Mais vous pouvez retourner une JSONResponse directement à partir de vos chemins d'accès.

Cela peut être utile, par exemple, pour retourner des en-têtes personnalisés ou des cookies.

Renvoyer une Response

En fait, vous pouvez retourner n'importe quelle Response ou n'importe quelle sous-classe de celle-ci.

Astuce

JSONResponse est elle-même une sous-classe de Response.

Et quand vous retournez une Response, FastAPI la transmet directement.

Elle ne fera aucune conversion de données avec les modèles Pydantic, elle ne convertira pas le contenu en un type quelconque.

Cela vous donne beaucoup de flexibilité. Vous pouvez retourner n'importe quel type de données, surcharger n'importe quelle déclaration ou validation de données, etc.

Utiliser le jsonable_encoder dans une Response

Parce que FastAPI n'apporte aucune modification à une Response que vous retournez, vous devez vous assurer que son contenu est prêt pour cela.

Par exemple, vous ne pouvez pas mettre un modèle Pydantic dans une JSONResponse sans d'abord le convertir en un dict avec tous les types de données (comme datetime, UUID, etc.) convertis en types compatibles avec JSON.

Pour ces cas, vous pouvez utiliser le jsonable_encoder pour convertir vos données avant de les passer à une réponse :

from datetime import datetime

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: 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)
🤓 Other versions and variants
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)

Détails techniques

Vous pouvez aussi utiliser from starlette.responses import JSONResponse.

FastAPI fournit le même starlette.responses que fastapi.responses juste par commodité pour vous, le développeur. Mais la plupart des réponses disponibles proviennent directement de Starlette.

Renvoyer une Response personnalisée

L'exemple ci-dessus montre toutes les parties dont vous avez besoin, mais il n'est pas encore très utile, car vous auriez pu retourner l'item directement, et FastAPI l'aurait mis dans une JSONResponse pour vous, en le convertissant en dict, etc. Tout cela par défaut.

Maintenant, voyons comment vous pourriez utiliser cela pour retourner une réponse personnalisée.

Disons que vous voulez retourner une réponse XML.

Vous pouvez mettre votre contenu XML dans une chaîne de caractères, la placer dans une Response, et la retourner :

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")

Notes

Lorsque vous renvoyez une Response directement, ses données ne sont pas validées, converties (sérialisées), ni documentées automatiquement.

Mais vous pouvez toujours les documenter comme décrit dans Additional Responses in OpenAPI.

Vous pouvez voir dans les sections suivantes comment utiliser/déclarer ces Responses personnalisées tout en conservant la conversion automatique des données, la documentation, etc.