with Pydantic, how can i create my own ValidationError reason
Question:
it seems impossible to set a regex constraint with a __root__
field like this one:
class Cars(BaseModel):
__root__: Dict[str, CarData]
so, i’ve resorted to doing it at the endpoint:
@app.post("/cars")
async def get_cars(cars: Cars = Body(...)):
x = cars.json()
y = json.loads(x)
keys = list(y.keys())
try:
if any([re.search(r'^d+$', i) is None for i in keys]):
raise ValidationError
except ValidationError as ex:
return 'wrong type'
return 'works'
this works well in that i get wrong type
returned if i dont use a digit in the request body.
but i’d like to return something similar to what pydantic returns but with a custom message:
{
"detail": [
{
"loc": [
"body",
"__root__",
],
"msg": "hey there, you can only use digits!",
"type": "type_error.???"
}
]
}
Answers:
You can pass your own error string by using raise ValidationError("Wrong data type")
.
Hope it helps.
if it helps anyone, here is how i validated a dynamic field:
class Cars(BaseModel):
__root__: Dict[str, CarData]
@pydantic.root_validator(pre=True)
@classmethod
def car_id_is_digit(cls, fields):
car_ids = list(list(fields.values())[0].keys())
print(car_ids)
if any([bool(re.search(r'^d+$', car_id)) == False for car_id in car_ids]):
raise ValueError("car_id must be a string that is a digit.")
else:
return fields
since a regular field validator
requires a field name as an argument, i used the root_validator
which validates all fields – and does not require that argument.
all this, because __root__
cannot be referenced in the regular field validator, it seems.
however, this means you can only have __root__
fields – and they will all be under the same validation rules…not sure how to added more fields with this.
it seems impossible to set a regex constraint with a __root__
field like this one:
class Cars(BaseModel):
__root__: Dict[str, CarData]
so, i’ve resorted to doing it at the endpoint:
@app.post("/cars")
async def get_cars(cars: Cars = Body(...)):
x = cars.json()
y = json.loads(x)
keys = list(y.keys())
try:
if any([re.search(r'^d+$', i) is None for i in keys]):
raise ValidationError
except ValidationError as ex:
return 'wrong type'
return 'works'
this works well in that i get wrong type
returned if i dont use a digit in the request body.
but i’d like to return something similar to what pydantic returns but with a custom message:
{
"detail": [
{
"loc": [
"body",
"__root__",
],
"msg": "hey there, you can only use digits!",
"type": "type_error.???"
}
]
}
You can pass your own error string by using raise ValidationError("Wrong data type")
.
Hope it helps.
if it helps anyone, here is how i validated a dynamic field:
class Cars(BaseModel):
__root__: Dict[str, CarData]
@pydantic.root_validator(pre=True)
@classmethod
def car_id_is_digit(cls, fields):
car_ids = list(list(fields.values())[0].keys())
print(car_ids)
if any([bool(re.search(r'^d+$', car_id)) == False for car_id in car_ids]):
raise ValueError("car_id must be a string that is a digit.")
else:
return fields
since a regular field validator
requires a field name as an argument, i used the root_validator
which validates all fields – and does not require that argument.
all this, because __root__
cannot be referenced in the regular field validator, it seems.
however, this means you can only have __root__
fields – and they will all be under the same validation rules…not sure how to added more fields with this.