-
Notifications
You must be signed in to change notification settings - Fork 691
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pydantic2 & double conversions (#22) #38
Comments
That is the nice catch! Probably, I messed up with migration from Pydantic v1 to v2 since the code of converting the BaseModel to dict is still there and there somewhere must be a validation with That is the important issue, so I will look at it properly later! |
Thanks for the prompt response, and the fastapi link! I used that to dig a bit deeper. I see there it does call I'll spare you the code, but I can modify you original code to override Looks like Yet when I call It's unclear to me which path the endpoint is taking through |
Well, I have some understanding right now with those updates. 1, If you change from Probably, the usage of those modes in |
If you want, you can make a PR with fixing the mode so that you would be added to the contributors list. |
Used First, my code: codeimport logging
from fastapi import FastAPI
from pydantic import BaseModel, model_validator
STACK_INFO = False
app = FastAPI()
class ProfileResponse(BaseModel):
def __init__(self, *args, **kwargs):
logging.error("init'd", stack_info=STACK_INFO)
super().__init__(*args, **kwargs)
@model_validator(mode="before")
@classmethod
def validate_before(cls, data: dict):
logging.error("validated before", stack_info=STACK_INFO)
return data
@model_validator(mode="after")
def validate_after(self):
logging.error("validated after", stack_info=STACK_INFO)
return self
def model_dump(self, **kwargs) -> dict:
logging.error("called model_dump", stack_info=STACK_INFO)
return super().model_dump(**kwargs)
def model_dump_json(self, *args, **kwargs) -> str:
logging.error("called model_dump_json", stack_info=STACK_INFO)
return super().model_dump_json(*args, **kwargs)
def dict(self, *args, **kwargs) -> dict:
logging.error("called dict", stack_info=STACK_INFO)
return super().dict(*args, **kwargs)
@app.get("/", response_model=ProfileResponse)
async def root():
return ProfileResponse() Calling that endpoint shows we only create the object and call the before-validator once, but we call the after-validator twice:
If we modify the endpoint to return If we then change The first set of logs, up through the first call to the after-validator, come from either stack traces
but the additional after-validation comes from stack trace
I think this shows that the double-creation problem has been fixed in the latest versions, but that a new, possibly-undesirable extra call to the after-validator is now present? Perhaps there's some other way to avoid that? Happy to file a PR; should I remove the section, or add some kind of note about it no longer applying? |
Hello,
Love this repo!
I was trying to modify your example from
#22
to check if nested models are round-tripped unnecessarily if contained within the dict I return in my endpoint function. Before I could do that, I had to update the example code in#22
to work with pydantic 2.0 (fastapi==0.100.1
,pydantic==2.4.2
). I first changed theroot_validator
tomodel_validator
:and when I run the app and hit that endpoint, I see "created pydantic model" once, and do not get "called dict" logged at all.
The
dict
method is deprecated in favor ofmodel_dump
, but if I also overridemodel_dump
andmodel_dump_json
:I don't get any of those "called ..." messages printed. If I use
jsonable_encoder
on a model in a terminal, I can see it usesmodel_dump_json
, but FastAPI doesn't seem to use any of these!So my questions are:
pydantic
andfastapi
, what happens if I return an object whose type matchesresponse_model
?The text was updated successfully, but these errors were encountered: