Orator Validator

The idea of this libraries was to create a similar experience to model validation as mongoose and Ecto I believe this was achieved and gone beyond the desired goal.

The only problem with this library is that is more of a plugin that runs over a python orm named orator and the creator of Orator hasn't been working on Orator for a long time now, so I'm working on porting this validator into a new orm named Masonite ORM.

In 2021 I'm using the fast API framework on my job, and orator-validator is not ready for pydantic, but I'm looking for a way to make it work.

Some use cases

The power of orator-validator is a lot more than what I intended in the first version, my intentions were just to validate the model cleanly but the possibilities are a lot more promising.

You can have something like this.

Where you have a User model that has to have a name, email, and password but where you validate the email and password with a regex


from orator import Model
from orator_validator import Validator

class User(Model, Validator):

    __fillable__ = [
          'name', 'email', 'password', 'phone_number'
    ]

class Validate(object):

    def saving(self, user):
        user.validate('name', require=True)
        user.validate(
            'email', regex="(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"
        )
        user.validate(
            'password', regex="^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{6,}$"
        )
        user.errors()

User.observer(Validate())

Or like this

Where you validate some token insert for a OAuth server, but you don't allow the user to create a refresh_token instead, you create one before inserting into the database on the same model.

import string
import random
from orator import Model, SoftDeletes
from orator_validator import Validator


class Token(Model, SoftDeletes, Validator):

    __fillable__ = [
        'client_id', 'user_id', 'token_type',
        'access_token', 'refresh_token', 'expires',
        'scopes'
    ]

class ValidateClass(object):

    def saving(self, token):
        token.validate('client_id', require=True)
        token.validate('user_id', require=True)
        token.validate('token_type', require=True)
        token.validate('access_token', require=True)
        token.validate('expires', require=True)
        token.refresh_token = ''.join(
            [random.choice(self.__get_digits_letters()) for i in range(24)]
        )
        token.scopes = 'openid'
        token.errors()

    def __get_digits_letters(self):
        '''
        Function dedicated to return all letter and digits in a simple
        string

        return: letter_digit str
        '''
        return '{}{}'.format(
            string.ascii_letters, string.digits
        )

Token.observe(ValidateClass())