Comment ajouter à la fois un fichier et un corps JSON dans une requête POST FastAPI ?
Dans FastAPI, vous ne pouvez pas envoyer à la fois des données et des fichiers JSON dans une seule requête si vous déclarez le corps au format JSON. Au lieu de cela, vous devez utiliser le codage multipart/form-data. Voici quelques méthodes pour y parvenir :
Méthode 1 : Utiliser un fichier et un formulaire
# Assuming you have a DataConfiguration model for the JSON data from fastapi import FastAPI, File, UploadFile from pydantic import BaseModel app = FastAPI() class DataConfiguration(BaseModel): textColumnNames: list[str] idColumn: str @app.post("/data") async def data(dataConfiguration: DataConfiguration, csvFile: UploadFile = File(...)): pass # read requested id and text columns from csvFile
Méthode 2 : Utiliser des modèles et des dépendances Pydantic
from fastapi import FastAPI, Form, File, UploadFile, Depends, Request from pydantic import BaseModel from typing import List, Optional, Dict from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates app = FastAPI() templates = Jinja2Templates(directory="templates") class Base(BaseModel): name: str point: Optional[float] = None is_accepted: Optional[bool] = False def validate_json_body(body: str = Form(...)): try: return Base.model_validate_json(body) except ValidationError as e: raise HTTPException( detail=jsonable_encoder(e.errors()), status_code=422, ) @app.post("/submit") async def submit(base: Base = Depends(validate_json_body), files: List[UploadFile] = File(...)): return { "JSON Payload": base, "Filenames": [file.filename for file in files], } @app.get("/", response_class=HTMLResponse) async def main(request: Request): return templates.TemplateResponse("index.html", {"request": request})
Méthode 3 : Passer JSON sous forme de chaîne dans le paramètre Body
from fastapi import FastAPI, Form, UploadFile, File from pydantic import BaseModel class Base(BaseModel): name: str point: float is_accepted: bool app = FastAPI() @app.post("/submit") async def submit(data: Base = Form(...), files: List[UploadFile] = File(...)): return { "JSON Payload": data, "Filenames": [file.filename for file in files], }
Méthode 4 : Utilisation d'une classe personnalisée pour valider JSON
from fastapi import FastAPI, File, UploadFile, Request from pydantic import BaseModel, model_validator from typing import Optional, List from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates import json app = FastAPI() templates = Jinja2Templates(directory="templates") class Base(BaseModel): name: str point: Optional[float] = None is_accepted: Optional[bool] = False @model_validator(mode='before') @classmethod def validate_to_json(cls, value): if isinstance(value, str): return cls(**json.loads(value)) return value @app.post("/submit") async def submit(data: Base = Body(...), files: List[UploadFile] = File(...)): return { "JSON Payload": data, "Filenames": [file.filename for file in files], } @app.get("/", response_class=HTMLResponse) async def main(request: Request): return templates.TemplateResponse("index.html", context={"request": request})
Remarque : Dans la méthode 1, vous pouvez utiliser les classes File et Form ensemble car Form est une sous-classe de Body. Cependant, si vous utilisez Body(...) au lieu de Form(...) dans la méthode 1, cela ne fonctionnera pas car FastAPI s'attendra à ce que les données JSON soient dans le corps de la requête, et non en tant que données de formulaire.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!