I am using cerberus
v1.3.2 with python-3.8
stable to validate json data that will be used to send http requests. I am having an issue using the dependencies
rule. My objects have a field request_type
and an optional field payload
that contains more data. Only objects that have a request_type
in ['CREATE', 'AMEND']
have a payload
. When I run the validation, I get an error related to one of the fields in payload
. Here is the code I'm running:
from cerberus import Validator
request = {
"request_type": "CREATE",
"other_field_1": "whatever",
"other_field_2": "whatever",
"payload": {
"id": "123456",
"jobs": [
{
"duration": 1800,
"other_field_1": "whatever",
"other_field_2": "whatever"
}
]
}
}
schema = {
'request_type': {
'type': 'string',
'allowed': ['CREATE', 'CANCEL', 'AMEND'],
'required': True,
'empty': False
},
'other_field_1': {'type': 'string', },
'other_field_2': {'type': 'string', },
'payload': {
'required': False,
'schema': {
'id': {
'type': 'string',
'regex': r'[A-Za-z0-9_-]`',
'minlength': 1, 'maxlength': 32,
'coerce': str
},
'jobs': {
'type': 'list',
'schema': {
'duration': {
'type': 'integer', 'min': 0,
'required': True, 'empty': False,
},
'other_field_1': {'type': 'string', },
'other_field_2': {'type': 'string', },
}
}
},
'dependencies': {'request_type': ['CREATE', 'AMEND']},
}
}
validator = Validator(schema, purge_unknown=True)
if validator.validate(request):
print('The request is valid.')
else:
print(f'The request failed validation: {validator.errors}')
And this is the error I'm getting:
"RuntimeError: There's no handler for 'duration' in the 'validate' domain."
Is there something I'm doing wrong?
For context, I managed to make the validation work by using the exact same rules, but instead of using dependencies
, I have two separate schemas named payload_schema
and no_payload_schema
. In payload_schema
I set the allowed values for request_type
to ['CREATE', 'AMEND']
, and in no_payload_schema
I set the allowed values to ['CANCEL']
. I run the validation on both schemas and if neither of them passes, I raise an error. This sounds a bit hacky and I'd like to understand how I could use the dependencies
rule to do that.
Mind the difference between schema being used for mappings and sequences. The jobs
field's value won't be checked as mapping since you require it to be of list
type. You'll need this pattern:
{"jobs":
{
{"type": "list", "schema":
{
"type": "dict", "schema": {"duration": ...}
}
}
}
}
This ambiguity of the schema
rule will be addressed in the next major release of Cerberus. For the sake of readability one may use schema- and rule set-registries with complex validation schemas.
It is generally advisable to ask with minimum examples for support.