I would like to create pydantic model to validate users form. one of my model values should be validated from a list of names. I succeed to create the model using enum as follow:
from enum import Enum
class Fruit(str, Enum):
APPLE = 'apple'
BANANA = 'banana'
MELON = 'melon'
from pydantic import BaseModel
class UserForm(BaseModel):
fruit: Fruit
name: str
Now I would like to switch the enum to a list of values in my code:
fruit = ['apple','banana','melon']
How can I manage to do so?
tnx
Add the fields to validate to the @validator decorator directly above the validation function. @validator("name") uses the field value of "name" (e.g. "Peter" ) as input to the validation function. All fields of the class and its parent classes can be added to the @validator decorator.
Pydantic models can be defined with a custom root type by declaring the __root__ field. The root type can be any type supported by pydantic, and is specified by the type hint on the __root__ field.
Pydantic is a useful library for validating your data model at runtime period. This would make sure you put the input data with the correct type which prevents you get an unexpected error while in production. Pydantic provides a series of field types that you can use for validating input fields.
constr is a specific type that give validation rules regarding this specific type. You have equivalent for all classic python types.
We might consider using a pydantic model for the input validation. We can start out with the simplest form of a pydantic model, with field types: Pydantic models are simply classes inheriting from the BaseModel class. We can create an instance of the new class as:
Python dataclasses however do not support type or data validation unlike Pydantic. In other to get started with pydantic you would need to install it into your virtual machine. To use pydantic you have to import BaseModel then pass it as an argument in your class. Pydantic checks whether the data given matches the schema described, if it does.
It will print out the following JSON, which indicates that the input for id is not a valid integer. pydantic provides support for most of the common types from the Python standard library. The full list is as follows:
Besides passing values via the constructor, we can also pass values via copy & update or with setters (Pydantic’s models are mutable by default). These, however, have a surprising behavior. Copy & update won’t perform any type of validation. We can see that in the following example: Create a regular model that coerces input types.
You could do this also by means of a list of Literal
type. Like so:
import pydantic
from typing import Literal, List
class M(pydantic.BaseModel):
fruits: List[Literal["apple", "orange"]]
print(M.parse_obj({"fruits":["apple", "orange"]})) # OK fruits=['apple', 'orange']
print(M.parse_obj({"fruits":["apple", "orange", "potato"]})) # Error unexpected value potato
I am proposing an elegant solution.
from pydantic import BaseModel
from typing import List
from enum import Enum
class Fruit(str, Enum):
APPLE = 'apple'
BANANA = 'banana'
MELON = 'melon'
class UserForm(BaseModel):
fruits: List[Fruit]
name: str
And that's it.
Check the above code:
put the above code in a file main.py
.
Run
python -i main.py
>>> uf = UserForm(fruits=['apple','banana'],name='hello')
>>> uf
UserForm(fruits=[<Fruit.APPLE: 'apple'>, <Fruit.BANANA: 'banana'>], name='hello')
>>> af = UserForm(fruits=['monkey','apple'],name='hello')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "pydantic/main.py", line 400, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for UserForm
fruits -> 0
value is not a valid enumeration member; permitted: 'apple', 'banana', 'melon' (type=type_error.enum; enum_values=[<Fruit.APPLE: 'apple'>, <Fruit.BANANA: 'banana'>, <Fruit.MELON: 'melon'>])
>>>
pydantic will raise an error, as monkey
is not in fruits.
You can use validator
in the following way:
from pydantic import BaseModel, ValidationError, validator
class UserForm(BaseModel):
fruit: str
name: str
@validator('fruit')
def fruit_must_be_in_fruits(cls,fruit):
fruits=['apple','banana','melon']
if fruit not in fruits:
raise ValueError(f'must be in {fruits}')
return fruit
try:
UserForm(fruit="apple",name="apple")
except ValidationError as e:
print(e)
It will raise a validation error if it doesn't match the criteria.
You can get informations about the enum by its .__members__
dictionary - here you can simply iterate it keys though:
from enum import Enum
class Fruit(str, Enum):
APPLE = 'apple'
BANANA = 'banana'
MELON = 'melon'
# only need __members__ if you need more infos about it
print(Fruit.__members__)
# you do not need the __members__ if you just want the keys
print([name.lower() for name in Fruit])
Output:
# enums __members__ dictionary
{'APPLE': <Fruit.APPLE: 'apple'>,
'BANANA': <Fruit.BANANA: 'banana'>,
'MELON': <Fruit.MELON: 'melon'>}
# lower keys
['apple', 'banana', 'melon']
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With