I have a set of jsonschema compliant documents. Some documents contain references to other documents (via the $ref
attribute). I do not wish to host these documents such that they are accessible at an HTTP URI. As such, all references are relative. All documents live in a local folder structure.
How can I make python-jsonschema
understand to properly use my local file system to load referenced documents?
For instance, if I have a document with filename defs.json
containing some definitions. And I try to load a different document which references it, like:
{
"allOf": [
{"$ref":"defs.json#/definitions/basic_event"},
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": ["page_load"]
}
},
"required": ["action"]
}
]
}
I get an error RefResolutionError: <urlopen error [Errno 2] No such file or directory: '/defs.json'>
It may be important that I'm on a linux box.
(I'm writing this as a Q&A because I had a hard time figuring this out and observed other folks having trouble too.)
jsonschema is an implementation of the JSON Schema specification for Python. validate(instance={"name" : "Eggs", "price" : 34.99}, schema=schema) >>> validate( ... instance={"name" : "Eggs", "price" : "Invalid"}, schema=schema, ... ) It can also be used from console: $ jsonschema --instance sample.json sample.schema.
The simplest way to check if JSON is valid is to load the JSON into a JObject or JArray and then use the IsValid(JToken, JsonSchema) method with the JSON Schema. To get validation error messages, use the IsValid(JToken, JsonSchema, IList<String> ) or Validate(JToken, JsonSchema, ValidationEventHandler) overloads.
schema is a library for validating Python data structures, such as those obtained from config-files, forms, external services or command-line parsing, converted from JSON/YAML (or something else) to Python data-types.
I had the hardest time figuring out how to do resolve against a set of schemas that $ref
each other (I am new to JSON Schemas). It turns out the key is to create the RefResolver
with a store
that is a dict
which maps from url to schema.
Building on @devin-p's answer:
import json
from jsonschema import RefResolver, Draft7Validator
base = """
{
"$id": "base.schema.json",
"type": "object",
"properties": {
"prop": {
"type": "string"
}
},
"required": ["prop"]
}
"""
extend = """
{
"$id": "extend.schema.json",
"allOf": [
{"$ref": "base.schema.json#"},
{
"properties": {
"extra": {
"type": "boolean"
}
},
"required": ["extra"]
}
]
}
"""
extend_extend = """
{
"$id": "extend_extend.schema.json",
"allOf": [
{"$ref": "extend.schema.json#"},
{
"properties": {
"extra2": {
"type": "boolean"
}
},
"required": ["extra2"]
}
]
}
"""
data = """
{
"prop": "This is the property string",
"extra": true,
"extra2": false
}
"""
schema = json.loads(base)
extendedSchema = json.loads(extend)
extendedExtendSchema = json.loads(extend_extend)
schema_store = {
schema['$id'] : schema,
extendedSchema['$id'] : extendedSchema,
extendedExtendSchema['$id'] : extendedExtendSchema,
}
resolver = RefResolver.from_schema(schema, store=schema_store)
validator = Draft7Validator(extendedExtendSchema, resolver=resolver)
jsonData = json.loads(data)
validator.validate(jsonData)
The above was built with jsonschema==3.2.0
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With