Search code examples
pythonvalidationcerberus

How to validate nested dictionary object in Cerberus


Here is a sample data that needs to be validated. The keys in the employee_eligibility nested dictionary are number string "[0-9]+".

{
  "client_id": 1,
  "subdomain": "Acme",
  "shifts": [
    20047, 20048, 20049
  ],
  "employee_eligibility": {
    "1": {
      "20047": 1,
      "20048": 0,
      "20049": 1
    },
    "2": {
      "20047": 1,
      "20048": 0,
      "20049": 1
    },
    "3": {
      "20047": 1,
      "20048": 1,
      "20049": 0
    }
  }
}

I have written the following schema for validation:

    {
        "client_id": {"type": "integer"},
        "subdomain": {"type": "string"},
        "shifts": {"type": "list", "schema": {"type": "integer"}},
        "employee_eligibility": {
            "type": "dict",
            "keysrules": {"type": "string", "regex": "[0-9]+"},
            "schema": {
                "type": "dict",
                "keysrules": {"type": "string", "regex": "[0-9]+"},
                "schema": {"type": "integer"}
            }
        },
    }

When I run the validation I get the following error:

{'employee_eligibility': ['must be of dict type']}

Solution

  • Your schema is slightly off, you'll need to use valuesrules to validate the values of your dictionaries.

    schema = {
        "client_id": {"type": "integer"},
        "subdomain": {"type": "string"},
        "shifts": {"type": "list", "schema": {"type": "integer"}},
    
        # `employee_eligibility` is a dictionary
        "employee_eligibility": {
            "type": "dict",
    
            # the keys in `employee_eligibility` are strings matching this regex
            "keysrules": {"type": "string", "regex": "^[0-9]+"},
    
            # the values in `employee_eligibility` are also dictionaries with keys
            # that are strings that match this regex and integer values
            "valuesrules": {
                "type": "dict",
                "keysrules": {"type": "string", "regex": "^[0-9]+"},
                "valuesrules": {"type": "integer"},
            },
        },
    }
    

    edit: added some comments to annotate the example