Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: jsonschema package to validate schema and custom error messages

Given this schema:

{
    "type": "object",
    "properties": {
        "account": {
            "type": "object",
            "required": ["id"],
            "properties": {
                "id": {"type": "number"}
            }
        },
        "name": {"type": "string"},
        "trigger": {
            "type": "object",
            "required": ["type"],
            "properties": {
                "type": {"type": "string"}
            }
        },
        "content": {
            "type": "object",
            "properties": {
                "emails": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                        "type": "object",
                        "required": ["fromEmail","subject"],
                        "properties": {
                            "fromEmail": {"type": "string", "format": "email"},
                            "subject": {"type": "string"}
                        }
                    }
                }
            }
        }
    }
}

I am trying to use jsonschema.Draft4Validator to validate a POSTed JSON object to check for validity, but I am having some issues trying to come up with better human readable messages from the returned errors.

Here is how I am validating:

from jsonschema import Draft4Validator

v = Draft4Validator(self.schema)
errors = sorted(v.iter_errors(autoresponder_workflow), key=lambda e: e.path)

if errors:
    print(', '.join(
        '%s %s %s' % (error.path.popleft(), error.path.pop(), error.message) for error in errors
    ))

The error message looks like:

content emails [] is too short, trigger type None is not of type u'string'

Im trying to create an error message that looks a little more like Please add at least one email to your workflow," "Please ensure that all of your emails contain subject lines,", etc

like image 286
dennismonsewicz Avatar asked Sep 18 '14 01:09

dennismonsewicz


2 Answers

I had the need of displaying a more detailed custom message to the user when an error occurred. I did this by adding a field to the property in the schema and then looking it up on ValidationError.

import json
import jsonschema


def validate(_data, _schema):
    try:
        jsonschema.validate(_data, _schema)
    except jsonschema.ValidationError as e:
        return e.schema["error_msg"] 


schema = {
    "title": "index",
    "type": "object",
    "required": [
        "author",
        "description"
    ],
    "properties": {
        "author": {
            "type": "string",
            "description": "Name of the Author",
            "minLength": 3,
            "default": "",
            "error_msg": "Please provide a Author name"
        },
        "description": {
            "type": "string",
            "description": "Short description",
            "minLength": 10,
            "default": "",
            "error_msg": "Please add a short description"
        }
    }
}

data = {
    "author": "Jerakin",
    "description": ""
}
like image 114
Jerakin Avatar answered Oct 04 '22 07:10

Jerakin


You could catch ValidationError exception and build a custom messages for the specific cases you want from ValidationError metadata. In this object you have:

info of the failed validator: its value and schema path info of the failed instance: its path and value at the time of the failed validation possible errors in subschemas cause (errors caused by a non-validation error)

like image 25
jruizaranguren Avatar answered Oct 04 '22 07:10

jruizaranguren