I want to customize the wrong version of pydantic, but it doesn't work。
I would like to ask what I should do。
from pydantic import BaseModel, ValidationError
class Model(BaseModel):
v: str
# def __init__(self,v =None):
# print('被调用了 外部类')
class Config:
max_anystr_length = 1
error_msg_templates = {
'value_error.any_str.max_length': 'max_length:{limit_value}',
}
@app.post("/items/")
async def create_item(item: Model):
return item
error_msg_templates definition does not work!
Thank you very much
How can I [...]?
Is it possible to [...]?
Add any other context or screenshots about the feature request here.
This one is actually interesting. Looks like pydantic's internal error_dict() function is overriding the previous custom error message and falls back to default because it did not get a valid model from FastAPI. It's being used publicly but it's mostly a pydantic internal function, and I would not blame pydantic here. I am not sure if FastAPI can use pydantic's internal more wisely somehow.
A more self-contained testcase:
from pydantic import BaseModel, ValidationError
from fastapi import FastAPI
from fastapi.exception_handlers import request_validation_exception_handler
from fastapi.exceptions import RequestValidationError
from starlette.requests import Request
from starlette.responses import Response
class Model(BaseModel):
v: str
class Config:
max_anystr_length = 1
error_msg_templates = {
'value_error.any_str.max_length': 'max_length:{limit_value}',
}
app = FastAPI()
@app.exception_handler(RequestValidationError)
async def http_exception_accept_handler(request: Request, exc: RequestValidationError) -> Response:
print(exc.raw_errors)
print(exc)
return await request_validation_exception_handler(request, exc)
@app.post("/")
async def create_item(item: Model):
return item
try:
Model.validate({'v':'x' * 20})
except ValidationError as e:
print(e)
Figured out some workaround:
@app.exception_handler(RequestValidationError)
async def http_exception_accept_handler(request: Request, exc: RequestValidationError) -> Response:
raw_errors = exc.raw_errors
error_wrapper: ErrorWrapper = raw_errors[0]
validation_error: ValidationError = error_wrapper.exc
overwritten_errors = validation_error.errors()
return JSONResponse(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content={"detail": jsonable_encoder(overwritten_errors)},
)
Now output will be as expected
I got the same Problem also!
I tested the same code in pydantic, it's OK, but in the environment of fastAPI, it returned the default error msg.
from pydantic import BaseModel, ValidationError
class UserModel(BaseModel):
name: str
age: int
class Config:
error_msg_templates = {"type_error.integer":"The param must be an integer!"}
try:
d = {"name":'aaa', "age":"ee"}
u = UserModel(**d)
print(u)
except ValidationError as e:
print(e)
# age
# The param must be an integer! (type=type_error.integer)
this is the code with fastAPI
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
name: str
age: int
class Config:
error_msg_templates = {"type_error.integer":"The param must be an integer!"}
@app.post('/')
def index(u:User):
return u
And the error msg is:
{
"detail": [
{
"loc": [
"body",
"u",
"age"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
}
Most helpful comment
This one is actually interesting. Looks like pydantic's internal
error_dict()function is overriding the previous custom error message and falls back to default because it did not get a valid model from FastAPI. It's being used publicly but it's mostly a pydantic internal function, and I would not blame pydantic here. I am not sure if FastAPI can use pydantic's internal more wisely somehow.https://github.com/samuelcolvin/pydantic/blob/d495710303c7716f0a54281b86a7c1c81930c223/pydantic/error_wrappers.py#L109-L111
A more self-contained testcase: