양식이나 JSON 본문을 허용하는 FastAPI 끝점을 만드는 방법은 무엇입니까?

DDD
풀어 주다: 2024-10-27 06:16:03
원래의
475명이 탐색했습니다.

How to Create a FastAPI Endpoint That Accepts Either Form or JSON Body?

양식 또는 JSON 본문을 수용할 수 있는 FastAPI 엔드포인트를 생성하는 방법은 무엇입니까?

FastAPI에서는 다음과 같은 다양한 유형의 요청 본문을 처리하는 엔드포인트를 정의할 수 있습니다. JSON 또는 양식 데이터. 이를 통해 별도의 엔드포인트 없이 두 형식 중 하나를 허용할 수 있는 엔드포인트를 생성할 수 있습니다.

이를 달성하려면 아래 접근 방식 중 하나를 따를 수 있습니다.

옵션 1: 종속성 기능 사용

종속성 기능을 활용하여 요청의 Content-Type 헤더를 확인한 다음 Starlette의 메서드를 사용하여 본문을 적절하게 구문 분석할 수 있습니다. Content-Type 헤더에만 의존하면 요청 본문의 유효성이 항상 보장되지 않을 수 있으므로 오류 처리를 포함하는 것이 좋습니다.

<code class="python">import os, sys
from fastapi import FastAPI, Depends, HTTPException
from starlette.requests import Request
app = FastAPI()

# Generating file
open("./app.txt", "w").write("hello from a file")

async def body_parser(request: Request):
    ct = request.headers.get("Content-Type", "")
    if ct == "application/json":
        try:
            d = await request.json()
            if not isinstance(d, dict):
                raise HTTPException(status_code=400, details={"error":"request body must be a dict"})
            return d
        except JSONDecodeError:
            raise HTTPException(400, "Could not parse request body as JSON")
    elif ct == "multipart/form-data":
        await request.stream()  # this is required for body parsing.
        d = await request.form()
        if not d:
            raise HTTPException(status_code=400, details={"error":"no form parameters found"})
        return d
    else:
        raise HTTPException(405, "Content-Type must be either JSON or multipart/form-data")

@app.post("/", dependencies=[Depends(body_parser)])
async def body_handler(d: dict):
    if "file" in d:
        return {"file": d["file"]}
    return d</code>
로그인 후 복사

옵션 2: 선택적 양식/파일 매개변수 활용

이 접근 방식에서는 엔드포인트에서 양식/파일 매개변수를 선택 사항으로 정의할 수 있습니다. 이러한 매개변수 중 하나에 값이 있으면 양식 데이터 요청으로 간주됩니다. 그렇지 않으면 요청 본문을 JSON으로 검증합니다.

<code class="python">from fastapi import FastAPI, Form, File, UploadFile
app = FastAPI()

@app.post("/")
async def file_or_json(
    files: List[UploadFile] = File(None),
    some_data: str = Form(None)
):
    if files:
        return {"files": len(files)}
    return {"data": some_data}</code>
로그인 후 복사

옵션 3: 각 유형에 대해 별도의 엔드포인트 정의

또한 JSON용 엔드포인트와 양식 데이터용 엔드포인트로 별도의 엔드포인트를 생성할 수도 있습니다. . 미들웨어를 사용하면 Content-Type 헤더를 확인하고 요청을 적절한 엔드포인트로 다시 라우팅할 수 있습니다.

<code class="python">from fastapi import FastAPI, Request, Form, File, UploadFile
from fastapi.responses import JSONResponse
app = FastAPI()

@app.middleware("http")
async def middleware(request: Request, call_next):
    ct = request.headers.get("Content-Type", "")
    if ct == "application/json":
        request.scope["path"] = "/json"
    elif ct in ["multipart/form-data", "application/x-www-form-urlencoded"]:
        request.scope["path"] = "/form"
    return await call_next(request)

@app.post("/json")
async def json_endpoint(json_data: dict):
    pass

@app.post("/form")
async def form_endpoint(file: UploadFile = File(...)):
    pass</code>
로그인 후 복사

옵션 4: 대체 접근 방식에 대한 다른 답변 참조

또한 다음을 수행할 수 있습니다. Stack Overflow에서 이 답변은 단일 엔드포인트에서 JSON과 양식 데이터를 모두 처리하는 데 다른 관점을 제공하므로 도움이 됩니다.

https://stackoverflow.com/a/67003163/10811840

테스트 옵션 1, 2, 3

테스트 목적으로 요청 라이브러리를 사용할 수 있습니다.

<code class="python">import requests

url = "http://127.0.0.1:8000"
# for testing Python 3.7 and above use:
# url = "http://localhost:8000"

# form-data request
files = [('files', ('a.txt', open('a.txt', 'rb'), 'text/plain'))]
response = requests.post(url, files=files)
print(response.text)

# JSON request
data = {"some_data": "Hello, world!"}
response = requests.post(url, json=data)
print(response.text)</code>
로그인 후 복사

이러한 접근 방식은 JSON과 양식을 모두 처리할 수 있는 엔드포인트를 생성하는 다양한 방법을 제공합니다. -FastAPI의 데이터. 귀하의 요구 사항과 사용 사례에 가장 적합한 접근 방식을 선택하세요.

위 내용은 양식이나 JSON 본문을 허용하는 FastAPI 끝점을 만드는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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