##// END OF EJS Templates
more verbose message on missing jsonschema
Paul Ivanov -
Show More
@@ -1,92 +1,101 b''
1 from __future__ import print_function
1 from __future__ import print_function
2 import json
2 import json
3 import os
3 import os
4
4
5 from jsonschema import SchemaError
5 try:
6 from jsonschema import Draft3Validator as Validator
6 from jsonschema import SchemaError
7 from jsonschema import Draft3Validator as Validator
8 except ImportError as e:
9 verbose_msg = """
10
11 The `jsonschema` packages is now a hard dependency for IPython
12
13 You can install it using `pip install jsonschema`
14 """
15 raise ImportError(e.message + verbose_msg)
7 import jsonpointer as jsonpointer
16 import jsonpointer as jsonpointer
8 from IPython.utils.py3compat import iteritems
17 from IPython.utils.py3compat import iteritems
9
18
10
19
11 from .current import nbformat, nbformat_schema
20 from .current import nbformat, nbformat_schema
12 schema_path = os.path.join(
21 schema_path = os.path.join(
13 os.path.dirname(__file__), "v%d" % nbformat, nbformat_schema)
22 os.path.dirname(__file__), "v%d" % nbformat, nbformat_schema)
14
23
15
24
16 def isvalid(nbjson):
25 def isvalid(nbjson):
17 """Checks whether the given notebook JSON conforms to the current
26 """Checks whether the given notebook JSON conforms to the current
18 notebook format schema. Returns True if the JSON is valid, and
27 notebook format schema. Returns True if the JSON is valid, and
19 False otherwise.
28 False otherwise.
20
29
21 To see the individual errors that were encountered, please use the
30 To see the individual errors that were encountered, please use the
22 `validate` function instead.
31 `validate` function instead.
23
32
24 """
33 """
25
34
26 errors = validate(nbjson)
35 errors = validate(nbjson)
27 return errors == []
36 return errors == []
28
37
29
38
30 def validate(nbjson):
39 def validate(nbjson):
31 """Checks whether the given notebook JSON conforms to the current
40 """Checks whether the given notebook JSON conforms to the current
32 notebook format schema, and returns the list of errors.
41 notebook format schema, and returns the list of errors.
33
42
34 """
43 """
35
44
36 # load the schema file
45 # load the schema file
37 with open(schema_path, 'r') as fh:
46 with open(schema_path, 'r') as fh:
38 schema_json = json.load(fh)
47 schema_json = json.load(fh)
39
48
40 # resolve internal references
49 # resolve internal references
41 schema = resolve_ref(schema_json)
50 schema = resolve_ref(schema_json)
42 schema = jsonpointer.resolve_pointer(schema, '/notebook')
51 schema = jsonpointer.resolve_pointer(schema, '/notebook')
43
52
44 # count how many errors there are
53 # count how many errors there are
45 v = Validator(schema)
54 v = Validator(schema)
46 errors = list(v.iter_errors(nbjson))
55 errors = list(v.iter_errors(nbjson))
47 return errors
56 return errors
48
57
49
58
50 def resolve_ref(json, schema=None):
59 def resolve_ref(json, schema=None):
51 """Resolve internal references within the given JSON. This essentially
60 """Resolve internal references within the given JSON. This essentially
52 means that dictionaries of this form:
61 means that dictionaries of this form:
53
62
54 {"$ref": "/somepointer"}
63 {"$ref": "/somepointer"}
55
64
56 will be replaced with the resolved reference to `/somepointer`.
65 will be replaced with the resolved reference to `/somepointer`.
57 This only supports local reference to the same JSON file.
66 This only supports local reference to the same JSON file.
58
67
59 """
68 """
60
69
61 if not schema:
70 if not schema:
62 schema = json
71 schema = json
63
72
64 # if it's a list, resolve references for each item in the list
73 # if it's a list, resolve references for each item in the list
65 if type(json) is list:
74 if type(json) is list:
66 resolved = []
75 resolved = []
67 for item in json:
76 for item in json:
68 resolved.append(resolve_ref(item, schema=schema))
77 resolved.append(resolve_ref(item, schema=schema))
69
78
70 # if it's a dictionary, resolve references for each item in the
79 # if it's a dictionary, resolve references for each item in the
71 # dictionary
80 # dictionary
72 elif type(json) is dict:
81 elif type(json) is dict:
73 resolved = {}
82 resolved = {}
74 for key, ref in iteritems(json):
83 for key, ref in iteritems(json):
75
84
76 # if the key is equal to $ref, then replace the entire
85 # if the key is equal to $ref, then replace the entire
77 # dictionary with the resolved value
86 # dictionary with the resolved value
78 if key == '$ref':
87 if key == '$ref':
79 if len(json) != 1:
88 if len(json) != 1:
80 raise SchemaError(
89 raise SchemaError(
81 "objects containing a $ref should only have one item")
90 "objects containing a $ref should only have one item")
82 pointer = jsonpointer.resolve_pointer(schema, ref)
91 pointer = jsonpointer.resolve_pointer(schema, ref)
83 resolved = resolve_ref(pointer, schema=schema)
92 resolved = resolve_ref(pointer, schema=schema)
84
93
85 else:
94 else:
86 resolved[key] = resolve_ref(ref, schema=schema)
95 resolved[key] = resolve_ref(ref, schema=schema)
87
96
88 # otherwise it's a normal object, so just return it
97 # otherwise it's a normal object, so just return it
89 else:
98 else:
90 resolved = json
99 resolved = json
91
100
92 return resolved
101 return resolved
General Comments 0
You need to be logged in to leave comments. Login now