Reputation: 1
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
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