> 백엔드 개발 > 파이썬 튜토리얼 > FastAPI POST 요청에서 JSON과 파일 업로드를 모두 수락하는 방법은 무엇입니까?

FastAPI POST 요청에서 JSON과 파일 업로드를 모두 수락하는 방법은 무엇입니까?

Mary-Kate Olsen
풀어 주다: 2024-12-19 10:35:12
원래의
481명이 탐색했습니다.

How to accept both JSON and file uploads in a FastAPI POST request?

FastAPI POST 요청에 파일과 JSON 본문을 모두 추가하는 방법은 무엇입니까?

구체적으로 아래 예가 작동하길 원합니다.

from typing import List
from pydantic import BaseModel
from fastapi import FastAPI, UploadFile, File


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
로그인 후 복사
로그인 후 복사

이것이 POST 요청에 대한 적절한 방법이 아닌 경우 업로드된 CSV 파일에서 필수 열을 선택하는 방법을 알려주십시오. FastAPI.

FastAPI 문서에 따라:

경로 작업에서 여러 양식 매개변수를 선언할 수 있지만 JSON으로 수신할 것으로 예상되는 본문 필드도 선언할 수는 없습니다. 요청의 본문은 application/json 대신 application/x-www-form-urlencoded를 사용하여 인코딩됩니다(양식에 파일이 포함된 경우 다음과 같이 인코딩됩니다). multipart/form-data).

이것은 FastAPI의 제한 사항이 아니며 HTTP 프로토콜의 일부입니다.

먼저 python-multipart를 설치해야 합니다. 아직은 그렇지 않습니다. 업로드된 파일은 "양식 데이터"로 전송되기 때문입니다. 예를 들면 다음과 같습니다.

pip install python-multipart
로그인 후 복사
로그인 후 복사

아래 예에서 엔드포인트는 일반 def로 정의되지만 필요에 따라 async def를 사용할 수도 있습니다. FastAPI의 def와 async def에 대한 자세한 내용은 이 답변을 참조하세요.

파일과 사전/JSON 데이터 목록을 모두 업로드하는 방법을 찾고 있다면, 이 답변과 이 답변 및 작업 예제에 대한 답변(주로 다음 방법 중 일부를 기반으로 함)을 살펴보세요.

방법 1

여기에 설명된 대로 File과 Form을 사용하여 파일과 양식 필드를 동시에 정의할 수 있습니다. 아래는 실제 예시입니다. 매개변수가 많고 이를 엔드포인트와 별도로 정의하려는 경우, 대신 종속성 클래스 또는 Pydantic 모델을 사용하여 데칼링 양식 필드를 선언하는 방법에 대한 이 답변을 살펴보세요.

app.py

from fastapi import Form, File, UploadFile, Request, FastAPI
from typing import List
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates

app = FastAPI()
templates = Jinja2Templates(directory="templates")


@app.post("/submit")
def submit(
    name: str = Form(...),
    point: float = Form(...),
    is_accepted: bool = Form(...),
    files: List[UploadFile] = File(...),
):
    return {
        "JSON Payload": {
            "name": name,
            "point": point,
            "is_accepted": is_accepted,
        },
        "Filenames": [file.filename for file in files],
    }


@app.get("/", response_class=HTMLResponse)
def main(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})
로그인 후 복사
로그인 후 복사

아래 템플릿에 액세스하여 위의 예를 테스트할 수 있습니다. http://127.0.0.1:8000. 템플릿에 Jinja 코드가 포함되어 있지 않으면 간단한 HTMLResponse를 반환할 수도 있습니다.

templates/index.html

<!DOCTYPE html>
<html>
   <body>
      <form method="post" action="http://127.0.0.1:8000/submit"  enctype="multipart/form-data">
         name : <input type="text" name="name" value="foo"><br>
         point : <input type="text" name="point" value=0.134><br>
         is_accepted : <input type="text" name="is_accepted" value=True><br>    
         <label for="files">Choose file(s) to upload</label>
         <input type="file">
로그인 후 복사

이 예제를 테스트할 수도 있습니다. /docs에서 대화형 OpenAPI/Swagger UI 자동 문서를 사용합니다. 예: http://127.0.0.1:8000/docs 또는 아래와 같이 Python 요청 사용:

test.py

from typing import List
from pydantic import BaseModel
from fastapi import FastAPI, UploadFile, File


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 모델을 종속성과 함께 사용하여 /submit 엔드포인트(아래 예에서)에 매개변수화된 변수 베이스가 Base 클래스에 종속된다는 것을 알릴 수도 있습니다. 이 방법은 기본 데이터를 쿼리(본문이 아닌) 매개변수로 예상하며, 이는 Pydantic 모델(이 경우 기본 모델)에 대해 검증되고 변환됩니다. 또한 심각한 보안 위험을 초래하므로 쿼리 문자열을 통해 민감한 데이터를 전달해서는 안 됩니다. 해당 주제에 대한 자세한 내용은 이 답변을 살펴보시기 바랍니다.

Pydantic 모델 인스턴스를 반환하는 경우 (이 경우 기본) FastAPI 엔드포인트(예: 아래 /submit 엔드포인트)에서 이 항목에 자세히 설명된 대로 jsonable_encoder를 사용하여 백그라운드에서 자동으로 JSON 문자열로 변환됩니다. 답변. 그러나 모델을 엔드포인트 내에서 직접 JSON 문자열로 변환하려면 Pydantic의 model_dump_json()(Pydantic V2에서)(예: base.model_dump_json())을 사용하고 사용자 정의 응답을 직접 반환할 수 있습니다. 이전에 연결된 답변에서 설명한 대로; 따라서 jsonable_encoder의 사용을 피하세요. 그렇지 않은 경우, 모델을 자체적으로 dict로 변환하려면 Pydantic의 model_dump()(Pydantic V2에서)를 사용할 수 있습니다(예: base.model_dump() 또는 간단히 dict(base))( 엔드포인트인 경우 FastAPI는 위의 링크된 답변에 설명된 대로 여전히 배후에서 jsonable_encoder를 사용합니다. 관련 Pydantic 메소드 및 문서에 대한 이 답변을 살펴볼 수도 있습니다.

쿼리 매개변수에 대해 Pydantic 모델을 사용하는 것 외에도 이 답변에서 설명한 것처럼 엔드포인트에서 직접 쿼리 매개변수를 정의할 수도 있습니다. , 이 답변 및 이 답변도 포함됩니다.

기본 쿼리 매개변수 외에도 다음 /submit 엔드포인트는 요청에서 multipart/form-data로 인코딩된 파일도 예상합니다. body.

app.py

pip install python-multipart
로그인 후 복사
로그인 후 복사

다시 아래 템플릿을 사용하여 테스트할 수 있습니다. 이번에는 JavaScript를 사용하여 action 속성을 수정합니다. 양식 요소를 사용하여 양식 데이터를 쿼리 매개변수로 URL에 전달하는 대신 양식 데이터.

templates/index.html

from fastapi import Form, File, UploadFile, Request, FastAPI
from typing import List
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates

app = FastAPI()
templates = Jinja2Templates(directory="templates")


@app.post("/submit")
def submit(
    name: str = Form(...),
    point: float = Form(...),
    is_accepted: bool = Form(...),
    files: List[UploadFile] = File(...),
):
    return {
        "JSON Payload": {
            "name": name,
            "point": point,
            "is_accepted": is_accepted,
        },
        "Filenames": [file.filename for file in files],
    }


@app.get("/", response_class=HTMLResponse)
def main(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})
로그인 후 복사
로그인 후 복사

위 내용은 FastAPI POST 요청에서 JSON과 파일 업로드를 모두 수락하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿