##// END OF EJS Templates
Add top-level IPython.nbformat API...
MinRK -
Show More
@@ -0,0 +1,143 b''
1 """The IPython notebook format
2
3 Use this module to read or write notebook files as particular nbformat versions.
4 """
5
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
8
9 from IPython.utils.log import get_logger
10
11 from . import v1
12 from . import v2
13 from . import v3
14 from . import v4
15
16 versions = {
17 1: v1,
18 2: v2,
19 3: v3,
20 4: v4,
21 }
22
23 from .validator import validate, ValidationError
24 from .converter import convert
25 from . import reader
26
27 from .v4 import (
28 nbformat as current_nbformat,
29 nbformat_minor as current_nbformat_minor,
30 )
31
32 class NBFormatError(ValueError):
33 pass
34
35 # no-conversion singleton
36 NO_CONVERT = object()
37
38 def reads(s, as_version, **kwargs):
39 """Read a notebook from a string and return the NotebookNode object as the given version.
40
41 The string can contain a notebook of any version.
42 The notebook will be returned `as_version`, converting, if necessary.
43
44 Notebook format errors will be logged.
45
46 Parameters
47 ----------
48 s : unicode
49 The raw unicode string to read the notebook from.
50 as_version : int
51 The version of the notebook format to return.
52 The notebook will be converted, if necessary.
53 Pass nbformat.NO_CONVERT to prevent conversion.
54
55 Returns
56 -------
57 nb : NotebookNode
58 The notebook that was read.
59 """
60 nb = reader.reads(s, **kwargs)
61 if as_version is not NO_CONVERT:
62 nb = convert(nb, as_version)
63 try:
64 validate(nb)
65 except ValidationError as e:
66 get_logger().error("Notebook JSON is invalid: %s", e)
67 return nb
68
69
70 def writes(nb, version, **kwargs):
71 """Write a notebook to a string in a given format in the given nbformat version.
72
73 Any notebook format errors will be logged.
74
75 Parameters
76 ----------
77 nb : NotebookNode
78 The notebook to write.
79 version : int
80 The nbformat version to write.
81 If nb is not this version, it will be converted.
82 Pass nbformat.NO_CONVERT to prevent conversion.
83
84 Returns
85 -------
86 s : unicode
87 The notebook as a JSON string.
88 """
89 if version is not NO_CONVERT:
90 nb = convert(nb, version)
91 else:
92 version, _ = reader.get_version(nb)
93 try:
94 validate(nb)
95 except ValidationError as e:
96 get_logger().error("Notebook JSON is invalid: %s", e)
97 return versions[version].writes_json(nb, **kwargs)
98
99
100 def read(fp, as_version, **kwargs):
101 """Read a notebook from a file as a NotebookNode of the given version.
102
103 The string can contain a notebook of any version.
104 The notebook will be returned `as_version`, converting, if necessary.
105
106 Notebook format errors will be logged.
107
108 Parameters
109 ----------
110 fp : file
111 Any file-like object with a read method.
112 as_version: int
113 The version of the notebook format to return.
114 The notebook will be converted, if necessary.
115 Pass nbformat.NO_CONVERT to prevent conversion.
116
117 Returns
118 -------
119 nb : NotebookNode
120 The notebook that was read.
121 """
122 return reads(fp.read(), as_version, **kwargs)
123
124
125 def write(fp, nb, version, **kwargs):
126 """Write a notebook to a file in a given nbformat version.
127
128 The file-like object must accept unicode input.
129
130 Parameters
131 ----------
132 fp : file
133 Any file-like object with a write method that accepts unicode.
134 nb : NotebookNode
135 The notebook to write.
136 version : int
137 The nbformat version to write.
138 If nb is not this version, it will be converted.
139 """
140 s = writes(nb, version, **kwargs)
141 if isinstance(s, bytes):
142 s = s.decode('utf8')
143 return fp.write(s)
@@ -3,7 +3,8 b''
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 from .reader import get_version, versions
6 from . import versions
7 from .reader import get_version
7
8
8
9
9 def convert(nb, to_version):
10 def convert(nb, to_version):
@@ -24,7 +25,7 b' def convert(nb, to_version):'
24 # Get input notebook version.
25 # Get input notebook version.
25 (version, version_minor) = get_version(nb)
26 (version, version_minor) = get_version(nb)
26
27
27 # Check if destination is current version, if so return contents
28 # Check if destination is target version, if so return contents
28 if version == to_version:
29 if version == to_version:
29 return nb
30 return nb
30
31
@@ -17,8 +17,8 b' from IPython.nbformat.v3 import ('
17 from IPython.nbformat import v3 as _v_latest
17 from IPython.nbformat import v3 as _v_latest
18
18
19 from .reader import reads as reader_reads
19 from .reader import reads as reader_reads
20 from .reader import versions
20 from . import versions
21 from .convert import convert
21 from .converter import convert
22 from .validator import validate, ValidationError
22 from .validator import validate, ValidationError
23
23
24 from IPython.utils.log import get_logger
24 from IPython.utils.log import get_logger
@@ -5,19 +5,6 b''
5
5
6 import json
6 import json
7
7
8 from . import v1
9 from . import v2
10 from . import v3
11 from . import v4
12
13 versions = {
14 1: v1,
15 2: v2,
16 3: v3,
17 4: v4,
18 }
19
20
21 class NotJSONError(ValueError):
8 class NotJSONError(ValueError):
22 pass
9 pass
23
10
@@ -66,7 +53,7 b' def reads(s, **kwargs):'
66 nb : NotebookNode
53 nb : NotebookNode
67 The notebook that was read.
54 The notebook that was read.
68 """
55 """
69 from .current import NBFormatError
56 from . import versions, NBFormatError
70
57
71 nb_dict = parse_json(s, **kwargs)
58 nb_dict = parse_json(s, **kwargs)
72 (major, minor) = get_version(nb_dict)
59 (major, minor) = get_version(nb_dict)
@@ -10,12 +10,13 b' from hmac import HMAC'
10 import io
10 import io
11 import os
11 import os
12
12
13 from IPython.utils.io import atomic_writing
13 from IPython.utils.py3compat import string_types, unicode_type, cast_bytes
14 from IPython.utils.py3compat import string_types, unicode_type, cast_bytes
14 from IPython.utils.traitlets import Instance, Bytes, Enum, Any, Unicode, Bool
15 from IPython.utils.traitlets import Instance, Bytes, Enum, Any, Unicode, Bool
15 from IPython.config import LoggingConfigurable, MultipleInstanceError
16 from IPython.config import LoggingConfigurable, MultipleInstanceError
16 from IPython.core.application import BaseIPythonApplication, base_flags
17 from IPython.core.application import BaseIPythonApplication, base_flags
17
18
18 from .current import read, write
19 from . import read, write, NO_CONVERT
19
20
20 try:
21 try:
21 # Python 3
22 # Python 3
@@ -278,14 +279,14 b' class TrustNotebookApp(BaseIPythonApplication):'
278 self.log.error("Notebook missing: %s" % notebook_path)
279 self.log.error("Notebook missing: %s" % notebook_path)
279 self.exit(1)
280 self.exit(1)
280 with io.open(notebook_path, encoding='utf8') as f:
281 with io.open(notebook_path, encoding='utf8') as f:
281 nb = read(f, 'json')
282 nb = read(f, NO_CONVERT)
282 if self.notary.check_signature(nb):
283 if self.notary.check_signature(nb):
283 print("Notebook already signed: %s" % notebook_path)
284 print("Notebook already signed: %s" % notebook_path)
284 else:
285 else:
285 print("Signing notebook: %s" % notebook_path)
286 print("Signing notebook: %s" % notebook_path)
286 self.notary.sign(nb)
287 self.notary.sign(nb)
287 with io.open(notebook_path, 'w', encoding='utf8') as f:
288 with atomic_writing(notebook_path) as f:
288 write(nb, f, 'json')
289 write(f, nb, NO_CONVERT)
289
290
290 def generate_new_key(self):
291 def generate_new_key(self):
291 """Generate a new notebook signature key"""
292 """Generate a new notebook signature key"""
@@ -1,29 +1,25 b''
1 """
1 """Test the APIs at the top-level of nbformat"""
2 Contains tests class for current.py
3 """
4
2
5 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
6 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
7
5
8 import io
9 import json
6 import json
10 import tempfile
11
7
12 from .base import TestsBase
8 from .base import TestsBase
13
9
14 from ..reader import get_version
10 from ..reader import get_version
15 from ..current import read, current_nbformat, validate, writes
11 from IPython.nbformat import read, current_nbformat, writes
16
12
17
13
18 class TestCurrent(TestsBase):
14 class TestAPI(TestsBase):
19
15
20 def test_read(self):
16 def test_read(self):
21 """Can older notebooks be opened and automatically converted to the current
17 """Can older notebooks be opened and automatically converted to the current
22 nbformat?"""
18 nbformat?"""
23
19
24 # Open a version 2 notebook.
20 # Open a version 2 notebook.
25 with self.fopen(u'test2.ipynb', u'r') as f:
21 with self.fopen(u'test2.ipynb', 'r') as f:
26 nb = read(f)
22 nb = read(f, as_version=current_nbformat)
27
23
28 # Check that the notebook was upgraded to the latest version automatically.
24 # Check that the notebook was upgraded to the latest version automatically.
29 (major, minor) = get_version(nb)
25 (major, minor) = get_version(nb)
@@ -33,7 +29,7 b' class TestCurrent(TestsBase):'
33 """dowgrade a v3 notebook to v2"""
29 """dowgrade a v3 notebook to v2"""
34 # Open a version 3 notebook.
30 # Open a version 3 notebook.
35 with self.fopen(u'test3.ipynb', 'r') as f:
31 with self.fopen(u'test3.ipynb', 'r') as f:
36 nb = read(f, u'json')
32 nb = read(f, as_version=3)
37
33
38 jsons = writes(nb, version=2)
34 jsons = writes(nb, version=2)
39 nb2 = json.loads(jsons)
35 nb2 = json.loads(jsons)
@@ -5,9 +5,9 b''
5
5
6 from .base import TestsBase
6 from .base import TestsBase
7
7
8 from ..convert import convert
8 from ..converter import convert
9 from ..reader import read, get_version
9 from ..reader import read, get_version
10 from ..current import current_nbformat
10 from .. import current_nbformat
11
11
12
12
13 class TestConvert(TestsBase):
13 class TestConvert(TestsBase):
@@ -3,10 +3,9 b''
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 from .. import sign
7 from .base import TestsBase
6 from .base import TestsBase
8
7
9 from ..current import read
8 from IPython.nbformat import read, sign
10 from IPython.core.getipython import get_ipython
9 from IPython.core.getipython import get_ipython
11
10
12
11
@@ -18,7 +17,7 b' class TestNotary(TestsBase):'
18 profile_dir=get_ipython().profile_dir
17 profile_dir=get_ipython().profile_dir
19 )
18 )
20 with self.fopen(u'test3.ipynb', u'r') as f:
19 with self.fopen(u'test3.ipynb', u'r') as f:
21 self.nb = read(f, u'json')
20 self.nb = read(f, as_version=4)
22
21
23 def test_algorithms(self):
22 def test_algorithms(self):
24 last_sig = ''
23 last_sig = ''
@@ -7,7 +7,7 b' import os'
7
7
8 from .base import TestsBase
8 from .base import TestsBase
9 from jsonschema import ValidationError
9 from jsonschema import ValidationError
10 from ..current import read
10 from IPython.nbformat import read
11 from ..validator import isvalid, validate
11 from ..validator import isvalid, validate
12
12
13
13
@@ -16,21 +16,21 b' class TestValidator(TestsBase):'
16 def test_nb2(self):
16 def test_nb2(self):
17 """Test that a v2 notebook converted to current passes validation"""
17 """Test that a v2 notebook converted to current passes validation"""
18 with self.fopen(u'test2.ipynb', u'r') as f:
18 with self.fopen(u'test2.ipynb', u'r') as f:
19 nb = read(f, u'json')
19 nb = read(f, as_version=4)
20 validate(nb)
20 validate(nb)
21 self.assertEqual(isvalid(nb), True)
21 self.assertEqual(isvalid(nb), True)
22
22
23 def test_nb3(self):
23 def test_nb3(self):
24 """Test that a v3 notebook passes validation"""
24 """Test that a v3 notebook passes validation"""
25 with self.fopen(u'test3.ipynb', u'r') as f:
25 with self.fopen(u'test3.ipynb', u'r') as f:
26 nb = read(f, u'json')
26 nb = read(f, as_version=4)
27 validate(nb)
27 validate(nb)
28 self.assertEqual(isvalid(nb), True)
28 self.assertEqual(isvalid(nb), True)
29
29
30 def test_nb4(self):
30 def test_nb4(self):
31 """Test that a v4 notebook passes validation"""
31 """Test that a v4 notebook passes validation"""
32 with self.fopen(u'test4.ipynb', u'r') as f:
32 with self.fopen(u'test4.ipynb', u'r') as f:
33 nb = read(f, u'json')
33 nb = read(f, as_version=4)
34 validate(nb)
34 validate(nb)
35 self.assertEqual(isvalid(nb), True)
35 self.assertEqual(isvalid(nb), True)
36
36
@@ -41,7 +41,7 b' class TestValidator(TestsBase):'
41 # - invalid cell type
41 # - invalid cell type
42 # - invalid output_type
42 # - invalid output_type
43 with self.fopen(u'invalid.ipynb', u'r') as f:
43 with self.fopen(u'invalid.ipynb', u'r') as f:
44 nb = read(f, u'json')
44 nb = read(f, as_version=4)
45 with self.assertRaises(ValidationError):
45 with self.assertRaises(ValidationError):
46 validate(nb)
46 validate(nb)
47 self.assertEqual(isvalid(nb), False)
47 self.assertEqual(isvalid(nb), False)
@@ -49,7 +49,7 b' class TestValidator(TestsBase):'
49 def test_future(self):
49 def test_future(self):
50 """Test than a notebook from the future with extra keys passes validation"""
50 """Test than a notebook from the future with extra keys passes validation"""
51 with self.fopen(u'test4plus.ipynb', u'r') as f:
51 with self.fopen(u'test4plus.ipynb', u'r') as f:
52 nb = read(f)
52 nb = read(f, as_version=4)
53 with self.assertRaises(ValidationError):
53 with self.assertRaises(ValidationError):
54 validate(nb, version=4)
54 validate(nb, version=4)
55
55
@@ -16,7 +16,7 b' from IPython.utils.log import get_logger'
16
16
17 def _warn_if_invalid(nb, version):
17 def _warn_if_invalid(nb, version):
18 """Log validation errors, if there are any."""
18 """Log validation errors, if there are any."""
19 from IPython.nbformat.current import validate, ValidationError
19 from IPython.nbformat import validate, ValidationError
20 try:
20 try:
21 validate(nb, version=version)
21 validate(nb, version=version)
22 except ValidationError as e:
22 except ValidationError as e:
@@ -19,7 +19,7 b" nbformat_schema = 'nbformat.v4.schema.json'"
19
19
20 def validate(node, ref=None):
20 def validate(node, ref=None):
21 """validate a v4 node"""
21 """validate a v4 node"""
22 from ..current import validate
22 from .. import validate
23 return validate(node, ref=ref, version=nbformat)
23 return validate(node, ref=ref, version=nbformat)
24
24
25
25
@@ -2,7 +2,7 b' import copy'
2
2
3 import nose.tools as nt
3 import nose.tools as nt
4
4
5 from IPython.nbformat.current import validate
5 from IPython.nbformat import validate
6 from .. import convert
6 from .. import convert
7
7
8 from . import nbexamples
8 from . import nbexamples
@@ -43,7 +43,8 b' def _relax_additional_properties(obj):'
43 def get_validator(version=None, version_minor=None):
43 def get_validator(version=None, version_minor=None):
44 """Load the JSON schema into a Validator"""
44 """Load the JSON schema into a Validator"""
45 if version is None:
45 if version is None:
46 from .current import nbformat as version
46 from .. import current_nbformat
47 version = current_nbformat
47
48
48 v = import_item("IPython.nbformat.v%s" % version)
49 v = import_item("IPython.nbformat.v%s" % version)
49 current_minor = v.nbformat_minor
50 current_minor = v.nbformat_minor
General Comments 0
You need to be logged in to leave comments. Login now