Python jsonschema fails to validate enum of strings - python

So, I'm trying to define a schema for a set of axis constraints. Therefore, I would like to restrict the possible values of the "axis" element to ["x", "y", "z"].
Here is my current sample, and it's output.
JSON:
{
"name_patterns": [
{
"regex": "block[_-]?([\\d]*)",
"class": "block",
"id_group": 1
}
],
"relationships": [
{
"src_class": "block",
"dst_class": "block",
"constraints": {
"axis": "x"
}
}
]
}
Schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name_patterns": {"type": "array",
"items": { "$ref": "#/definitions/name_entry" } },
"relationships": {"type": "array",
"items": { "anyof": [ {"$ref": "#/definitions/relation"} ] } }
},
"definitions": {
"name_entry": {
"type": "object",
"properties": {
"regex": {"type": "string"},
"class": {"type": "string"},
"id_group": {"type": "number"}
},
"required": ["regex", "class"]
},
"relation": {
"type": "object",
"properties": {
"src_class": {"type": "string"},
"dst_class": {"type": "string"},
"constraints": {
"type": "object",
"properties": {
"axis": {
"enum": ["x", "y", "z"]
}
},
"required": ["axis"]
}
},
"required": ["src_class", "dst_class", "constraints"]
}
}
}
How can I fix my schema to reject values which are not specified in the enumerator?

Your schema syntax is a bit off.
Firstly, you need to put property definitions inside properties:
{
"properties": {
"axis": {...}
}
}
Secondly, type defines the type (e.g. "string"), but you don't need it here. enum should just be directly inside the "axis" schema:
{
"properties": {
"axis": {
"enum": ["x", "y", "z"]
}
}
}

Related

How to model OneOf in Flask Restx?

I have the following schema doc
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "foo",
"definitions": {
"stuff": {
"type": "object",
"properties": {
"id": {
"description": "the id",
"type": "string"
},
"type": {
"description": "the type",
"type": "string"
}
},
"oneOf": [{
"required": ["id"]
}, {
"required": ["type"]
}],
},
},
"type": "object",
"properties": {
"bar": {
"description": "blah",
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/stuff"
}
}
},
"required": ["bar"]
}
and I'm trying to create the flask restx model, but I'm not sure how to model the required OneOf fields?
I think the following will work, but then it ignores the oneof requirement.
stuff_model = (
"Stuff Model",
"id": fields.String(description="the id", required=False),
"type": fields.String(description="the type", required=False)
)
bar_model = (
"Bar Model",
"bar": fields.Nested(stuff_model, required=True)
)

Why is JSON-validation always successful using this schema containing 'allOf'?

I have a JSON schema with which I want to validate some data, using python and the jsonschema module. However, this doesn't quite work as expected, as some of the accepted data doesn't appear valid at all (to me and the purpose of my application). Sadly, the schema is provided, so I can't change the schema itself - at least not manually.
This is a shortened version of the schema ('schema.json' in code below):
{
"type": "object",
"allOf": [
{
"type": "object",
"allOf": [
{
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
}
}
},
{
"type": "object",
"properties": {
"language": {
"type": "integer"
}
}
}
]
},
{
"type": "object",
"properties": {
"addressArray": {
"type": "array",
"items": {
"type": "object",
"properties": {
"streetNumber": {
"type": "string"
},
"street": {
"type": "string"
},
"city": {
"type": "string"
}
}
}
}
}
}
]
}
This is an example of what should be a valid instance ('person.json' in code below):
{
"firstName": "Sherlock",
"lastName": "Holmes",
"language": 1,
"addresses": [
{
"streetNumber": "221B",
"street": "Baker Street",
"city": "London"
}
]
}
This is an example of what should be considered invalid ('no_person.json' in code below):
{
"name": "eggs",
"colour": "white"
}
And this is the code I used for validating:
from json import load
from jsonschema import Draft7Validator, exceptions
with open('schema.json') as f:
schema = load(f)
with open('person.json') as f:
person = load(f)
with open('no_person.json') as f:
no_person = load(f)
validator = Draft7Validator(schema)
try:
validator.validate(person)
print("person.json is valid")
except exceptions.ValidationError:
print("person.json is invalid")
try:
validator.validate(no_person)
print("no_person.json is valid")
except exceptions.ValidationError:
print("no_person.json is invalid")
Result:
person.json is valid
no_person.json is valid
I expected no_person.json to be invalid. What can there be done to have only data such as person.json to be validated successfully? Thank you very much for your help, I'm very new to this (spent ages searching for an answer).
This is work schema and pay attention on "required" (when there is no such key - if field is doesn't get it just skipped):
{
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"language": {
"type": "integer"
},
"addresses": {
"type": "array",
"items": {
"type": "object",
"properties": {
"streetNumber": {
"type": "string"
},
"street": {
"type": "string"
},
"city": {
"type": "string"
}
},
"required": [
"streetNumber",
"street",
"city"
]
}
}
},
"required": [
"firstName",
"lastName",
"language",
"addresses"
]
}
I've got:
person.json is valid
no_person.json is invalid
If you have hardest structure of response (array of objects, which contain objects etc) let me known

How to validate a specific jsonschema based on document type

I have a JSON schema for user's new message:
message_creation = {
"title": "Message",
"type": "object",
"properties": {
"post": {
"oneOf": [
{
"type": "object",
"properties": {
"content": {
"type": "string"
}
},
"additionalProperties": False,
"required": ["content"]
},
{
"type": "object",
"properties": {
"image": {
"type": "string"
}
},
"additionalProperties": False,
"required": ["image"]
},
{
"type": "object",
"properties": {
"video_path": {
"type": "string"
}
},
"additionalProperties": False,
"required": ["video"]
}
]
},
"doc_type": {
"type": "string",
"enum": ["text", "image", "video"]
}
},
"required": ["post", "doc_type"],
"additionalProperties": False
}
It's simple as that! There is two fields one is type and the other is post. So a payload like below succeeds:
{
"post": {
"image": "Hey there!"
},
"type": "image"
}
Now problem is that if user sets type value to text I cannot validate if text's schema has been given. How should I verify this? How should I check in case type is set to image then make sure that image exists inside of post?
You can do it, but it's complicated. This uses a boolean logic concept called implication to ensure that if schema A matches then schema B must also match.
{
"type": "object",
"properties": {
"post": {
"type": "object",
"properties": {
"content": { "type": "string" },
"image": { "type": "string" },
"video_path": { "type": "string" }
},
"additionalProperties": false
},
"doc_type": {
"type": "string",
"enum": ["text", "image", "video"]
}
},
"required": ["post", "doc_type"],
"additionalProperties": false,
"allOf": [
{ "$ref": "#/definitions/image-requires-post-image" },
{ "$ref": "#/definitions/text-requires-post-content" },
{ "$ref": "#/definitions/video-requires-post-video-path" }
],
"definitions": {
"image-requires-post-image": {
"anyOf": [
{ "not": { "$ref": "#/definitions/type-image" } },
{ "$ref": "#/definitions/post-image-required" }
]
},
"type-image": {
"properties": {
"doc_type": { "const": "image" }
}
},
"post-image-required": {
"properties": {
"post": { "required": ["image"] }
}
},
"text-requires-post-content": {
"anyOf": [
{ "not": { "$ref": "#/definitions/type-text" } },
{ "$ref": "#/definitions/post-content-required" }
]
},
"type-text": {
"properties": {
"doc_type": { "const": "text" }
}
},
"post-content-required": {
"properties": {
"post": { "required": ["content"] }
}
},
"video-requires-post-video-path": {
"anyOf": [
{ "not": { "$ref": "#/definitions/type-video" } },
{ "$ref": "#/definitions/post-video-path-required" }
]
},
"type-video": {
"properties": {
"doc_type": { "const": "video" }
}
},
"post-video-path-required": {
"properties": {
"post": { "required": ["video_path"] }
}
}
}
}

Edit Json schema with python

I have the main Json-schema. It looks like that:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"listInfo": {
"type": "object",
"properties": {
"limit": {
"type": "integer"
},
"count": {
"type": "integer"
}
},
"required": [
"offset",
"count"
]
},
"items": {
"type": ["array", "null"],
"items": {
"type": "object",
"properties": {
"startDate": {
"type": "string"
},
"customer": {
"type": "object",
"properties": {
"customerId": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"required": [
"customerId",
"name"
]
}
},
"required": [
"startDate",
"customer"
]
}
}
},
"required": [
"listInfo",
"items"
]
}
Every time after sending a get query to a host I check Json on a validation with my schema.
But Sometimes I need not all fields in it. For example I can add "&fields=startDate" in the end of my GET query.
How I can generate new Json schema for my new data (I need to automatically delete lines about "customer" in my old Json schema and generate a new json-schema file)?

Failed validating 'type' json schema

I've writen a small chunk os json schema but I'm getting a validation error using python jsonschema.
Here is my schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"output": {
"type": "object",
"properties": {
"Type": {
"type": "object",
"properties": {
"Type": {
"type": "string"
},
"Value": {
"type": "string"
},
"Default": {
"type": "string"
},
"Description": {
"type": "string"
},
"Options": {
"type": "array"
}
},
"required": [
"Type",
"Value",
"Default",
"Description",
"Options"
]
},
"Inverted": {
"type": "object",
"properties": {
"Type": {
"type": "string"
},
"Value": {
"type": "bool"
},
"Default": {
"type": "bool"
},
"Description": {
"type": "string"
}
},
"required": [
"Type",
"Value",
"Default",
"Description"
]
},
"Pulse Width": {
"type": "object",
"properties": {
"Type": {
"type": "string"
},
"Value": {
"type": "number"
},
"Default": {
"type": "number"
},
"Description": {
"type": "string"
}
},
"required": [
"Type",
"Value",
"Default",
"Description"
]
}
},
"required": [
"Type",
"Inverted",
"Pulse Width"
]
}
}
}
Here is the error I'm receiving:
Failed validating u'type' in schema
I'm attempting to validate my schema with:
schema = ""
with open(jsonSchemaFilePath, 'r') as schema_file:
schema = schema_file.read()
try:
Draft4Validator.check_schema(schema)
except SchemaError as schemaError:
print schemaError
What am I doing wrong with the schema I've written? Am I not allowed to have a property named Type?
My problem was Draft4Validator.check_schema takes a dic not a string, nor a json object.
Here was my solution:
schema = {}
with open(jsonSchemaFilePath, 'r') as schema_file:
schema = json.loads(schema_file.read())
try:
Draft4Validator.check_schema(schema)
except SchemaError as schemaError:
print schemaError

Categories

Resources