2023-03-13

each_item Flag in Pydantic Validators

each_item Flag in Pydantic Validators

The each_item flag is a feature in Pydantic validators that, when set to True, allows the validator to apply the defined validation rules to each item within an iterable (e.g., lists, dictionaries) in the input data.

Implementing the each_item Flag

To use the each_item flag, import the validator decorator from the Pydantic library, define a validation function, and set each_item=True. The validation function should receive the field name, the field value, and the values of the model instance, and return the validated value or raise a validation error if the input does not meet the specified criteria.

Here's an example:

python
from pydantic import BaseModel, validator

class PositiveNumberList(BaseModel):
    numbers: List[int]

    @validator('numbers', each_item=True)
    def validate_positive(cls, item):
        if item < 0:
            raise ValueError('Item must be a positive integer')
        return item

In this example, we've defined a PositiveNumberList model with a numbers field that expects a list of integers. We've also created a validator for the numbers field that checks each item to ensure it is a positive integer. By setting each_item=True, the validator applies the validate_positive function to each item in the list.

Common Mistakes and Solutions

When using the each_item flag, it is crucial to remember that the validator will be applied to each item within the iterable. One common mistake is to apply the validation logic to the entire iterable instead of each item. To avoid this, ensure that the validation logic within the function is designed to operate on individual items.

For example, consider the following incorrect implementation:

python
from pydantic import BaseModel, validator

class IncorrectPositiveNumberList(BaseModel):
    numbers: List[int]

    @validator('numbers', each_item=True)
    def validate_positive(cls, numbers):
        for number in numbers:
            if number < 0:
                raise ValueError('All items must be positive integers')
        return numbers

In this case, the validator function validate_positive is incorrectly looping through the numbers iterable inside the function, while the each_item=True flag is already applying the function to each item. This would result in a TypeError since the function expects an integer but receives a list.

To fix this, rewrite the function to operate on individual items:

python
from pydantic import BaseModel, validator

class CorrectPositiveNumberList(BaseModel):
    numbers: List[int]

    @validator('numbers', each_item=True)
    def validate_positive(cls, number):
        if number < 0:
            raise ValueError('Item must be a positive integer')
        return number

Now, the validate_positive function correctly operates on each item in the numbers list, ensuring that every number is a positive integer.

References

https://docs.pydantic.dev/usage/validators/

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!