##// 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 3 # Copyright (c) IPython Development Team.
4 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 10 def convert(nb, to_version):
@@ -24,7 +25,7 b' def convert(nb, to_version):'
24 25 # Get input notebook version.
25 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 29 if version == to_version:
29 30 return nb
30 31
@@ -17,8 +17,8 b' from IPython.nbformat.v3 import ('
17 17 from IPython.nbformat import v3 as _v_latest
18 18
19 19 from .reader import reads as reader_reads
20 from .reader import versions
21 from .convert import convert
20 from . import versions
21 from .converter import convert
22 22 from .validator import validate, ValidationError
23 23
24 24 from IPython.utils.log import get_logger
@@ -5,19 +5,6 b''
5 5
6 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 8 class NotJSONError(ValueError):
22 9 pass
23 10
@@ -66,7 +53,7 b' def reads(s, **kwargs):'
66 53 nb : NotebookNode
67 54 The notebook that was read.
68 55 """
69 from .current import NBFormatError
56 from . import versions, NBFormatError
70 57
71 58 nb_dict = parse_json(s, **kwargs)
72 59 (major, minor) = get_version(nb_dict)
@@ -10,12 +10,13 b' from hmac import HMAC'
10 10 import io
11 11 import os
12 12
13 from IPython.utils.io import atomic_writing
13 14 from IPython.utils.py3compat import string_types, unicode_type, cast_bytes
14 15 from IPython.utils.traitlets import Instance, Bytes, Enum, Any, Unicode, Bool
15 16 from IPython.config import LoggingConfigurable, MultipleInstanceError
16 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 21 try:
21 22 # Python 3
@@ -278,14 +279,14 b' class TrustNotebookApp(BaseIPythonApplication):'
278 279 self.log.error("Notebook missing: %s" % notebook_path)
279 280 self.exit(1)
280 281 with io.open(notebook_path, encoding='utf8') as f:
281 nb = read(f, 'json')
282 nb = read(f, NO_CONVERT)
282 283 if self.notary.check_signature(nb):
283 284 print("Notebook already signed: %s" % notebook_path)
284 285 else:
285 286 print("Signing notebook: %s" % notebook_path)
286 287 self.notary.sign(nb)
287 with io.open(notebook_path, 'w', encoding='utf8') as f:
288 write(nb, f, 'json')
288 with atomic_writing(notebook_path) as f:
289 write(f, nb, NO_CONVERT)
289 290
290 291 def generate_new_key(self):
291 292 """Generate a new notebook signature key"""
@@ -1,29 +1,25 b''
1 """
2 Contains tests class for current.py
3 """
1 """Test the APIs at the top-level of nbformat"""
4 2
5 3 # Copyright (c) IPython Development Team.
6 4 # Distributed under the terms of the Modified BSD License.
7 5
8 import io
9 6 import json
10 import tempfile
11 7
12 8 from .base import TestsBase
13 9
14 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 16 def test_read(self):
21 17 """Can older notebooks be opened and automatically converted to the current
22 18 nbformat?"""
23 19
24 20 # Open a version 2 notebook.
25 with self.fopen(u'test2.ipynb', u'r') as f:
26 nb = read(f)
21 with self.fopen(u'test2.ipynb', 'r') as f:
22 nb = read(f, as_version=current_nbformat)
27 23
28 24 # Check that the notebook was upgraded to the latest version automatically.
29 25 (major, minor) = get_version(nb)
@@ -33,7 +29,7 b' class TestCurrent(TestsBase):'
33 29 """dowgrade a v3 notebook to v2"""
34 30 # Open a version 3 notebook.
35 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 34 jsons = writes(nb, version=2)
39 35 nb2 = json.loads(jsons)
@@ -5,9 +5,9 b''
5 5
6 6 from .base import TestsBase
7 7
8 from ..convert import convert
8 from ..converter import convert
9 9 from ..reader import read, get_version
10 from ..current import current_nbformat
10 from .. import current_nbformat
11 11
12 12
13 13 class TestConvert(TestsBase):
@@ -3,10 +3,9 b''
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6 from .. import sign
7 6 from .base import TestsBase
8 7
9 from ..current import read
8 from IPython.nbformat import read, sign
10 9 from IPython.core.getipython import get_ipython
11 10
12 11
@@ -18,7 +17,7 b' class TestNotary(TestsBase):'
18 17 profile_dir=get_ipython().profile_dir
19 18 )
20 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 22 def test_algorithms(self):
24 23 last_sig = ''
@@ -7,7 +7,7 b' import os'
7 7
8 8 from .base import TestsBase
9 9 from jsonschema import ValidationError
10 from ..current import read
10 from IPython.nbformat import read
11 11 from ..validator import isvalid, validate
12 12
13 13
@@ -16,21 +16,21 b' class TestValidator(TestsBase):'
16 16 def test_nb2(self):
17 17 """Test that a v2 notebook converted to current passes validation"""
18 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 20 validate(nb)
21 21 self.assertEqual(isvalid(nb), True)
22 22
23 23 def test_nb3(self):
24 24 """Test that a v3 notebook passes validation"""
25 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 27 validate(nb)
28 28 self.assertEqual(isvalid(nb), True)
29 29
30 30 def test_nb4(self):
31 31 """Test that a v4 notebook passes validation"""
32 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 34 validate(nb)
35 35 self.assertEqual(isvalid(nb), True)
36 36
@@ -41,7 +41,7 b' class TestValidator(TestsBase):'
41 41 # - invalid cell type
42 42 # - invalid output_type
43 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 45 with self.assertRaises(ValidationError):
46 46 validate(nb)
47 47 self.assertEqual(isvalid(nb), False)
@@ -49,7 +49,7 b' class TestValidator(TestsBase):'
49 49 def test_future(self):
50 50 """Test than a notebook from the future with extra keys passes validation"""
51 51 with self.fopen(u'test4plus.ipynb', u'r') as f:
52 nb = read(f)
52 nb = read(f, as_version=4)
53 53 with self.assertRaises(ValidationError):
54 54 validate(nb, version=4)
55 55
@@ -16,7 +16,7 b' from IPython.utils.log import get_logger'
16 16
17 17 def _warn_if_invalid(nb, version):
18 18 """Log validation errors, if there are any."""
19 from IPython.nbformat.current import validate, ValidationError
19 from IPython.nbformat import validate, ValidationError
20 20 try:
21 21 validate(nb, version=version)
22 22 except ValidationError as e:
@@ -19,7 +19,7 b" nbformat_schema = 'nbformat.v4.schema.json'"
19 19
20 20 def validate(node, ref=None):
21 21 """validate a v4 node"""
22 from ..current import validate
22 from .. import validate
23 23 return validate(node, ref=ref, version=nbformat)
24 24
25 25
@@ -2,7 +2,7 b' import copy'
2 2
3 3 import nose.tools as nt
4 4
5 from IPython.nbformat.current import validate
5 from IPython.nbformat import validate
6 6 from .. import convert
7 7
8 8 from . import nbexamples
@@ -43,7 +43,8 b' def _relax_additional_properties(obj):'
43 43 def get_validator(version=None, version_minor=None):
44 44 """Load the JSON schema into a Validator"""
45 45 if version is None:
46 from .current import nbformat as version
46 from .. import current_nbformat
47 version = current_nbformat
47 48
48 49 v = import_item("IPython.nbformat.v%s" % version)
49 50 current_minor = v.nbformat_minor
General Comments 0
You need to be logged in to leave comments. Login now