Wie erstelle ich einen FastAPI-Endpunkt, der entweder Formulare oder JSON-Body akzeptiert?

DDD
Freigeben: 2024-10-27 06:16:03
Original
480 Leute haben es durchsucht

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

Wie erstelle ich einen FastAPI-Endpunkt, der entweder Form- oder JSON-Textkörper akzeptieren kann?

In FastAPI können Sie Endpunkte definieren, die verschiedene Arten von Anforderungstexten verarbeiten, z JSON oder Formulardaten. Dadurch können Sie Endpunkte erstellen, die beide Formate akzeptieren können, ohne dass separate Endpunkte erforderlich sind.

Um dies zu erreichen, können Sie einen der folgenden Ansätze verfolgen:

Option 1: Verwendung einer Abhängigkeitsfunktion

Sie können eine Abhängigkeitsfunktion verwenden, um den Content-Type-Header der Anfrage zu überprüfen und dann den Text mithilfe der Starlette-Methoden entsprechend zu analysieren. Beachten Sie, dass die alleinige Verwendung des Content-Type-Headers möglicherweise nicht immer die Gültigkeit des Anforderungstexts garantiert. Daher wird empfohlen, die Fehlerbehandlung einzubeziehen.

<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>
Nach dem Login kopieren

Option 2: Verwendung optionaler Formular-/Dateiparameter

Bei diesem Ansatz können Sie Formular-/Dateiparameter in Ihrem Endpunkt als optional definieren. Wenn einer dieser Parameter Werte hat, wird von einer Formulardatenanforderung ausgegangen. Andernfalls wird der Anforderungstext als JSON validiert.

<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>
Nach dem Login kopieren

Option 3: Separate Endpunkte für jeden Typ definieren

Sie können auch separate Endpunkte erstellen, einen für JSON und einen für Formulardaten . Mit einer Middleware können Sie den Content-Type-Header überprüfen und die Anfrage an den entsprechenden Endpunkt umleiten.

<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>
Nach dem Login kopieren

Option 4: Verweisen auf eine andere Antwort für einen alternativen Ansatz

Darüber hinaus können Sie Ich finde diese Antwort auf Stack Overflow hilfreich, da sie eine andere Perspektive auf die Verarbeitung von JSON- und Formulardaten in einem einzigen Endpunkt bietet:

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

Testoptionen 1, 2 und 3

Zu Testzwecken können Sie die Anforderungsbibliothek verwenden:

<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>
Nach dem Login kopieren

Diese Ansätze bieten verschiedene Methoden zum Erstellen eines Endpunkts, der sowohl JSON als auch Formulare verarbeiten kann -Daten in FastAPI. Wählen Sie den Ansatz, der Ihren Anforderungen und Ihrem Anwendungsfall am besten entspricht.

Das obige ist der detaillierte Inhalt vonWie erstelle ich einen FastAPI-Endpunkt, der entweder Formulare oder JSON-Body akzeptiert?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage