class Foo(BaseModel):
template : str
body: FooBody
class Bar(BaseModel):
template : str
body: BarBody
class Xyz(BaseModel):
template : str
body: XyzBody
@router.post("/something", status_code=status.HTTP_200_OK)
async def get_pdf(
request: Request,
request_body: Union[Foo, Bar, Xyz],
):
In the above code snippet my body can be of three types (any one) using Union
The code works perfect for the given body types. However if single field is missing the 422 validation error provides lot of missing fields even if only one field is missing.
What could be the cause of this. or I am I using Union incorrectly ?
My Goal is to only allow the mentioned BaseModel (Foo, Bar, Xyz) and if my request has detect Foo and certain field missing in the request then it should only show that filed instead of showing all the field in Bar, Xyz and the one missing in Foo
Minimum Reproducible Example
from typing import Union
from fastapi import FastAPI
app = FastAPI(debug=True)
from fastapi import APIRouter, status
from pydantic import BaseModel
class FooBody(BaseModel):
foo1: str
foo2: int
foo3: str
class Foo(BaseModel):
temp: str
body: FooBody
class BarBody(BaseModel):
bar1: str
bar2: int
bar3: str
class Bar(BaseModel):
temp: str
body: BarBody
class XyzBody(BaseModel):
xyz1: str
xyz2: int
xyz3: str
class Xyz(BaseModel):
temp: str
body: XyzBody
@app.get("/type", status_code=status.HTTP_200_OK)
def health(response_body: Union[Foo, Bar, Xyz]):
return response_body
so if I use
{
"temp": "xyz",
"body": {
"foo1": "ok",
"foo2": 1,
"foo3": "2"
}
}
It works as expected, but if I miss one parameter say foo3
in request body I don't get the validation error saying foo3 is missing instead I get
{
"detail": [
{
"loc": [
"body",
"body",
"foo3"
],
"msg": "field required",
"type": "value_error.missing"
},
{
"loc": [
"body",
"body",
"bar1"
],
"msg": "field required",
"type": "value_error.missing"
},
{
"loc": [
"body",
"body",
"bar2"
],
"msg": "field required",
"type": "value_error.missing"
},
{
"loc": [
"body",
"body",
"bar3"
],
"msg": "field required",
"type": "value_error.missing"
},
{
"loc": [
"body",
"body",
"xyz1"
],
"msg": "field required",
"type": "value_error.missing"
},
{
"loc": [
"body",
"body",
"xyz2"
],
"msg": "field required",
"type": "value_error.missing"
},
{
"loc": [
"body",
"body",
"xyz3"
],
"msg": "field required",
"type": "value_error.missing"
}
]
}
The entire class parameters mentioned in the Union.
Iam I using Union Wrong ?
What I neeed is like it should accept body of only of classes which I add I it detects its class Foo then it should only check for validations in the class Foo and not the entire thing.