Is it possible for cerberus to check nested recursive structure?

60 Views Asked by At

So there is a response, which has recursive list children :

resp = [{'name': "child-1",
      'cap': 3,
      'children': [
          {
              'name': "child-11",
              'cap': 3,
              'children': [
                  {
                      'name': "child-111",
                      'cap': 3,
                      'children': []
                  },
                  {
                      'name': "child-112",
                      'cap': "Str err",
                      'children': []
                  }
              ]
          }
      ]
      },
     {
         'name': "child-2",
         'cap': 3,
         'children': []
     }
     ]

and I would like to check if all children have correct structure ('name': "child-112" should raise error)

Is it possible to make recursive schema?

I know that I can add my own type e.g:

group_schema = {
    'name': {'type': 'string', 'required': True},
    'cap': {'type': 'integer', 'required': True},
    'children': {
        'type': 'list',
        'required': True,
        'schema': {
            \*\*'type': 'group'\*\*
        }
    }
}

but I don't know how to validate it. Hope You guys are more experienced. Thanks for help

1

There are 1 best solutions below

0
On

Yes, it is possible to do it recursively using Cerberus library.

First, you need to add a new schema to the registry registry that will reference itself. And then create schema that will use that schema.

Code

from cerberus import Validator, schema_registry

schema_registry.add(
    "group_schema",
    {
        "name": {"type": "string", "required": True},
        "cap": {"type": "integer", "required": True},
        "children": {
            "type": "list",
            "required": True,
            "schema": {
                "type": "dict",
                "schema": "group_schema"
            }
        }
    }
)

schema = {"list_of_values": {"type": "list", "schema": {"type": "dict", "schema": "group_schema"}}}

v = Validator(schema)

resp = [...]
# since resp is a list put it as a value in dictionary
print(v.validate({"list_of_values": resp}))
print(v.errors)

Output

False
{'list_of_values': [{0: [{'children': [{0: [{'children': [{1: [{'cap': ['must be of integer type']}]}]}]}]}]}]}