Home > Mobile >  Validating json with pydantic (fastapi)
Validating json with pydantic (fastapi)

Time:07-11

So I have a request that looks like this

[
    {
        "Code": "EVR-T-0dsfdsdf532",
        "Agent": "pacman",
        "Kilometrage": "60000",
        "Operation": "Vidange",
        "Piece_Consomable": "filtre à air",
        "Quantité": 1,
        "UnitPrice": "200.00",
        "Montant": 200,
        "Mainoeuvre": 100
    },
    {
        "Code": "EVR-T-ddsdf53dfds2",
        "Agent": "pacman",
        "Kilometrage": "60000",
        "Operation": "Pneumatique",
        "Piece_Consomable": "(Autre) Uiop",
        "Quantité": 1,
        "UnitPrice": "200.00"
    }
]

and my code looks like this

@app.post("/utilities/Entretien/submit", status_code=status.HTTP_200_OK)
async def create_item(item: Request, db: Session = Depends(get_db)):
    operations = await item.json()
    for i in operations:
        i : EntretienModel
        new_operation = TableEntretien(**i)
        db.add(new_operation)
        db.commit()
        db.refresh(new_operation)
    return {"ping": "pong"}

I'm basically looping through the array then inserting every object in the database, I'm looking for a solution that can validate every object with a pydantic model like this one:

class EntretienModel(BaseModel):
    Code: str
    Agent: str
    Kilometrage: int
    Operation: str
    Piece_Consomable: str
    Quantité: int
    UnitPrice: float
    Montant: int
    Mainoeuvre: Union[int, None] = None

Or another solution better than mine, Thanks.

CodePudding user response:

You can use the parse_obj_as Pydantic helper function to parse a list of dictionaries. So assuming item.json() returns a JSON string, you could do:

from pydantic import parse_obj_as

@app.post("/utilities/Entretien/submit", status_code=status.HTTP_200_OK)
async def create_item(item: Request, db: Session = Depends(get_db)):
    operations = await item.json()
    try:
        validated_operations = parse_obj_as(List[EntretienModel], json.loads(operations))
        for i in validated_operations:
            i : EntretienModel
            new_operation = TableEntretien(**i)
            db.add(new_operation)
            db.commit()
            db.refresh(new_operation)
    except ValidationError as e:
        print(e)

This will validate each json record in item as a dict. From there you can proceed with inserting the records into your database. parse_obj_as documentation

CodePudding user response:

In a FastAPI operation you can use a Pydantic model directly as a parameter. According to the FastAPI tutorial:

To declare a request body, you use Pydantic models with all their power and benefits.

[...]

With just that Python type declaration, FastAPI will:

  • Read the body of the request as JSON.
  • Convert the corresponding types (if needed).
  • Validate the data
  • [...]

Example:

@app.post("/utilities/Entretien/submit", status_code=status.HTTP_200_OK)
async def create_item(operations: List[EntretienModel], db: Session = Depends(get_db)):
    ...
  • Related