Open kakakikikeke-fork opened 7 months ago
@kakakikikeke-fork Hi there, thank you for the issue and also the PR. I did some investigation today and yesterday, it is indeed a valid issue and would occur on not only things like body_params but also things like query params since they are based on the same fundation. The PR #84 is currently failing the unit test on CI, I belive its caused by calling err.get("body_params") on err that does not have "body_params", so request that only has query_params if that makes sense.
@yctomwang I tried supporting parameters other than body_params. I have locally run pytest I have also verified that locally all pytest tests are successful. Thanks.
As a workaround for your custom validations you can use PydanticCustomError
from pydantic_core
.
from pydantic_core import PydanticCustomError
def custom_validator(value: str) -> str:
if value == "bad":
raise PydanticCustomError("bad_str", "bad is not good.")
return value
Instead of removing ctx (or url, or input), it would be better to introduce some arguments to 'validate' decorator, similar to include_context|include_url|include_input and pass it down to ve.errors
@nickzorin yep i have to agree with this, removing the ctx would not be the best idea. I am planning to spend some time eventually to deal with this issue, current we are storing the acutal objects hence the reason for the error apprearing. This will require a bit of rework to get all exist test cases to adapt. Also currently the CI is failing because of the pytest black plugin. For some reason I cannot merge to master to address the CI issue.
Any updates on this? I'm planning to introduce flask-pydantic to my org but feel that with all this extra context we are exposing far more info than is desirable.
Guys, any updates so far?( this is really really frustrating! This issue literally means that you cannot use all the pydantic field_validator
or model_validator
by raising python's AssertionError
or ValueError
. Just a small example:
class RequestBodyModel(BaseModel):
name: str
phone_number: Optional[str] = None
email: Optional[EmailStr] = None
@model_validator(mode='before')
@classmethod
def check_email_or_phone(cls, data: Any) -> Any:
email = data.get('email')
phone_number = data.get('phone_number')
assert bool(email) ^ bool(phone_number), 'Email or phone number must be provided, but not both'
return data
And obviously because of ctx
includes the error as Python object, Flask cannot jsonify
the response. @yctomwang I have a simple suggestion as a maybe workaround, just in order to allow Flask does its' JSON serialization job:
ctx
is a kinda optional, so I do not see any objections removing it from the resulting dict
convert_errors()
func, which can do anything we want, e.g. converting AssertionError
/ValueError
exception instances to a str
using builtin repr()
:
>>> repr(err['body_params'][0]['ctx']['error'])
"AssertionError('Email or phone number must be provided, but not both')"
We literally got the ci fixed this week and can finally merge code into the master. After some careful thinking, i think the remove appraoch in #84 might not be the best. We are planning to get this issue addressed as soon as possible. any ideas are welcome
If you intentionally raise ValueError, a field called ctx seems to be added. An example of pydantic v2 error object.
An error object is included in ctx and the error object cannot be serialized to dict, resulting in an error. The traceback is this.
I solved it by deleting ctx, is there anything else I can do? #84
Thanks.