I released "pyvaru" (https://github.com/daveoncode/pyvaru) a couple of days ago, it is a simple, flexible and unobtrusive data validation library for Python 3 (3.4+), based on the concept of validation rules.
Given an existing model to validate, like the one below (but it could
be a simple dictionary or any data structure since pyvaru does not
make any assumption on the data format):
class User:
def __init__(self, first_name: str, last_name: str, date_of_birth: datetime, sex: str):
self.first_name = first_name
self.last_name = last_name
self.date_of_birth = date_of_birth
self.sex = sex
We have to define a validator, by implementing the get_rules() method
and for each field we want to validate we have to provide one or more
proper rule(s).
from pyvaru import Validator
from pyvaru.rules import TypeRule, FullStringRule, ChoiceRule, PastDateRule
class UserValidator(Validator):
def get_rules(self) -> list:
user = self.data # type: User
return [
TypeRule(apply_to=user,
label='User',
valid_type=User,
error_message='User must be an instance of user model.',
stop_if_invalid=True),
FullStringRule(user.first_name, 'First name'),
FullStringRule(user.last_name, 'Last name'),
ChoiceRule(user.sex, 'Sex', choices=('M', 'F')),
PastDateRule(user.date_of_birth, 'Date of birth')
]
Finally we have two choices regarding how to use our custom validator:
As a context processor:
with UserValidator(user):
# do whatever you want with your valid model
In this case the code inside with will be executed only if the
validation succeed, otherwise a ValidationException (containing a
validation_result property with the appropriate report) is raised.
By invoking the validate() method (which returns a ValidationResult)
validation = UserValidator(user).validate()
if validation.is_successful():
# do whatever you want with your valid model
else:
# you can take a proper action and access validation.errors
# in order to provide a useful message to the application user,
# write logs or whatever
Assuming we have a instance of an User configured as the one below:
user = User(first_name=' ',
last_name=None,
date_of_birth=datetime(2020, 1, 1),
sex='unknown')
By running a validation with the previous defined rules we will obtain
a ValidationResult with the following errors:
{
'First name': ['String is empty.'],
'Last name': ['Not a string.'],
'Sex': ['Value not found in available choices.'],
'Date of birth': ['Not a past date.']
}