Reputation: 665
I'm using the jsonschema
Python library like this:
import jsonschema
schema = {
"type": "object",
"oneOf": [
{
"type": "object",
"additionalProperties": False,
"required": ["key"],
"properties": {"key": {"enum": ["foo"], "type": "string"}},
},
{
"type": "object",
"additionalProperties": False,
"required": ["key", "baritem"],
"properties": {
"key": {"enum": ["bar"], "type": "string"},
"baritem": {"type": "string"},
},
},
],
}
I can validate correct data:
jsonschema.validate({"key": "bar", "baritem": "ok"}, schema)
But if a property is missing, if fails (as expected), but with a strange error message:
jsonschema.validate({"key": "bar"}, schema)
Traceback (most recent call last):
File "valid.py", line 29, in <module>
jsonschema.validate({"key": "bar"}, schema)
File "/home/david/.pyenv/versions/3.7.11/lib/python3.7/site-packages/jsonschema/validators.py", line 934, in validate
raise error
jsonschema.exceptions.ValidationError: 'bar' is not one of ['foo']
Failed validating 'enum' in schema[0]['properties']['key']:
{'enum': ['foo'], 'type': 'string'}
On instance['key']:
'bar'
My first question is: Is it the right way to defined the JSON
schema, especially the part defined the key
with an enum
?
My second question is: Is there a way to define properly Abstract Data Type like this with jsonschema
, ie to tell jsonschema
to choose the object
listed in oneOf
based on the key
property, and to validate the rest of the properties based on this object?
Upvotes: 0
Views: 61
Reputation: 53966
You can choose which subschema to apply based on the values of other properties with if
/then
/else
, as well as dependentSchemas
: https://json-schema.org/understanding-json-schema/reference/conditionals.html
Upvotes: 1
Reputation: 665
For now, my solution will be to choose the specific schema to use by myself:
import jsonschema
from jsonschema.exceptions import ValidationError
schema_foo = {
"type": "object",
"additionalProperties": False,
"required": ["key"],
"properties": {"key": {"enum": ["foo"], "type": "string"}},
}
schema_bar = {
"type": "object",
"additionalProperties": False,
"required": ["key", "baritem"],
"properties": {
"key": {"enum": ["bar"], "type": "string"},
"baritem": {"type": "string"},
},
}
schema = {
"type": "object",
"oneOf": [
schema_foo,
schema_bar,
],
}
schema_by_key = {"foo": schema_foo, "bar": schema_bar}
data = {"key": "bar"}
try:
key = data["key"]
except KeyError:
raise ValidationError("key is missing")
try:
specific_schema = schema_by_key[key]
except KeyError:
raise ValidationError("key is invalid")
jsonschema.validate(data, specific_schema)
So error is correctly reported:
Traceback (most recent call last):
File "valid.py", line 43, in <module>
jsonschema.validate(data, specific_schema)
File "/home/david/.pyenv/versions/3.7.11/lib/python3.7/site-packages/jsonschema/validators.py", line 934, in validate
raise error
jsonschema.exceptions.ValidationError: 'baritem' is a required property
Failed validating 'required' in schema:
{'additionalProperties': False,
'properties': {'baritem': {'type': 'string'},
'key': {'enum': ['bar'], 'type': 'string'}},
'required': ['key', 'baritem'],
'type': 'object'}
On instance:
{'key': 'bar'}
Upvotes: 0