구체적으로 아래 예가 작동하길 원합니다.
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 데이터 목록을 모두 업로드하는 방법을 찾고 있다면, 이 답변과 이 답변 및 작업 예제에 대한 답변(주로 다음 방법 중 일부를 기반으로 함)을 살펴보세요.
여기에 설명된 대로 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
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!