How to validate cerberus schema

1.3k Views Asked by At

My web application uses Cerberus schema validation for each request (current version is 1.2). For this purposes I'm writing schema in YAML, load it on application start and do validation and use a lot of back references to optimize my work as shown in a schema below.

It's very unfortunate to catch schema errors in tests/runtime. How to validate a schema itself on application startup without writing dummy values for each one?

---
_required_string: &required_string
  type: string
  empty: False
  required: True
  nullable: False

# Sign in request body
signin:
  type: dict
  empty: False
  nullable: False
  schema:
    name: *required_string
    password: *required_string
1

There are 1 best solutions below

1
On

I hope this answers your question as I am not quite sure that I understood it correctly. This does feel a little bit like a workaround, but it will do what you want it too. It sounds like you want to reuse a set of requirements in multiple places. The best choice I see for this is to create a custom Validator subclass and add a custom validator method to handle the shared rule sets. The code below should work given the example you provided.

from cerberus import Validator
import yaml

class MyValidator(Validator):
    def _validator_required_string(self, field, value):
        # Check the type
        if type(value) != str:
            self._error(field, "Must be of type 'str'")
        # Check the length
        if len(value) == 0:
            self._error(field, "Cannot be blank")

data = {"signin": { "name": "myusername",
                    "password": "mypassword"}}

schema = '''
signin:
    type: dict
    empty: False
    nullable: False
    schema:
        name:
            validator: required_string
        password:
            validator: required_string
'''

v = MyValidator(yaml.load(schema))

You can check out the Custom Validators documentation here to understand the naming requirements. As a side note, if you can define your schema in Python code instead of YAML, you could define a required_string variable which holds a dictionary of the actual rules you want to use and then reference that variable in the larger schema definitions. This would allow you to use the actual rules instead of having to define a function to implement the rules.