gray/schemas/validate.py

54 lines
2.1 KiB
Python

import argparse
import sys
import json
import jsonschema
import jsonschema.validators
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)
# Validate the document
try:
validator.validate(document)
print("Valid!")
except ValidationError as e:
print("Validation failed.")
print(f"{e.message}")
exit(1)