首頁 >後端開發 >Python教學 >如何在 FastAPI POST 請求中同時提交 JSON 和文件?

如何在 FastAPI POST 請求中同時提交 JSON 和文件?

Barbara Streisand
Barbara Streisand原創
2025-01-04 17:20:39633瀏覽

How to Submit Both JSON and Files in a FastAPI POST Request?

如何在 FastAPI POST 請求中同時新增檔案和 JSON 正文?

在 FastAPI 中,您無法同時傳送 JSON 資料和檔案如果您將正文宣告為 JSON,則為單一請求。相反,您需要使用 multipart/form-data 編碼。以下是幾個實現此目的的方法:

方法1:使用檔案和表單

# 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

方法2:使用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})

方法3:將JSON傳遞為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],
    }

方法四:使用自定義類驗證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})

注意:中方法1,您可以同時使用File 和Form 類,因為Form 是Body 的子類別。但是,如果您在方法 1 中使用 Body(...) 而不是 Form(...),它將不起作用,因為 FastAPI 會期望 JSON 資料位於請求正文中,而不是表單資料。

以上是如何在 FastAPI POST 請求中同時提交 JSON 和文件?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn