##// END OF EJS Templates
Merge pull request #5658 from jhamrick/nbvalidate...
Thomas Kluyver -
r16465:6c15f0ed merge
parent child Browse files
Show More
@@ -0,0 +1,152 b''
1 {
2 "metadata": {
3 "cell_tags": [
4 [
5 "<None>",
6 null
7 ]
8 ],
9 "name": 0
10 },
11 "nbformat": 3,
12 "nbformat_minor": 0,
13 "worksheets": [
14 {
15 "cells": [
16 {
17 "cell_type": "heading",
18 "level": 1,
19 "source": [
20 "nbconvert latex test"
21 ]
22 },
23 {
24 "cell_type": "markdown",
25 "metadata": {},
26 "source": [
27 "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit. Nunc luctus bibendum felis dictum sodales. Ut suscipit, orci ut interdum imperdiet, purus ligula mollis *justo*, non malesuada nisl augue eget lorem. Donec bibendum, erat sit amet porttitor aliquam, urna lorem ornare libero, in vehicula diam diam ut ante. Nam non urna rhoncus, accumsan elit sit amet, mollis tellus. Vestibulum nec tellus metus. Vestibulum tempor, ligula et vehicula rhoncus, sapien turpis faucibus lorem, id dapibus turpis mauris ac orci. Sed volutpat vestibulum venenatis."
28 ]
29 },
30 {
31 "cell_type": "heading",
32 "level": 2,
33 "metadata": {},
34 "source": [
35 "Printed Using Python"
36 ]
37 },
38 {
39 "cell_type": "code",
40 "collapsed": false,
41 "input": [
42 "print(\"hello\")"
43 ],
44 "language": "python",
45 "metadata": {},
46 "outputs": [
47 {
48 "output_type": "stream",
49 "stream": "stdout",
50 "text": [
51 "hello\n"
52 ]
53 }
54 ],
55 "prompt_number": 1
56 },
57 {
58 "cell_type": "heading",
59 "level": 1000,
60 "metadata": {},
61 "source": [
62 "Pyout"
63 ]
64 },
65 {
66 "cell_type": "code",
67 "collapsed": false,
68 "input": [
69 "from IPython.display import HTML\n",
70 "HTML(\"\"\"\n",
71 "<script>\n",
72 "console.log(\"hello\");\n",
73 "</script>\n",
74 "<b>HTML</b>\n",
75 "\"\"\")"
76 ],
77 "language": "python",
78 "metadata": {},
79 "outputs": [
80 {
81 "html": [
82 "\n",
83 "<script>\n",
84 "console.log(\"hello\");\n",
85 "</script>\n",
86 "<b>HTML</b>\n"
87 ],
88 "metadata": {},
89 "output_type": "pyout",
90 "prompt_number": 3,
91 "text": [
92 "<IPython.core.display.HTML at 0x1112757d0>"
93 ]
94 }
95 ],
96 "prompt_number": 3
97 },
98 {
99 "cell_type": "code",
100 "collapsed": false,
101 "input": [
102 "%%javascript\n",
103 "console.log(\"hi\");"
104 ],
105 "language": "python",
106 "metadata": {},
107 "outputs": [
108 {
109 "javascript": [
110 "console.log(\"hi\");"
111 ],
112 "metadata": {},
113 "output_type": "display_data",
114 "text": [
115 "<IPython.core.display.Javascript at 0x1112b4b50>"
116 ]
117 }
118 ],
119 "prompt_number": 7
120 },
121 {
122 "cell_type": "heading",
123 "level": 3,
124 "metadata": {}
125 },
126 {
127 "cell_type": "code",
128 "collapsed": false,
129 "input": [
130 "from IPython.display import Image\n",
131 "Image(\"http://ipython.org/_static/IPy_header.png\")"
132 ],
133 "language": "python",
134 "metadata": {},
135 "outputs": [
136 {
137 "metadata": {},
138 "output_type": "pyout",
139 "png": "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\n",
140 "prompt_number": 6,
141 "text": [
142 "<IPython.core.display.Image at 0x111275490>"
143 ]
144 }
145 ],
146 "prompt_number": 6
147 }
148 ],
149 "metadata": {}
150 }
151 ]
152 }
@@ -0,0 +1,73 b''
1 """
2 Contains tests class for validator.py
3 """
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2014 The IPython Development Team
6 #
7 # Distributed under the terms of the BSD License. The full license is in
8 # the file COPYING, distributed as part of this software.
9 #-----------------------------------------------------------------------------
10
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
14
15 import os
16
17 from .base import TestsBase
18 from IPython.external.jsonschema import SchemaError
19 from ..current import read
20 from ..validator import schema_path, isvalid, validate, resolve_ref
21
22
23 #-----------------------------------------------------------------------------
24 # Classes and functions
25 #-----------------------------------------------------------------------------
26
27 class TestValidator(TestsBase):
28
29 def test_schema_path(self):
30 """Test that the schema path exists"""
31 self.assertEqual(os.path.exists(schema_path), True)
32
33 def test_nb2(self):
34 """Test that a v2 notebook converted to v3 passes validation"""
35 with self.fopen(u'test2.ipynb', u'r') as f:
36 nb = read(f, u'json')
37 self.assertEqual(validate(nb), [])
38 self.assertEqual(isvalid(nb), True)
39
40 def test_nb3(self):
41 """Test that a v3 notebook passes validation"""
42 with self.fopen(u'test3.ipynb', u'r') as f:
43 nb = read(f, u'json')
44 self.assertEqual(validate(nb), [])
45 self.assertEqual(isvalid(nb), True)
46
47 def test_invalid(self):
48 """Test than an invalid notebook does not pass validation"""
49 # this notebook has a few different errors:
50 # - the name is an integer, rather than a string
51 # - one cell is missing its source
52 # - one cell has an invalid level
53 with self.fopen(u'invalid.ipynb', u'r') as f:
54 nb = read(f, u'json')
55 self.assertEqual(len(validate(nb)), 3)
56 self.assertEqual(isvalid(nb), False)
57
58 def test_resolve_ref(self):
59 """Test that references are correctly resolved"""
60 # make sure it resolves the ref correctly
61 json = {"abc": "def", "ghi": {"$ref": "/abc"}}
62 resolved = resolve_ref(json)
63 self.assertEqual(resolved, {"abc": "def", "ghi": "def"})
64
65 # make sure it throws an error if the ref is not by itself
66 json = {"abc": "def", "ghi": {"$ref": "/abc", "foo": "bar"}}
67 with self.assertRaises(SchemaError):
68 resolved = resolve_ref(json)
69
70 # make sure it can handle json with no reference
71 json = {"abc": "def"}
72 resolved = resolve_ref(json)
73 self.assertEqual(resolved, json)
@@ -0,0 +1,91 b''
1 from __future__ import print_function
2 import json
3 import os
4
5 from IPython.external.jsonschema import Draft3Validator, SchemaError
6 import IPython.external.jsonpointer as jsonpointer
7 from IPython.utils.py3compat import iteritems
8
9
10 from .current import nbformat, nbformat_schema
11 schema_path = os.path.join(
12 os.path.dirname(__file__), "v%d" % nbformat, nbformat_schema)
13
14
15 def isvalid(nbjson):
16 """Checks whether the given notebook JSON conforms to the current
17 notebook format schema. Returns True if the JSON is valid, and
18 False otherwise.
19
20 To see the individual errors that were encountered, please use the
21 `validate` function instead.
22
23 """
24
25 errors = validate(nbjson)
26 return errors == []
27
28
29 def validate(nbjson):
30 """Checks whether the given notebook JSON conforms to the current
31 notebook format schema, and returns the list of errors.
32
33 """
34
35 # load the schema file
36 with open(schema_path, 'r') as fh:
37 schema_json = json.load(fh)
38
39 # resolve internal references
40 v3schema = resolve_ref(schema_json)
41 v3schema = jsonpointer.resolve_pointer(v3schema, '/notebook')
42
43 # count how many errors there are
44 v = Draft3Validator(v3schema)
45 errors = list(v.iter_errors(nbjson))
46 return errors
47
48
49 def resolve_ref(json, schema=None):
50 """Resolve internal references within the given JSON. This essentially
51 means that dictionaries of this form:
52
53 {"$ref": "/somepointer"}
54
55 will be replaced with the resolved reference to `/somepointer`.
56 This only supports local reference to the same JSON file.
57
58 """
59
60 if not schema:
61 schema = json
62
63 # if it's a list, resolve references for each item in the list
64 if type(json) is list:
65 resolved = []
66 for item in json:
67 resolved.append(resolve_ref(item, schema=schema))
68
69 # if it's a dictionary, resolve references for each item in the
70 # dictionary
71 elif type(json) is dict:
72 resolved = {}
73 for key, ref in iteritems(json):
74
75 # if the key is equal to $ref, then replace the entire
76 # dictionary with the resolved value
77 if key == '$ref':
78 if len(json) != 1:
79 raise SchemaError(
80 "objects containing a $ref should only have one item")
81 pointer = jsonpointer.resolve_pointer(schema, ref)
82 resolved = resolve_ref(pointer, schema=schema)
83
84 else:
85 resolved[key] = resolve_ref(ref, schema=schema)
86
87 # otherwise it's a normal object, so just return it
88 else:
89 resolved = json
90
91 return resolved
@@ -28,13 +28,17 b' from IPython.nbformat.v3 import ('
28 NotebookNode,
28 NotebookNode,
29 new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet,
29 new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet,
30 parse_filename, new_metadata, new_author, new_heading_cell, nbformat,
30 parse_filename, new_metadata, new_author, new_heading_cell, nbformat,
31 nbformat_minor, to_notebook_json
31 nbformat_minor, nbformat_schema, to_notebook_json
32 )
32 )
33 from IPython.nbformat import v3 as _v_latest
33 from IPython.nbformat import v3 as _v_latest
34
34
35 from .reader import reads as reader_reads
35 from .reader import reads as reader_reads
36 from .reader import versions
36 from .reader import versions
37 from .convert import convert
37 from .convert import convert
38 from .validator import validate
39
40 import logging
41 logger = logging.getLogger('NotebookApp')
38
42
39 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
40 # Code
44 # Code
@@ -44,6 +48,7 b' current_nbformat = nbformat'
44 current_nbformat_minor = nbformat_minor
48 current_nbformat_minor = nbformat_minor
45 current_nbformat_module = _v_latest.__name__
49 current_nbformat_module = _v_latest.__name__
46
50
51
47 def docstring_nbformat_mod(func):
52 def docstring_nbformat_mod(func):
48 """Decorator for docstrings referring to classes/functions accessed through
53 """Decorator for docstrings referring to classes/functions accessed through
49 nbformat.current.
54 nbformat.current.
@@ -74,13 +79,33 b' def parse_py(s, **kwargs):'
74 return nbf, nbm, s
79 return nbf, nbm, s
75
80
76
81
77 def reads_json(s, **kwargs):
82 def reads_json(nbjson, **kwargs):
78 """Read a JSON notebook from a string and return the NotebookNode object."""
83 """Read a JSON notebook from a string and return the NotebookNode
79 return convert(reader_reads(s), current_nbformat)
84 object. Report if any JSON format errors are detected.
85
86 """
87 nb = reader_reads(nbjson, **kwargs)
88 nb_current = convert(nb, current_nbformat)
89 errors = validate(nb_current)
90 if errors:
91 logger.error(
92 "Notebook JSON is invalid (%d errors detected during read)",
93 len(errors))
94 return nb_current
80
95
81
96
82 def writes_json(nb, **kwargs):
97 def writes_json(nb, **kwargs):
83 return versions[current_nbformat].writes_json(nb, **kwargs)
98 """Take a NotebookNode object and write out a JSON string. Report if
99 any JSON format errors are detected.
100
101 """
102 errors = validate(nb)
103 if errors:
104 logger.error(
105 "Notebook JSON is invalid (%d errors detected during write)",
106 len(errors))
107 nbjson = versions[current_nbformat].writes_json(nb, **kwargs)
108 return nbjson
84
109
85
110
86 def reads_py(s, **kwargs):
111 def reads_py(s, **kwargs):
@@ -19,7 +19,8 b' Authors:'
19 from .nbbase import (
19 from .nbbase import (
20 NotebookNode,
20 NotebookNode,
21 new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet,
21 new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet,
22 new_metadata, new_author, new_heading_cell, nbformat, nbformat_minor
22 new_metadata, new_author, new_heading_cell, nbformat, nbformat_minor,
23 nbformat_schema
23 )
24 )
24
25
25 from .nbjson import reads as reads_json, writes as writes_json
26 from .nbjson import reads as reads_json, writes as writes_json
@@ -22,6 +22,7 b' from IPython.utils.py3compat import cast_unicode, unicode_type'
22 # Change this when incrementing the nbformat version
22 # Change this when incrementing the nbformat version
23 nbformat = 3
23 nbformat = 3
24 nbformat_minor = 0
24 nbformat_minor = 0
25 nbformat_schema = 'v3.withref.json'
25
26
26 class NotebookNode(Struct):
27 class NotebookNode(Struct):
27 pass
28 pass
@@ -38,6 +38,13 b''
38 "id": "nbformat",
38 "id": "nbformat",
39 "required": true
39 "required": true
40 },
40 },
41 "orig_nbformat": {
42 "description": "Original notebook format, major number.",
43 "type": "integer",
44 "minimum": 1,
45 "id": "orig_nbformat",
46 "required": false
47 },
41 "worksheets": {
48 "worksheets": {
42 "description": "Array of worksheet, not used by the current implementation of ipython yet",
49 "description": "Array of worksheet, not used by the current implementation of ipython yet",
43 "type": "array",
50 "type": "array",
@@ -64,7 +71,7 b''
64 "type": "object",
71 "type": "object",
65 "description": "metadata of the current worksheet",
72 "description": "metadata of the current worksheet",
66 "id": "metadata",
73 "id": "metadata",
67 "required": true
74 "required": false
68 }
75 }
69 }
76 }
70 },
77 },
@@ -92,11 +99,11 b''
92 "metadata": {
99 "metadata": {
93 "type": "object",
100 "type": "object",
94 "id": "metadata",
101 "id": "metadata",
95 "required": true
102 "required": false
96 },
103 },
97 "source": {
104 "source": {
98 "description": "for code cell, the source code",
105 "description": "for code cell, the source code",
99 "type": "array",
106 "type": ["array", "string"],
100 "id": "source",
107 "id": "source",
101 "required": true,
108 "required": true,
102 "items":
109 "items":
@@ -133,7 +140,7 b''
133 "metadata": {
140 "metadata": {
134 "type": "object",
141 "type": "object",
135 "id": "metadata",
142 "id": "metadata",
136 "required": true
143 "required": false
137 },
144 },
138 "collapsed": {
145 "collapsed": {
139 "type": "boolean",
146 "type": "boolean",
@@ -141,7 +148,7 b''
141 },
148 },
142 "input": {
149 "input": {
143 "description": "user input for text cells",
150 "description": "user input for text cells",
144 "type": "array",
151 "type": ["array", "string"],
145 "id": "input",
152 "id": "input",
146 "required": true,
153 "required": true,
147 "items":
154 "items":
@@ -158,7 +165,7 b''
158 },
165 },
159 "prompt_number": {
166 "prompt_number": {
160 "type": ["integer","null"],
167 "type": ["integer","null"],
161 "required": true,
168 "required": false,
162 "minimum": 0
169 "minimum": 0
163 },
170 },
164 "language": {
171 "language": {
@@ -14,6 +14,7 b' prune IPython/html/static/mathjax'
14 # Include some specific files and data resources we need
14 # Include some specific files and data resources we need
15 include IPython/.git_commit_info.ini
15 include IPython/.git_commit_info.ini
16 include IPython/qt/console/resources/icon/IPythonConsole.svg
16 include IPython/qt/console/resources/icon/IPythonConsole.svg
17 include IPython/nbformat/v3/v3.withref.json
17
18
18 # Documentation
19 # Documentation
19 graft docs
20 graft docs
@@ -187,7 +187,7 b' def find_package_data():'
187 'IPython.nbconvert' : nbconvert_templates +
187 'IPython.nbconvert' : nbconvert_templates +
188 ['tests/files/*.*', 'exporters/tests/files/*.*'],
188 ['tests/files/*.*', 'exporters/tests/files/*.*'],
189 'IPython.nbconvert.filters' : ['marked.js'],
189 'IPython.nbconvert.filters' : ['marked.js'],
190 'IPython.nbformat' : ['tests/*.ipynb']
190 'IPython.nbformat' : ['tests/*.ipynb','v3/v3.withref.json']
191 }
191 }
192
192
193 return package_data
193 return package_data
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now