pyeve / cerberus

Lightweight, extensible data validation library for Python
http://python-cerberus.org
ISC License
3.15k stars 238 forks source link

Cerberus validator #225

Closed txomon closed 8 years ago

txomon commented 8 years ago

I have been using cerberus for a while, and I actually miss a feature, would it be possible to have a cerberus validator? like a validator to validate schemas?

I often find myself creating really complex schemas, and spotting one missing level, or a keyword, and having a way to validate my schemas would be really welcome.

I will probably end up doing it myself eventually, but just in case I wanted to post the idea.

funkyfuture commented 8 years ago

schema validation is actually implemented for a while, but has has been pimped since the last release. if you need an impression of the latest development, i can open a pr that includes the results of #217.

if you're currently using the master branch and no SchemaError is raised due to a broken schema, consider it as a bug.

txomon commented 8 years ago

I was thinking on using cerberus validate() to validate the schema, having the same output as the normal cerberus validation. Now the validation is quite cryptic and doesn't give me as many insights as validate(). I was thinking on creating an schema that validates schemas.

On Sat, Apr 16, 2016 at 10:33 AM Frank Sachsenheim notifications@github.com wrote:

schema validation is actually implemented for a while, but has has been pimped since the last release. if you need an impression of the latest development, i can open a pr that includes the results of #217 https://github.com/nicolaiarocci/cerberus/issues/217.

if you're currently using the master branch and no SchemaError is raised due to a broken schema, consider it as a bug.

— You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub https://github.com/nicolaiarocci/cerberus/issues/225#issuecomment-210781344

txomon commented 8 years ago

Just in case, I was referring to the output of:

from cerberus import Validator

sample_schema = {
    'id': {
        'type': 'string',
        'nullable': False,
        'required': False,
    },
    'kind': {
        'type': 'dict',
        'anyof': [
            {
                'schema': {
                    'type': {
                        'type': 'string',
                        'allowed': ['kind1'],
                        'required': True,
                        'nullable': False,
                    },
                    'data11': {
                        'type': 'integer',
                    },
                },
            },
            {
                'schema': {
                    'type': {
                        'type': 'string',
                        'allowed': ['kind2'],
                        'required': True,
                        'nullable': False,
                    },
                    'data21': {
                        'type': 'string',
                    },
                },
            },
            {
                'schema': {
                    'type': {
                        'type': 'string',
                        'allowed': ['kind3'],
                        'required': True,
                        'nullable': False,
                    },
                    'data31': {
                        'type': 'datetime',
                    },
                },
            },
        ],
    },
    'temp': {
        'type': 'list',
        'anyof': [
            {
                'schema': {
                    'type': {
                        'type': 'string',
                        'required': True,
                        'nullable': False,
                        'allowed': ['temp1'],
                    },
                },
            },
            {
                'schema': {
                    'type': {
                        'type': 'string',
                        'required': True,
                        'nullable': False,
                        'allowed': ['temp2'],
                    },
                },
            },
            {
                'schema': {
                    'type': {
                        'type': 'string',
                        'required': True,
                        'nullable': False,
                        'allowed': ['temp3'],
                    },
                },
            },
        ]
    }
}

Validator(schema=sample_schema)

As you can see, the error is not quite readable (I have added my own traces to the validate_schema trying to find the error...):

Validating schema  {'kind': {'type': 'dict', 'anyof': [{'schema': {'data11': {'type': 'integer'}, 'type': {'type': 'string', 'allowed': ['kind1'], 'required': True, 'nullable': False}}}, {'schema': {'type': {'ty
pe': 'string', 'allowed': ['kind2'], 'required': True, 'nullable': False}, 'data21': {'type': 'string'}}}, {'schema': {'type': {'type': 'string', 'allowed': ['kind3'], 'required': True, 'nullable': False}, 'data
31': {'type': 'datetime'}}}]}, 'id': {'type': 'string', 'nullable': False, 'required': False}, 'temp': {'type': 'list', 'anyof': [{'schema': {'type': {'type': 'string', 'allowed': ['temp1'], 'required': True, 'nullable': False}}}, {'schema': {'type': {'type': 'string', 'allowed': ['temp2'], 'required': True, 'nullable': False}}}, {'schema': {'type': {'type': 'string', 'allowed': ['temp3'], 'required': True, 'nullable':
 False}}}]}}
Analyzing field kind with constraints {'type': 'dict', 'anyof': [{'schema': {'data11': {'type': 'integer'}, 'type': {'type': 'string', 'allowed': ['kind1'], 'required': True, 'nullable': False}}}, {'schema': {'type': {'type': 'string', 'allowed': ['kind2'], 'required': True, 'nullable': False}, 'data21': {'type': 'string'}}}, {'schema': {'type': {'type': 'string', 'allowed': ['kind3'], 'required': True, 'nullable': Fal
se}, 'data31': {'type': 'datetime'}}}]}
Inspecting contraint type with value dict
Inspecting contraint anyof with value [{'schema': {'data11': {'type': 'integer'}, 'type': {'type': 'string', 'allowed': ['kind1'], 'required': True, 'nullable': False}}}, {'schema': {'type': {'type': 'string', '
allowed': ['kind2'], 'required': True, 'nullable': False}, 'data21': {'type': 'string'}}}, {'schema': {'type': {'type': 'string', 'allowed': ['kind3'], 'required': True, 'nullable': False}, 'data31': {'type': 'd
atetime'}}}]
*of value {'type': 'dict', 'schema': {'data11': {'type': 'integer'}, 'type': {'type': 'string', 'allowed': ['kind1'], 'required': True, 'nullable': False}}}
Validating schema  {'kind': {'type': 'dict', 'schema': {'data11': {'type': 'integer'}, 'type': {'type': 'string', 'allowed': ['kind1'], 'required': True, 'nullable': False}}}}
Analyzing field kind with constraints {'type': 'dict', 'schema': {'data11': {'type': 'integer'}, 'type': {'type': 'string', 'allowed': ['kind1'], 'required': True, 'nullable': False}}}
Inspecting contraint type with value dict
Inspecting contraint schema with value {'data11': {'type': 'integer'}, 'type': {'type': 'string', 'allowed': ['kind1'], 'required': True, 'nullable': False}}
Validating schema  {'data11': {'type': 'integer'}, 'type': {'type': 'string', 'allowed': ['kind1'], 'required': True, 'nullable': False}}
Analyzing field data11 with constraints {'type': 'integer'}
Inspecting contraint type with value integer
Analyzing field type with constraints {'type': 'string', 'allowed': ['kind1'], 'required': True, 'nullable': False}
Inspecting contraint type with value string
Inspecting contraint allowed with value ['kind1']
Inspecting contraint required with value True
Inspecting contraint nullable with value False
*of value {'type': 'dict', 'schema': {'type': {'type': 'string', 'allowed': ['kind2'], 'required': True, 'nullable': False}, 'data21': {'type': 'string'}}}
Validating schema  {'kind': {'type': 'dict', 'schema': {'type': {'type': 'string', 'allowed': ['kind2'], 'required': True, 'nullable': False}, 'data21': {'type': 'string'}}}}
Analyzing field kind with constraints {'type': 'dict', 'schema': {'type': {'type': 'string', 'allowed': ['kind2'], 'required': True, 'nullable': False}, 'data21': {'type': 'string'}}}
Inspecting contraint type with value dict
Inspecting contraint schema with value {'type': {'type': 'string', 'allowed': ['kind2'], 'required': True, 'nullable': False}, 'data21': {'type': 'string'}}
Validating schema  {'type': {'type': 'string', 'allowed': ['kind2'], 'required': True, 'nullable': False}, 'data21': {'type': 'string'}}
Analyzing field type with constraints {'type': 'string', 'allowed': ['kind2'], 'required': True, 'nullable': False}
Inspecting contraint type with value string
Inspecting contraint allowed with value ['kind2']
Inspecting contraint required with value True
Inspecting contraint nullable with value False
Analyzing field data21 with constraints {'type': 'string'}
Inspecting contraint type with value string
*of value {'type': 'dict', 'schema': {'type': {'type': 'string', 'allowed': ['kind3'], 'required': True, 'nullable': False}, 'data31': {'type': 'datetime'}}}
Validating schema  {'kind': {'type': 'dict', 'schema': {'type': {'type': 'string', 'allowed': ['kind3'], 'required': True, 'nullable': False}, 'data31': {'type': 'datetime'}}}}
Analyzing field kind with constraints {'type': 'dict', 'schema': {'type': {'type': 'string', 'allowed': ['kind3'], 'required': True, 'nullable': False}, 'data31': {'type': 'datetime'}}}
Inspecting contraint type with value dict
Inspecting contraint schema with value {'type': {'type': 'string', 'allowed': ['kind3'], 'required': True, 'nullable': False}, 'data31': {'type': 'datetime'}}
Validating schema  {'type': {'type': 'string', 'allowed': ['kind3'], 'required': True, 'nullable': False}, 'data31': {'type': 'datetime'}}
Analyzing field type with constraints {'type': 'string', 'allowed': ['kind3'], 'required': True, 'nullable': False}
Inspecting contraint type with value string
Inspecting contraint allowed with value ['kind3']
Inspecting contraint required with value True
Inspecting contraint nullable with value False
Analyzing field data31 with constraints {'type': 'datetime'}
Inspecting contraint type with value datetime
Analyzing field id with constraints {'type': 'string', 'nullable': False, 'required': False}
Inspecting contraint type with value string
Inspecting contraint nullable with value False
Inspecting contraint required with value False
Analyzing field temp with constraints {'type': 'list', 'anyof': [{'schema': {'type': {'type': 'string', 'allowed': ['temp1'], 'required': True, 'nullable': False}}}, {'schema': {'type': {'type': 'string', 'allow
ed': ['temp2'], 'required': True, 'nullable': False}}}, {'schema': {'type': {'type': 'string', 'allowed': ['temp3'], 'required': True, 'nullable': False}}}]}
Inspecting contraint type with value list
Inspecting contraint anyof with value [{'schema': {'type': {'type': 'string', 'allowed': ['temp1'], 'required': True, 'nullable': False}}}, {'schema': {'type': {'type': 'string', 'allowed': ['temp2'], 'required'
: True, 'nullable': False}}}, {'schema': {'type': {'type': 'string', 'allowed': ['temp3'], 'required': True, 'nullable': False}}}]
*of value {'type': 'list', 'schema': {'type': {'type': 'string', 'allowed': ['temp1'], 'required': True, 'nullable': False}}}
Validating schema  {'temp': {'type': 'list', 'schema': {'type': {'type': 'string', 'allowed': ['temp1'], 'required': True, 'nullable': False}}}}
Analyzing field temp with constraints {'type': 'list', 'schema': {'type': {'type': 'string', 'allowed': ['temp1'], 'required': True, 'nullable': False}}}
Inspecting contraint type with value list
Inspecting contraint schema with value {'type': {'type': 'string', 'allowed': ['temp1'], 'required': True, 'nullable': False}}
Validating schema  {'schema': {'type': {'type': 'string', 'allowed': ['temp1'], 'required': True, 'nullable': False}}}
Analyzing field schema with constraints {'type': {'type': 'string', 'allowed': ['temp1'], 'required': True, 'nullable': False}}
Inspecting contraint type with value {'type': 'string', 'allowed': ['temp1'], 'required': True, 'nullable': False}
Traceback (most recent call last):
  File "test.py", line 90, in <module>
    Validator(schema=sample_schema)
  File "/home/javier/ve3/lib/python3.5/site-packages/cerberus/cerberus.py", line 175, in __init__
    self.validate_schema(self.schema)
  File "/home/javier/ve3/lib/python3.5/site-packages/cerberus/cerberus.py", line 444, in validate_schema
    self.validate_schema({field: s})
  File "/home/javier/ve3/lib/python3.5/site-packages/cerberus/cerberus.py", line 423, in validate_schema
    self.validate_schema({'schema': value})
  File "/home/javier/ve3/lib/python3.5/site-packages/cerberus/cerberus.py", line 406, in validate_schema
    if not hasattr(self, '_validate_type_' + value):
TypeError: Can't convert 'dict' object to str implicitly
funkyfuture commented 8 years ago

are you using the master-branch? if so, what's the output of

from cerberus.schema import DefinitionSchema
DefinitionSchema(sample_schema)

?

txomon commented 8 years ago

I was using the pip package. I cloned master, and had the last lines changed to:

validator = Validator(schema=sample_schema)
print(DefinitionSchema(validator, schema=sample_schema))

Seems to be working...

{'kind': {'anyof': [{'schema': {'data11': {'type': 'integer'}, 'type': {'required': True, 'nullable': False, 'type': 'string', 'allowed': ['kind1']}}}, {'schema': {'type': {'required': True, 'nullable': False, 'type': 'string', 'allowed': ['kind2']}, 'data21': {'type': 'string'}}}, {'schema': {'data31': {'type': 'datetime'}, 'type': {'required': True, 'nullable': False, 'type': 'string', 'allowed': ['kind3']}}}], 'type': 'dict'}, 'id': {'required': False, 'type': 'string', 'nullable': False}, 'temp': {'anyof': [{'schema': {'type': {'allowed': ['temp1'], 'nullable': False, 'type': 'string', 'required': True}}}, {'schema': {'type': {'allowed': ['temp2'], 'nullable': False, 'type': 'string', 'required': True}}}, {'schema': {'type': {'allowed': ['temp3'], 'nullable': False, 'type': 'string', 'required': True}}}], 'type': 'list'}}

When is the bugfix going to be released?

nicolaiarocci commented 8 years ago

Hopefully Soon™