Dans FastAPI, vous pouvez créer un point de terminaison pouvant accepter un formulaire ou un corps JSON en utilisant différentes méthodes. Voici quelques options :
Cette option implique la création d'une fonction de dépendance qui vérifie la valeur de l'en-tête de la requête Content-Type et analyse le corps à l'aide des méthodes de Starlette. , en conséquence.
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
Une autre option consiste à avoir un seul point de terminaison et à définir vos paramètres de données de fichier et/ou de formulaire comme facultatifs. Si l'un des paramètres reçoit des valeurs, cela signifie que la requête était soit application/x-www-form-urlencoded, soit multipart/form-data. Sinon, il s'agissait probablement d'une requête JSON.
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}
Vous pouvez également utiliser un middleware pour vérifier la requête entrante et la rediriger vers le point de terminaison /submitJSON ou /submitForm, selon sur le type de contenu de la requête.
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
app = FastAPI()
@app.middleware("http")
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
Vous pouvez tester les options ci-dessus à l'aide de la bibliothèque de requêtes de 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)
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3