Já faz uns 4 anos que decidi experimentar Python e não deu outra: foi paixão arrebatadora. Mas algumas funcionalidades de outras linguagens e bibliotecas despertam saudades, uma delas foi o Bean Validation do Java EE.
Em um projeto que decidi usar Flask, Flask-Restless e SQLAlchemy, senti falta de algo parecido para fazer as validações de campos. O SQLAlchemy tem um decorator para validar campos, mas você precisa escrever dentro da função a validação. Para auxiliar na tarefa, criei uma biblioteca, chamada osirisvalidator, com decorators para auxiliar nessa validação.
Você pode clonar o código fonte em: https://github.com/davidaug/osirisvalidator (e contribuir com novas validações) ou instalar pelo comando:
pip install osirisvalidator
Sintaxe
Vamos considerar a classe User, que é um objeto Model do SQLAlchemy:
class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) cpf = db.Column(db.String(11), unique=True, nullable=False)
Para validar um campo no SQLAlchemy, é necessário fazer uma função com o decorator @validates , passando o nome do campo e criando os parâmetros key e value na função alvo.
class User(db.Model): [...] @validates('email') def validate_email(self, key, email): return email
Mais informações em: https://docs.sqlalchemy.org/en/13/orm/mapped_attributes.html
Com o osirisvalidator, podemos adicionar os decorators já prontos, como no exemplo abaixo:
from osirisvalidator.internet import valid_email [...] class User(db.Model): [...] @validates('email') @not_blank(field='email') @valid_email(field='email', message='email deve ser válido!') def validate_email(self, key, email): return email
O USO DO “@validates(‘nomecampo’)” É OBRIGATÓRIO!
O parâmetro “field” no decorator é obrigatório, e “message” é opcional, sendo que todas as validações já possuem uma mensagem padrão. Outros validadores possuem atributos próprios, como o osirisvalidator.string.string_len e o osirisvalidator.string.match_regex :
@validates('telefone') @is_digit(field='Telefone') @string_len(field='Telefone', min=10, max=11) def validate_telefone(self, key, telefone): return telefone
@validates("sexo") @match_regex(field='Sexo', regex=r'^[FMfm]$', message='Sexo deve ser F ou M') def validate_sexo(self, key, sexo): if sexo is not None: return sexo.upper()
Exemplo Completo em Flask
Para facilitar o entendimento, criei um script já completo utilizando Flask, basta instalar as dependências, que estão descritas no requirements.txt e rodar o arquivo app.py.
https://github.com/davidaug/osirisvalidator-flask-example
Caso seja encontrado algum erro de validação, uma ValidationException é disparada e é possível disponibilizar o erro ao consumidor:
except ValidationException as ve: return jsonify({"status": 400, "message": "erro de validação!", "errors": ve.errors}), 400

O osirisvalidator funciona em conjunto com o SQLAlchemy, logo, pode ser utilizado em qualquer lugar para validação de campos, incluindo uma aplicação Qt.
Validadores Implementados
osirisvalidator.string
- not_empty
- not_blank
- is_alpha
- is_alpha_space (alpha characters and space)
- is_alnum
- is_alnum_space (alphanumeric characters and space)
- is_digit
- string_len (mandatory parameters: min and max)
- match_regex (mandatory parameter: regex)
osirisvalidator.number
- min_max (mandatory parameters: min and max)
- not_null
osirisvalidator.internet
- valid_email
osiris.intl.br
- valid_cpf
- valid_cnpj