0

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.

1 Answers1

1

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
    }
JPG
  • 82,442
  • 19
  • 127
  • 206
  • Didn't completely follow it, but I liked the Idea so I removed AModel, BModel and CModel and just merged their contents into one BaseModel class (originally didn't want to for several reasons, but looked like the cleanest way) and the entity part helped a lot! Thanks! – AnnemarieWittig Aug 12 '22 at 16:06