I am writing Python code to validate a dictionnary using a JSON schema and this schema is referenced by $ref some of them are a path of an other schema such like : ( "$ref": "./insurance-schema.json#/components/schemas/Name") and the others are the ref in the same file like ( "$ref": "#/components/schemas/Adresse"). my schema looks like this:
And the documents-schema.json contain a nested dictionnary that is called components where i can find my AdditionalDocument properties and after the validation i want to delete the attributes that doesn't match with schema fom my dictionnary here is my code
"components": {
"schemas": {
"title": "Data",
"description": "Bloc data de l'objet",
"additionalProperties": false,
"properties": {
"Id": {
"type": "string"
},
"Name": {
"type": "string"
},
"DateNac": {
"type": "string"
},
"Adresse": {
"$ref": "#/components/schemas/Adresse"
},
"MedicalDocuments": {
"type": "array",
"items": {
"$ref": "./documents-schema.json#/components/schemas/AdditionnalDocument"
}
},
"CompanyProperties": {
"type": "Object",
"required": [
"EtsName",
"EtsIdx",
],
"additionalProperties": false,
"properties": {
"startDate": {
"type": "string",
"format": "date"
},
"EtsName": {
"type": "string"
},
"EtsIdx": {
"$ref": "#/components/schemas/EtsIdx"
}
}
},
"EtsIdx": {
"required": [
"Reference",
"Date"
],
"type": "object",
"additionalProperties": false,
"properties": {
"Reference": {
"type": "string"
},
"Complement": {
"type": "string"
},
"Date": {
"type": "string",
"format": "date"
}
}
}
}
}
}
}```
import json
elements_to_exclude = ["$..traceability"]
UTF_8 = 'utf8'
def extract_object(input_payload: dict, path_schema: str) -> list:
if is_valid(path_schema, input_payload):
is_exist(path_schema, input_payload)
def is_valid(path_schema: str, input: dict) -> bool:
import validators
from jsonschema import RefResolver, exceptions, validate
import os
import requests
if (validators.url(path_schema)):
response = requests.get(path_schema)
schema_content = response.content.decode(UTF_8)
url = True
else:
schema_dir = os.path.abspath('schemas')
schema_content = json.loads(open(path_schema))
try:
if not url:
resolver = RefResolver('file://' + schema_dir + '/', None)
else:
# resolver = RefResolver("file://%s.json" % os.path.join(path_schema), schema_content)
validate(input,schema_content, resolver)
except exceptions.ValidationError as validation_error:
return False
def is_exist(path_schema: dict, input: dict) -> list:
schema_content = json.loads(open(path_schema))
for k, v in input.items():
if schema_content.get(k) is None:
# nexite pas
elements_to_exclude.append("$..", k)
else:
if schema_content.get(v, {}).get(type) != type(input.get(v)) and schema_content.get(v, {}).get(
type) is not None:
# n'ont pas le meme type
raise Exception("Types doesnt mach")
elif schema_content.get(v, {}).get(type) == 'object':
# nested object with type object
return is_exist(schema_content.get(v, {}).get("properties"), input.get(v))
elif schema_content.get(v, {}).get("$ref") is not None:
# nested object with ref object or array
ref = schema_content.get(v, {}).get("$ref")
if "#" in ref:
# chemin contient "#"
ref_content = ref.split("#")
if len(ref_content) > 1 and len(ref_content[0]) != 0:
# existe dans un autre fichier
path = ref_content[0]
nested_schema_content = json.loads(open(path))
return is_exist(nested_schema_content.get("components", {}).get("schemas"), input.get(v))
elif len(ref_content) > 1 and len(ref_content[0]) == 0:
# ref of the same file
keys = ref_content[1].split("/")
for key in keys:
nested_schema_content = nested_schema_content[key]
return is_exist(nested_schema_content, input.get(v))
else:
# chemin simple ne contient pas "#"
nested_schema_content = json.loads(open(ref))
return is_exist(nested_schema_content.get("components", {}).get("schemas"), input.get(v))
return elements_to_exclude