Cerberus List Schema is a Cerberus based validation library with extended methods to support list schemas as well as list transposition to dictionary and python objects.
- List/array schema support
- Transposition of lists to python objects via schemas
- Support for missing values in document
Cerberus List Schema can be installed using pip.
$ pip install cerberus-list-schema
>>> schema = {
>>> "type": "list",
>>> "items": [{"type": "string"}, {"type": "integer", "min": 20}],
>>> }
Lists can now be validated out of context of a dictionary
>>> document = ["Apples", 40]
>>> v = Validator(schema)
>>> v.validate(document)
True
... and usual cerberus validation rules still apply
>>> document = ["Apples", 15]
>>> v.validate(document)
False
>>> v.errors
{'_schema': [{1: ['min value is 20']}]}
In cerberus, documents that are missing information specified in a list schema will fail.
Using Cerberus List Schema you can pass allow_list_missing=True
to a Validator object to enable incomplete lists.
>>> document = ["Apples"]
>>> v.validate(document)
False
>>> v.errors
{'_schema': ['length of list should be 2, it is 1']}
>>> v = Validator(schema, allow_list_missing=True)
>>> v.validate(document)
True
Lists can now be normalized as dict additional to the standard cerberus validation. By default they are given a key equalled to their list index.
>>> document = {"produce": ["Apple", 5, "High"]}
>>> schema = {
>>> "produce": {
>>> "type": "list",
>>> "items": [
>>> {"type": "string"},
>>> {"type": "integer", "min": 0},
>>> {"type": "string"},
>>> ],
>>> }
>>> }
>>> v = Validator(schema)
>>> v.normalized_as_dict(document)
{"fruits": {0: "Apple", 1: 5, 2: "High"}}
However by using the name
rule, lists can be assigned to a namable dict. Note that this is different to rename
and should be preferred when using the dictionary normalization as rename can produce adverse effects.
>>> document = {"produce": ["Apple", 5, "High"]}
>>> schema = {
>>> "produce": {
>>> "type": "list",
>>> "name": "fruits",
>>> "items": [
>>> {"name": "type", "type": "string"},
>>> {"name": "count", "type": "integer", "min": 0},
>>> {"name": "quality", "type": "string"},
>>> ],
>>> }
>>> }
>>> v = Validator(schema)
>>> v.normalized_as_dict(document)
{'fruits': {'type': 'Apple', 'count': 5, 'quality': 'High'}}
By default, conflicting names will throw an error.
However, allow_name_conflicts
can be specified to ignore the error.
In this case, previous assignments will be overwritten without error
>>> document = {"produce": ["Apple", "Orange"]}
>>> schema = {
>>> "produce": {
>>> "type": "list",
>>> "items": [
>>> {"name": "fruit_type", "type": "string"},
>>> {"name": "fruit_type", "type": "string"},
>>> ],
>>> }
>>> }
>>> v = Validator(schema)
>>> v.normalized_as_dict(document)
AttributeError: `name` rule (`fruit_type`) already in use by another field
>>> v.normalized_as_dict(document, allow_name_conflicts=True)
{'produce': {'type': 'Orange'}}
Lists can now be normalized as dict additional to the standard cerberus validation.
By default they are given a key equalled to their list index. However name
may be used to rename
object property to that provided. (ensuring the name is a valid python variable name)
>>> document = {"produce": ["Apple", 5, "High"], "supplier": ["Greg", "United Kingdom", 7.34]}
>>> schema = {
>>> "produce": {
>>> "type": "list",
>>> "name": "fruits",
>>> "items": [
>>> {"name": "type", "type": "string"},
>>> {"name": "count", "type": "integer", "min": 0},
>>> {"name": "quality", "type": "string"},
>>> ],
>>> },
>>> "supplier": {
>>> "type": "list",
>>> "items": [
>>> {"type": "string"},
>>> {"type": "string"},
>>> {"type": "string", "coerce": int},
>>> ],
>>> },
>>> }
>>> v = Validator(schema)
>>> obj = v.normalized_as_object(document)
>>> obj.fruits.type # note produce has been renamed to fruits
'Apple'
>>> obj.fruits.quality
'High'
>>> obj.supplier[0]
'Greg'
>>> obj.supplier[2] # w/ coerce as int rule applied
7
Array values without a name
property can also be callable by using callable_numbers
. This is places an underscore
before the key index such that it can be called as a property of an object rather than by index.
>>> document = ["Greg", "United Kingdom", 7.34]
>>> schema = {
>>> "type": "list",
>>> "items": [
>>> {"type": "string"},
>>> {"type": "string", "name": "country"},
>>> {"type": "string", "coerce": int},
>>> ],
>>>}
>>> v = Validator(schema)
>>> obj = v.normalized_as_object(document, callable_numbers=True)
>>> obj._0
'Greg'
>>> obj._1 # value renamed to country
>>> obj.country
'United Kingdom'
>>> obj._2
7
More information about Cerberus and its validators can be found on their GitHub page @ https://github.com/pyeve/cerberus
Complete documentation for Cerberus is available at http://docs.python-cerberus.org