Get the property for each jsonschema errror

2019-08-06 10:12发布

问题:

I am trying to determine which property caused the error. It seems for each type of error the way to get the property is different.

from jsonschema import Draft4Validator

request_json = {
  'num_pages': 'invalid',
  'duration': 'invalid',
  'dne': 'invalid'
}

schema = {
  "patch": {
    "type": "object",
    "properties": {
      "name": {"type": "string"},
      "location": {},
      "description": {},
      "objectives": {},
      "num_pages": {"type": "integer"},
      "duration": {"type": "integer"}
    },
    "required": ["name"],
    "additionalProperties": False
  }
}

v = Draft4Validator(schema['patch'])
errors = []

for error in v.iter_errors(request_json):
    print error.__dict__

From this example I would like to construct output with the field and error.

{
  num_pages: 'invalid is not an integer',
  duration: 'invalid is not an integer',
  'dne': 'unexpected additional property',
  'name': 'property is required'
}

Currently I have the following

    if error.relative_schema_path[0] == 'required':
        errors.append({error.message.split(' ')[0]: 'Required property'})
    elif error.relative_path:
        # field: error_message
        errors.append({error.relative_path[0]: error.message})
    # Additional Field was found
    else:
        errors.append({error.instance.keys()[0]: error.message})

If there are multiple errors then error.instance.keys()[0] is not guaranteed to be correct.

回答1:

The recommended approach to traverse and process errors is to use an ErrorTree object.

tree = ErrorTree(v.iter_errors(instance))

From here you can get global errors to the instance:

tree.errors

Errors for first item in an array:

if 1 in tree:
    tree[1].errors