Json Schema Pyhton
Json Schema Pyhton
Julian Berman
https://github.com/Julian | @JulianWasTaken | tos9 on Freenode
[email protected]
{
"name": "PyCon Sette",
"location": [
43.7661479,
11.2699767
]
}
jsonschema
https://github.com/Julian/jsonschema
42 {“type”: “integer”}
instance schema
>>> from jsonschema import validate
>>> validate(instance=42, schema={"type": "integer"})
“Fourty Two” {“type”: “integer”}
>>> validate(instance="Fourty Two", schema={"type": "integer"})
Traceback (most recent call last):
...
On instance:
'Fourty Two'
What Can We Validate?
● Types
● Ranges, Sizes & Lengths
● Container Contents
● Form
● Higher-Order Operators
{
"name": "PyCon Sette",
"location": [
43.7661479,
11.2699767
]
}
{
"type": "object",
"properties": {
"name": {"type": "string"},
"location": {
"type": "array",
"description": "Latitude & Longitude",
"items": [
{"type": "integer", "minimum": -90, "maximum": 90},
{"type": "integer", "minimum": -180, "maximum": 180}
]
}
}
}
*jsonschema, kind of a lie.
*pythonschema, less of a lie.
When Things Go Very Wrong
{
"items": {
"type": "boolean"
[1] },
"minItems": 2
}
>>> from jsonschema.validators import Draft4Validator
>>> validator = Draft4Validator(
... schema={"items": {"type": "boolean"}, "minItems": 2},
... )
>>> validator.validate([True, False])
>>> validator.validate([True, True, True])
>>> validator.validate(instance=[1])
Traceback (most recent call last):
...
ValidationError: 1 is not of type 'boolean'
On instance[0]:
1
>>> [error.message for error in validator.iter_errors(instance=[1])]
["1 is not of type 'boolean'", '[1] is too short']
What happened? Why did it happen? What was being validated?
● instance
● path
● context ● schema
● message
● cause ● schema_path
● validator
● validator_value
>>> jsonschema.ErrorTree(errors=validator.iter_errors(instance=[1]))
<ErrorTree (2 total errors)>
>>> tree = _
>>> tree[0].errors
{'type': <ValidationError: "1 is not of type 'boolean'">}
References
{
"properties": {
"name": {"type": "string", "minLength": 1},
"nickname": {"type": "string", "minLength": 1},
"username": {"type": "string", "minLength": 1}
}
}
{
"properties": {
"name": {"$ref": "#/definitions/nameLike"},
"nicknname": {"$ref": "#/definitions/nameLike"},
"username": {"$ref": "#/definitions/nameLike"}
},
"definitions": {
"nameLike": {"type": "string", "minLength": 1}
}
}
{
"properties": {
"name": {"$ref": "#/definitions/nameLike"},
"nicknname": {"$ref": "#/definitions/nameLike"},
"username": {"$ref": "#/definitions/nameLike"}
},
"definitions": {
"nameLike": {
"type": "string", "minLength": 1, "maxLength": 4096
}
}
}
"Non-empty Sequence"
{
"type": ["string", "array"],
"minItems": 1,
"minLength": 1
}
"A moniker, a name or an alias"
"S"
{"name": "Clark Kent"}
{"alias": "Superman"}
{
"oneOf": [
{"$ref": "#/definitions/moniker"},
{"$ref": "#/definitions/name"},
{"$ref": "#/definitions/alias"},
],
...
"definitions": {
"moniker": {"type": "string", "pattern": "[A-Z]+"},
"name": {
"type": "object",
"required": ["name"],
"properties": {"name": {"type": "string"}}
},
"alias": {
"type": "object",
"required": ["alias"],
"properties": {"alias": {"type": "string"}}
}
}
}
Traceback (most recent call last):
...
On instance:
''
>>> list(validator.iter_errors(""))
[<ValidationError: "'' is not valid under any of the given schemas">]
>>> next(validator.iter_errors("")).context
[<ValidationError: "'' does not match '[A-Z]+'">,
<ValidationError: "'' is not of type 'object'">,
<ValidationError: "'' is not of type 'object'">]
>>> import jsonschema.exceptions
>>> print jsonschema.exceptions.best_match(errors=validator.iter_errors(""))
'' does not match '[A-Z]+'
On instance:
''
Format
{"type": "string", "format": "date"}
>>> from jsonschema import FormatChecker
>>> validator = Draft4Validator(
... schema=schema, format_checker=FormatChecker(),
... )
>>> validator.validate("2014-01")
Traceback (most recent call last):
...
ValidationError: '2014-01' is not a 'date'
On instance:
'2014-01'
>>> checker = jsonschema.FormatChecker()
>>> @checker.checks(format="prime")
... def is_prime(value):
... return miller_rabin(value, iterations=10)
Meta-schemas
Draft4Validator.check_schema(
{"type": {"whoops": "an object"}},
)
Traceback (most recent call last):
...
SchemaError: {'whoops': 'an object'} is not valid under any of the given schemas
On instance[u'type']:
{'whoops': 'an object'}
>>> validator = Draft4Validator(schema=Draft4Validator.META_SCHEMA)
>>> for error in validator.iter_errors(
... instance={"type": {"whoops": "an object"}, "minimum": "wage"}
... ):
... print repr(error)