I am currently struggling to define a base model correctly displaying the data I want to send to it using postman's "raw body" (type set to JSON).
I want to send a body looking something like this:
{
"a": [
{
"text": "text",
"language": "en",
"entities": [
{ "d": "g" },
{ "e": "h" },
{ "f": "i" }
]
},
{
"text": "another text",
"language": "en",
"entities": [
{ "d": "z" }
]
}
],
"b": [
{
"text": "more texts",
"language": "en",
"entities": [
{ "d": "r" },
{ "e": "t" },
{ "f": "z" }
]
}
],
"c": ["d", "e", "f"]
}
My endpoint in fastapi looks like this:
@app.post("/json")
def method(a: AModel, b: BModel, c: CModel):
# code
and the BaseModels are:
class Input(BaseModel):
text: str = Field (
title="A text", example= "text"
)
language: str = Field (
default=None, title="A language string", max_length=2, example="en"
)
entities: Dict[str, str] = Field (
default=None, title="xxx.",
example= [{"d": "x"}, {"f": "y"}]
)
class Config:
orm_mode=True
class CModel (BaseModel):
c: List[str] = Field (
title="xxx.", example= ["d", "e", "f"]
)
class BModel (BaseModel):
b: List[Input] = Field (
title="yyy."
)
class AModel (BaseModel):
a: List[Input] = Field (
title="zzz."
)
However, sending the data to postman returns:
{
"detail": [
{
"loc": [
"body",
"trainingdata"
],
"msg": "value is not a valid dict",
"type": "type_error.dict"
},
{
"loc": [
"body",
"testingdata"
],
"msg": "value is not a valid dict",
"type": "type_error.dict"
},
{
"loc": [
"body",
"entities"
],
"msg": "value is not a valid dict",
"type": "type_error.dict"
}
]
}
(I am aware AModel and BModel have the same structure)
Now, I wanted to ask how I need to adjust my BaseModels to represent the structure I have shown in my initial body. I have seen people with similar issues but couldn't quite pinpoint it in my case.
Can anyone help?
EDIT: I forgot to mention that I cannot hardcode d, e and f into my BaseModel as these are just examples and I can't ever know for sure which keys the values there have.
CodePudding user response:
entities
should be List[Dict[str, str]]
and your route method should be as
class Combo(AModel, BModel, CModel):
...
@app.post("/")
def method(combo: Combo):
return {
"combo": combo
}