gray/schemas/validate.py

55 lines
2.1 KiB
Python

import argparse
import sys
import json
import jsonschema
import jsonschema.protocols
import jsonschema.validators
from jsonschema import Draft202012Validator
from jsonschema.exceptions import SchemaError, ValidationError
from referencing import Registry, Resource
from referencing.jsonschema import DRAFT202012
parser = argparse.ArgumentParser(
description="Validate a JSON document against a JSON schema"
)
parser.add_argument("-f", "--file",
help="file containing the JSON document to validate. " +
"If absent, the JSON document is read from the standard input")
parser.add_argument("-s", "--schema", required=True,
help="file containing the schema definition"
)
parser.add_argument("-r", "--resource", nargs="+", default=[],
help="additional schemas to be added to the registry for reference resolution")
if __name__ == "__main__":
args = parser.parse_args()
# Load the schema and any additional resources and add them to the registry for reference resolution
# The schema is last in the list: it will remain stored in schema_dict at the end of the for loop
registry = Registry()
for schema_file in (*args.resource, args.schema):
with open(file=schema_file, mode="r") as f:
schema = json.load(f)
resource = Resource.from_contents(
contents=schema,
default_specification=DRAFT202012
)
registry = resource @ registry
# Load the JSON document to validate
with open(file=args.file, mode="r") if args.file else sys.stdin as f:
document = json.load(f)
# Set the validator with the desired schema and check the schema itself before validating the document
validator = jsonschema.validators.validator_for(schema)(schema, registry=registry)
try:
validator.check_schema(schema)
except SchemaError as e:
print("Schema check failed.")
print(f"{e.message}")
exit(1)
try:
validator.validate(document)
print("Valid!")
except ValidationError as e:
print("Validation failed.")
print(f"{e.message}")
exit(1)