Wie füge ich sowohl eine Datei als auch einen JSON-Text in einer FastAPI-POST-Anfrage hinzu?
In FastAPI können Sie nicht sowohl JSON-Daten als auch Dateien einsenden eine einzelne Anfrage, wenn Sie den Text als JSON deklarieren. Stattdessen müssen Sie die Multipart-/Formulardatenkodierung verwenden. Hier sind einige Methoden, um dies zu erreichen:
Methode 1: Datei und Formular verwenden
# 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
Methode 2: Pydantische Modelle und Abhängigkeiten verwenden
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})
Methode 3: JSON als String übergeben im Körperparameter
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], }
Methode 4: Verwenden einer benutzerdefinierten Klasse zur Validierung von 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})
Hinweis: In-Methode 1 können Sie die Klassen File und Form zusammen verwenden, da Form eine Unterklasse von Body ist. Wenn Sie jedoch in Methode 1 Body(...) anstelle von Form(...) verwenden, funktioniert dies nicht, da FastAPI erwartet, dass sich die JSON-Daten im Anforderungstext und nicht als Formulardaten befinden.
Das obige ist der detaillierte Inhalt vonWie übermittle ich sowohl JSON als auch Dateien in einer FastAPI-POST-Anfrage?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!