Skip to main content

Cerberus validation support for Morepath

Project description

more.cerberus: validation and normalization support for Morepath

This package provides Morepath integration for the Cerberus data validation library:

Cerberus can automate user input validation and normalization in a HTTP API.

Schema

You can define a schema simply as a Python dict:

user_schema = {
  'name': {'type': 'string', 'minlength' : 3, 'required': True},
  'age': {'type': 'integer', 'min': 0, 'required': True}
}

Altenatively you can define the schema in yaml and load it with pyyaml:

user:
  name:
    type: string
    minlength: 3
    required: true
  age:
    type: integer
    min: 0
    required: true
import yaml

with open('schema.yml') as schema:
    schema = yaml.load(schema)

user_schema = schema['user']

Validate

The more.cerberus integration helps with validation of the request body as it is POSTed or PUT to a view. First we must create a loader for our schema:

from more.cerberus import loader

user_schema_load = loader(user_schema)

We can use this loader to handle a PUT or POST request for instance:

@App.json(model=User, request_method='POST', load=user_schema_load)
def user_post(self, request, json):
    # json is now a validated and normalized dict of whatever got
    # POST onto this view that you can use to update
    # self

Update models

By default in PUT or PATCH requests the load function sets the update flag of the validate() method to True, so required fields won’t be checked. For other requests like POST update is False.

You can set this manually by passing the update argument to the load function:

user_schema_load = loader(user_schema, update=False)

@App.json(model=User, request_method='PUT', load=user_schema_load)
def user_put(self, request, json):

Customize the Validator

With Cerberus you can customize the rules, data types, validators, coercers (for normalization) and default setters by subclassing CerberusValidator:

import re
from more.cerberus import CerberusValidator

class CustomValidator(CerberusValidator):
    def _validator_validate_email(self, field, value):
      match = re.match(
        '^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$',value
      )
      if match == None:
        self._error(field, 'Not valid email')

    def _normalize_coerce_normalize_email(self, value):
        parts = value.split('@')
        if len(parts) != 2:
          return value
        else:
          domain = parts[1].lower
          if domain == 'googlemail.com':
            domain = 'gmail.com'
          return parts[0] + '@' + domain

You have to pass the custom Validator class to the load function:

user_schema_load = loader(user_schema, validator=CustomValidator)

Now you can use the new email validator and normalizer in your schema:

user_schema = {
  'name': {'type': 'string', 'minlength' : 3, 'required': True},
  'email': {'type': 'string', 'validator': 'validate_email',
            'coerce': 'normalize_email','required': True}
}

or with YAML:

user:
  name:
    type: string
    minlength: 3
    required: true
  email:
    type: string
    validator: validate_email
    coerce: normalize_email
    required: true

For more information how to customize the Validator take a look at the Cerberus documentation.

Use the request or app instance in your custom validator

In CerberusValidator you can access the request through self.request and the app through self.request.app. Like this you can use e.g. Morepath settings and services when extending rules.

Here an example from auth-boilerplate for custom email validation and normalization using a service based on email_validator:

from more.cerberus import CerberusValidator
from email_validator import EmailSyntaxError, EmailUndeliverableError


class Validator(CerberusValidator):
    def _validator_verify_email(self, field, value):
        email_validation_service = self.request.app.service(
            name='email_validation'
        )
        try:
            email_validation_service.verify(value)

        except EmailSyntaxError:
            self._error(field, 'Not valid email')

        except EmailUndeliverableError:
            self._error(field, 'Email could not be delivered')

    def _normalize_coerce_normalize_email(self, value):
        email_validation_service = self.request.app.service(
            name='email_validation'
        )
        return email_validation_service.normalize(value)

Error handling

If validation fails due to a validation error (a required field is missing, or a field is of the wrong datatype, for instance), you want to show some kind of error message. The load function created by more.cerberus raises the more.cerberus.ValidationError exception in case of errors.

This exception object has an errors attribute with the validation errors. You must define an exception view for it, otherwise validation errors are returned as “500 internal server error” to API users.

This package provides a default exception view implementation. If you subclass your application from more.cerberus.CerberusApp then you get a default error view for ValidationError that has a 422 status code with a JSON response with the Cerberus errors structure:

from more.cerberus import CerberusApp

class App(CerberusApp):
    pass

Now your app has reasonable error handling built-in.

CHANGES

0.1 (2017-03-17)

  • initial public release.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

more.cerberus-0.1.tar.gz (7.4 kB view details)

Uploaded Source

Built Distribution

more.cerberus-0.1-py2.py3-none-any.whl (10.5 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file more.cerberus-0.1.tar.gz.

File metadata

  • Download URL: more.cerberus-0.1.tar.gz
  • Upload date:
  • Size: 7.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for more.cerberus-0.1.tar.gz
Algorithm Hash digest
SHA256 4777184454424ea3ae6af0281f551ef94ac63561f325d6f314d85785e897cae5
MD5 3e38ef044d5fd477738d1f3343fa86f4
BLAKE2b-256 d85af411786086840f903d4da852268761104c740ed3068daf161f2f0437ed68

See more details on using hashes here.

Provenance

File details

Details for the file more.cerberus-0.1-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for more.cerberus-0.1-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 a7f4176b6d4f462516ad0e79fbb288ce9147beeb357205dedd43945d67d8b375
MD5 16cadc2b9cdc16deb79e3b848c0c081d
BLAKE2b-256 cabdd0c9e2cf7049e0e1c27bf0327301ab16d66ca416c04d903a0675cfab3a23

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page