We recently upgraded all of our Starlite-based services to v2, in the process of which we turned up this rather puzzling issue. Specifically, it appears that Pydantic validators are not run for input parameters to handler methods. This is rather unintuitive for us and caused some headaches in regards to data parsing/validating/munging, as exemplified in the MCVE below.
What we expected with a handler like this:
async def mwe_bad(data: MyType) -> dict:
would be that the type would be instantiated from the incoming request body and the validators would run to do potential extra checks and/or manipulate the data slightly.
This seemingly does not happen, instead it seems to be the case that the class is filled with data but bypasses its own validators. Not sure how that can occur, but it's what we're observing. See the MVCE for a detailed reproduction. This same issue also occurs with Pydantic v1 by the way, both versions of Pydantic behave the same in this case.
Let me know if you need any additional information and I'll be happy to oblige.
No response
"""
Run with:
uvicorn main:app --reload
Works:
curl --location 'http://localhost:8000/good' --header 'Content-Type: application/json' --data '{"picture": "test"}'
Doesn't work:
curl --location 'http://localhost:8000/bad' --header 'Content-Type: application/json' --data '{"picture": "test"}'
"""
from dataclasses import field
from litestar import Litestar, post
from pydantic import field_validator
from pydantic.dataclasses import dataclass
@dataclass
class MyType:
picture: list[str] = field(default_factory=list)
@field_validator("picture", mode="before")
@classmethod
def single_picture_validator(cls, v):
if isinstance(v, str):
return [v]
return v
@post("/good")
async def mwe_good(data: dict) -> dict:
data = MyType(**data)
return data
@post("/bad")
async def mwe_bad(data: MyType) -> dict:
return data
app = Litestar([mwe_good, mwe_bad], debug=True)
1. Test the working endpoint: `curl --location 'http://localhost:8000/good' --header 'Content-Type: application/json' --data '{"picture": "test"}'`
2. Test the broken endpoint: `curl --location 'http://localhost:8000/bad' --header 'Content-Type: application/json' --data '{"picture": "test"}'`
3. Observe that Step 2 fails with a validation error that does not occur in Step 1, even though the same type is used.
No response
No response
2.2.1
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too