30 lines
1.1 KiB
Python
30 lines
1.1 KiB
Python
# retoor <retoor@molodetz.nl>
|
|||
|
|
import json
|
||
|
|
|
||
|
|
from fastapi import Request
|
||
|
|
from fastapi.exceptions import RequestValidationError
|
||
|
|
from pydantic import ValidationError
|
||
|
|
|
||
|
|
|
||
|
|
async def json_or_form(request: Request, model):
|
||
|
|
content_type = request.headers.get("content-type", "")
|
||
|
|
if content_type.startswith("application/json"):
|
||
|
|
try:
|
||
|
|
data = await request.json()
|
||
|
|
except json.JSONDecodeError as exc:
|
||
|
|
raise RequestValidationError([{"loc": ("body",), "msg": "Invalid JSON", "type": "json_invalid"}]) from exc
|
||
|
|
if not isinstance(data, dict):
|
||
|
|
raise RequestValidationError([{"loc": ("body",), "msg": "Expected an object", "type": "type_error"}])
|
||
|
|
else:
|
||
|
|
form = await request.form()
|
||
|
|
data = {}
|
||
|
|
for key in form.keys():
|
||
|
|
values = [value for value in form.getlist(key) if value != ""]
|
||
|
|
if not values:
|
||
|
|
continue
|
||
|
|
data[key] = values if len(values) > 1 else values[0]
|
||
|
|
try:
|
||
|
|
return model.model_validate(data)
|
||
|
|
except ValidationError as exc:
|
||
|
|
raise RequestValidationError(exc.errors()) from exc
|