hashinate
hashinate

Reputation: 1

Is it possible to validate key names and dictionary names of a yaml file with Cerberus?

I have a need to validate a YAML file, using Python3.7. I am trying Cerberus to perform a content validation. As for the value validation, that is working just fine, but for key names I cannot find a way to successfully verify their validity in the context of the YAML file.

The dictionary name is an e-mail address and should be unique for each entry in the YAML file and should be validated. A couple of the key names are case sensitive and need to be validated as accurate.

I am also a newb at Python so there is a high chance this is just newb ignorance. It is possible that I need to look elsewhere than Cerberus, but I haven't found a robust YAML validator otherwise. Suggestions very welcome.

I created a schema.py and a validationScript.py following the Cerberus documentation. I have tried to put keysrules, but can't seem to have an 'anyof' validation at that level. It seems the keysrules apply to all keys in the dictionary in my testing. If I use a keysrules I can validate one key, but others fail. I have tried an array of rules, I have tried the anyof and anyof_regex but have not been able to get them to successfully look at all key names and validate.

I cannot find a way to validate the dictionary name. I know I can validate it if I hardcode a valid e-mail that exists in the YAML.

#! python
from cerberus import Validator
import yaml

def __val_users():
    with open("yamlfile.yaml", 'r') as stream:
        try:
            return yaml.safe_load(stream)
        except yaml.YAMLError as exception:
            print(exception)

schema = eval(open('C:/path/to/schema.py', 'r').read())
v = Validator(schema)
document = __val_users()
print(v.validate(document, schema))
print(v.errors)

And the schema.py looks like this:

{
    '[email protected]': {
        'type': 'dict',
    },
        'varOn': {
            'required': True,
            'type': 'string',
                        'regex': '/^\S*$/;'
                },
        'varOff': {
            'required': True,
            'type': 'string',
                        'regex': '/^\S*$/;'
        },
        'access': {
            'required': True,
            'type': 'list',
                        'allowed': ['h1', 'h2', 'h3', 'oper1', 'oper2', 'oper3', 'drive1', 'drive2', 'drive3']
        },
        'hub': {
            'required': True,
            'type': 'list'
        }
}

The yaml is

[email protected]:
  varOn: Single
  varOff: Word
  access:
    - h1
    - drive2
    - oper3
  hub:
    - onehub

I expect there is code that can validate rules, but I end up with syntax errors when using anyof: File "", line 5 'anyof': ^ SyntaxError: invalid syntax

I end up with schema errors when using keysrules

File "C:\Python37\lib\site-packages\cerberus\schema.py", line 275, in _validate
    raise SchemaError(self.schema_validator.errors)
cerberus.schema.SchemaError: `{'[email protected]': [{'keysrules': ["must be of ['dict', 'string'] type"]}]}`

With all content validation working, I end up with the dictionary names (the email addresses) comes back with False stating {'[email protected]': ['unknown field'], '[email protected]': ['unknown field']}

Upvotes: 0

Views: 2128

Answers (1)

Sk.
Sk.

Reputation: 460

you cant include a value inside of schema part, lets try to avoid the email address, 'key' in the root of yaml... an look at into the inside parts and validate him.

import yaml
from cerberus import Validator
from schema_a import schema



def __val_users():
    with open("/home/sirsk/Active/document.yml", 'r') as stream:
    #with open("yamlfile.yaml", 'r') as stream:
        try:
            return yaml.safe_load(stream)
        except yaml.YAMLError as exception:
            print(exception)




v = Validator()

document = __val_users()

#you dont know about the email value in this case is the root, key of a dictionary
document = document[next(iter(document))]

if not v.validate(document, schema):
    print(v.errors)

schema_a.py in the same folder

schema = {
    'varOn': {
        'required': True,
        'type': 'string',
                    'regex': '/^\S*$/;'
            },
    'varOff': {
        'required': True,
        'type': 'string',
                    'regex': '/^\S*$/;'
    },
    'access': {
        'required': True,
        'type': 'list',
                    'allowed': ['h1', 'h2', 'h3', 'oper1', 'oper2', 'oper3', 'drive1', 'drive2', 'drive3']
    },
    'hub': {
        'required': True,
        'type': 'list'
    }
}

Upvotes: 0

Related Questions