Heim  >  Artikel  >  Backend-Entwicklung  >  Wie werden sowohl Formular- als auch JSON-Daten in einem einzigen FastAPI-Endpunkt verarbeitet?

Wie werden sowohl Formular- als auch JSON-Daten in einem einzigen FastAPI-Endpunkt verarbeitet?

Patricia Arquette
Patricia ArquetteOriginal
2024-10-26 23:22:30660Durchsuche

How to Handle Both Form and JSON Data in a Single FastAPI Endpoint?

Wie erstelle ich einen FastAPI-Endpunkt, der entweder ein Formular oder einen JSON-Text akzeptieren kann?

In FastAPI können Sie einen Endpunkt erstellen, der entweder ein Formular oder einen JSON-Text akzeptieren kann mit unterschiedlichen Methoden. Hier sind einige Optionen:

Option 1: Verwendung einer Abhängigkeitsfunktion

Diese Option beinhaltet das Erstellen einer Abhängigkeitsfunktion, die den Wert des Content-Type-Anfrageheaders überprüft und den Text mithilfe der Methoden von Starlette analysiert , entsprechend.

<code class="python">from fastapi import FastAPI, Depends, Request
from starlette.datastructures import FormData

app = FastAPI()

async def get_body(request: Request):
    content_type = request.headers.get('Content-Type')
    if content_type is None:
        raise HTTPException(status_code=400, detail='No Content-Type provided!')
    elif content_type == 'application/json':
        return await request.json()
    elif (content_type == 'application/x-www-form-urlencoded' or
          content_type.startswith('multipart/form-data')):
        try:
            return await request.form()
        except Exception:
            raise HTTPException(status_code=400, detail='Invalid Form data')
    else:
        raise HTTPException(status_code=400, detail='Content-Type not supported!')

@app.post('/')
def main(body = Depends(get_body)):
    if isinstance(body, dict):  # if JSON data received
        return body
    elif isinstance(body, FormData):  # if Form/File data received
        msg = body.get('msg')
        items = body.getlist('items')
        return msg</code>

Option 2: Separate Endpunkte definieren

Eine andere Option besteht darin, einen einzelnen Endpunkt zu haben und Ihre Datei(en) und/oder Formulardatenparameter als optional zu definieren. Wenn an einen der Parameter Werte übergeben werden, bedeutet dies, dass die Anfrage entweder application/x-www-form-urlencoded oder multipart/form-data war. Andernfalls handelte es sich wahrscheinlich um eine JSON-Anfrage.

<code class="python">from fastapi import FastAPI, UploadFile, File, Form
from typing import Optional, List

app = FastAPI()

@app.post('/')
async def submit(items: Optional[List[str]] = Form(None),
                    files: Optional[List[UploadFile]] = File(None)):
    # if File(s) and/or form-data were received
    if items or files:
        filenames = None
        if files:
            filenames = [f.filename for f in files]
        return {'File(s)/form-data': {'items': items, 'filenames': filenames}}
    else:  # check if JSON data were received
        data = await request.json()
        return {'JSON': data}</code>

Option 3: Verwendung einer Middleware

Sie können auch eine Middleware verwenden, um die eingehende Anfrage zu überprüfen und sie entweder an /submitJSON oder / umzuleiten. „submitForm“-Endpunkt, abhängig vom Inhaltstyp der Anfrage.

<code class="python">from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse

app = FastAPI()

@app.middleware(&quot;http&quot;)
async def some_middleware(request: Request, call_next):
    if request.url.path == '/':
        content_type = request.headers.get('Content-Type')
        if content_type is None:
            return JSONResponse(
                content={'detail': 'No Content-Type provided!'}, status_code=400)
        elif content_type == 'application/json':
            request.scope['path'] = '/submitJSON'
        elif (content_type == 'application/x-www-form-urlencoded' or
              content_type.startswith('multipart/form-data')):
            request.scope['path'] = '/submitForm'
        else:
            return JSONResponse(
                content={'detail': 'Content-Type not supported!'}, status_code=400)

    return await call_next(request)

@app.post('/')
def main():
    return

@app.post('/submitJSON')
def submit_json(item: Item):
    return item

@app.post('/submitForm')
def submit_form(msg: str = Form(...), items: List[str] = Form(...),
                    files: Optional[List[UploadFile]] = File(None)):
    return msg</code>

Testen der Optionen

Sie können die oben genannten Optionen mit der Anforderungsbibliothek von Python testen:

<code class="python">import requests

url = 'http://127.0.0.1:8000/'
files = [('files', open('a.txt', 'rb')), ('files', open('b.txt', 'rb'))]
payload ={'items': ['foo', 'bar'], 'msg': 'Hello!'}
 
# Send Form data and files
r = requests.post(url, data=payload, files=files)  
print(r.text)

# Send Form data only
r = requests.post(url, data=payload)              
print(r.text)

# Send JSON data
r = requests.post(url, json=payload)              
print(r.text)</code>

Das obige ist der detaillierte Inhalt vonWie werden sowohl Formular- als auch JSON-Daten in einem einzigen FastAPI-Endpunkt verarbeitet?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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