Validatish – a Python validation library

I was looking for a good validation library in Python and then I found validatish. As usual, it uses exceptions every time it encounters an error. I like its simplicity and ease of use. Below is how I used it on a basic contact form.

Basic usage

You can get validatish from here or you may install it via easy_install or other command line installer tool for Python. Me, I just downloaded it an put on my project top level directory since I’m using it on my Google AppEngine site.

It has two way to use; function calls and validation classes. I used the simple function calls for its straightforwardness. Below are basic examples.

import validatish

name = ''
email = 'foo'

try:
    validatish.validate.is_required(name)
    validatish.validate.has_length(name, 50, 100)
    validatish.validate.is_required(email)
    validatish.validate.is_email(email)
except validatish.Invalid as e:
    print e.message

When the validator encounters an invalid value, it throws validatish.Invalid exception. In our example above, it will catch the first error it encounters then prints the error message.

Customizing error messages

Each validation function provides an optional parameter, a dictionary of messages where you can override the default messages the validator provides. Below is an example.

validatish.validate.is_required(name, {
    'required': 'Name is required'
});
validatish.validate.has_length(name, 2, 100, {
    'between': 'Enter a valid name',
    'fewer-than': 'Name is too short',
    'more-than': 'Name is too long',
})
validatish.validate.is_required(email, {
    'required': 'Email is required'
})
validatish.validate.has_length(email, 10, 100, {
    'between': 'Enter a valid email',
    'fewer-than': 'Email is too short',
    'more-than': 'Email is too long',
})
validatish.validate.is_email(email, {
    'type-string': 'Enter a valid email',
    'contain-at': 'Enter a valid email',
    'username-incorrect': 'Enter a valid email',
    'domain-incorrect': 'Enter a valid email',
})

Collecting error messages

Now that we got our validators working, what if we need to get all error messages then display them on the page? With few lines of code, we can achieve that, below is an example.

def validate_post(self, name, email):
    messages = {}
    field_validators = {
        'name': [
            ['is_required', name, {
                'required': 'Name is required'
            }],
            ['has_length', name, 2, 100, {
                'between': 'Enter a valid name',
                'fewer-than': 'Name is too short',
                'more-than': 'Name is too long',
            }],
        ],
        'email': [
            ['is_required', email, {
                'required': 'Email is required'
            }],
            ['has_length', email, 10, 100, {
                'between': 'Enter a valid email',
                'fewer-than': 'Email is too short',
                'more-than': 'Email is too long',
            }],
            ['is_email', email, {
                'type-string': 'Enter a valid email',
                'contain-at': 'Enter a valid email',
                'username-incorrect': 'Enter a valid email',
                'domain-incorrect': 'Enter a valid email',
            }],
        ]
    }

    # Call all validators and collect error messages
    for field,validators in field_validators.items():
        # Only get 1 error per field
        try:
            for v in validators:
                method = v[0]
                args = v[1:]
                fn = getattr(validatish.validate, method)
                fn(*args)
        except validatish.Invalid as e:
            messages[field] = e.message

    # If can haz messages, throw a big exception
    if len(messages):
        raise validatish.Invalid(messages)

We can enhance this by putting all this thing (validators and error messages) on a config file. That should be trival to implement.

This entry was posted in Python and tagged , , , . Bookmark the permalink.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *