from __future__ import print_function import json import os try: from jsonschema import SchemaError from jsonschema import Draft3Validator as Validator except ImportError as e: verbose_msg = """ IPython depends on the jsonschema package: https://pypi.python.org/pypi/jsonschema Please install it first. """ raise ImportError(str(e) + verbose_msg) try: import jsonpointer as jsonpointer except ImportError as e: verbose_msg = """ IPython depends on the jsonpointer package: https://pypi.python.org/pypi/jsonpointer Please install it first. """ raise ImportError(str(e) + verbose_msg) from IPython.utils.py3compat import iteritems from .current import nbformat, nbformat_schema schema_path = os.path.join( os.path.dirname(__file__), "v%d" % nbformat, nbformat_schema) def isvalid(nbjson): """Checks whether the given notebook JSON conforms to the current notebook format schema. Returns True if the JSON is valid, and False otherwise. To see the individual errors that were encountered, please use the `validate` function instead. """ errors = validate(nbjson) return errors == [] def validate(nbjson): """Checks whether the given notebook JSON conforms to the current notebook format schema, and returns the list of errors. """ # load the schema file with open(schema_path, 'r') as fh: schema_json = json.load(fh) # resolve internal references schema = resolve_ref(schema_json) schema = jsonpointer.resolve_pointer(schema, '/notebook') # count how many errors there are v = Validator(schema) errors = list(v.iter_errors(nbjson)) return errors def resolve_ref(json, schema=None): """Resolve internal references within the given JSON. This essentially means that dictionaries of this form: {"$ref": "/somepointer"} will be replaced with the resolved reference to `/somepointer`. This only supports local reference to the same JSON file. """ if not schema: schema = json # if it's a list, resolve references for each item in the list if type(json) is list: resolved = [] for item in json: resolved.append(resolve_ref(item, schema=schema)) # if it's a dictionary, resolve references for each item in the # dictionary elif type(json) is dict: resolved = {} for key, ref in iteritems(json): # if the key is equal to $ref, then replace the entire # dictionary with the resolved value if key == '$ref': if len(json) != 1: raise SchemaError( "objects containing a $ref should only have one item") pointer = jsonpointer.resolve_pointer(schema, ref) resolved = resolve_ref(pointer, schema=schema) else: resolved[key] = resolve_ref(ref, schema=schema) # otherwise it's a normal object, so just return it else: resolved = json return resolved