##// END OF EJS Templates
Distinguish errors during read/write
Jessica B. Hamrick -
Show More
@@ -1,238 +1,238 b''
1 """The official API for working with notebooks in the current format version.
1 """The official API for working with notebooks in the current format version.
2
2
3 Authors:
3 Authors:
4
4
5 * Brian Granger
5 * Brian Granger
6 * Jonathan Frederic
6 * Jonathan Frederic
7 """
7 """
8
8
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2008-2011 The IPython Development Team
10 # Copyright (C) 2008-2011 The IPython Development Team
11 #
11 #
12 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Imports
17 # Imports
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 from __future__ import print_function
20 from __future__ import print_function
21
21
22 from xml.etree import ElementTree as ET
22 from xml.etree import ElementTree as ET
23 import re
23 import re
24
24
25 from IPython.utils.py3compat import unicode_type
25 from IPython.utils.py3compat import unicode_type
26
26
27 from IPython.nbformat.v3 import (
27 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, nbformat_schema, 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
38 from .validator import validate
39
39
40 import logging
40 import logging
41 logger = logging.getLogger('NotebookApp')
41 logger = logging.getLogger('NotebookApp')
42
42
43 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
44 # Code
44 # Code
45 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
46
46
47 current_nbformat = nbformat
47 current_nbformat = nbformat
48 current_nbformat_minor = nbformat_minor
48 current_nbformat_minor = nbformat_minor
49 current_nbformat_module = _v_latest.__name__
49 current_nbformat_module = _v_latest.__name__
50
50
51
51
52 def docstring_nbformat_mod(func):
52 def docstring_nbformat_mod(func):
53 """Decorator for docstrings referring to classes/functions accessed through
53 """Decorator for docstrings referring to classes/functions accessed through
54 nbformat.current.
54 nbformat.current.
55
55
56 Put {nbformat_mod} in the docstring in place of 'IPython.nbformat.v3'.
56 Put {nbformat_mod} in the docstring in place of 'IPython.nbformat.v3'.
57 """
57 """
58 func.__doc__ = func.__doc__.format(nbformat_mod=current_nbformat_module)
58 func.__doc__ = func.__doc__.format(nbformat_mod=current_nbformat_module)
59 return func
59 return func
60
60
61
61
62 class NBFormatError(ValueError):
62 class NBFormatError(ValueError):
63 pass
63 pass
64
64
65
65
66 def parse_py(s, **kwargs):
66 def parse_py(s, **kwargs):
67 """Parse a string into a (nbformat, string) tuple."""
67 """Parse a string into a (nbformat, string) tuple."""
68 nbf = current_nbformat
68 nbf = current_nbformat
69 nbm = current_nbformat_minor
69 nbm = current_nbformat_minor
70
70
71 pattern = r'# <nbformat>(?P<nbformat>\d+[\.\d+]*)</nbformat>'
71 pattern = r'# <nbformat>(?P<nbformat>\d+[\.\d+]*)</nbformat>'
72 m = re.search(pattern,s)
72 m = re.search(pattern,s)
73 if m is not None:
73 if m is not None:
74 digits = m.group('nbformat').split('.')
74 digits = m.group('nbformat').split('.')
75 nbf = int(digits[0])
75 nbf = int(digits[0])
76 if len(digits) > 1:
76 if len(digits) > 1:
77 nbm = int(digits[1])
77 nbm = int(digits[1])
78
78
79 return nbf, nbm, s
79 return nbf, nbm, s
80
80
81
81
82 def reads_json(nbjson, **kwargs):
82 def reads_json(nbjson, **kwargs):
83 """Read a JSON notebook from a string and return the NotebookNode
83 """Read a JSON notebook from a string and return the NotebookNode
84 object. Report if any JSON format errors are detected.
84 object. Report if any JSON format errors are detected.
85
85
86 """
86 """
87 nb = reader_reads(nbjson, **kwargs)
87 nb = reader_reads(nbjson, **kwargs)
88 nb_current = convert(nb, current_nbformat)
88 nb_current = convert(nb, current_nbformat)
89 num_errors = validate(nb_current)
89 num_errors = validate(nb_current)
90 if num_errors > 0:
90 if num_errors > 0:
91 logger.error(
91 logger.error(
92 "Notebook JSON is invalid (%d errors detected)",
92 "Notebook JSON is invalid (%d errors detected during read)",
93 num_errors)
93 num_errors)
94 return nb_current
94 return nb_current
95
95
96
96
97 def writes_json(nb, **kwargs):
97 def writes_json(nb, **kwargs):
98 """Take a NotebookNode object and write out a JSON string. Report if
98 """Take a NotebookNode object and write out a JSON string. Report if
99 any JSON format errors are detected.
99 any JSON format errors are detected.
100
100
101 """
101 """
102 num_errors = validate(nb)
102 num_errors = validate(nb)
103 if num_errors > 0:
103 if num_errors > 0:
104 logger.error(
104 logger.error(
105 "Notebook JSON is invalid (%d errors detected)",
105 "Notebook JSON is invalid (%d errors detected during write)",
106 num_errors)
106 num_errors)
107 nbjson = versions[current_nbformat].writes_json(nb, **kwargs)
107 nbjson = versions[current_nbformat].writes_json(nb, **kwargs)
108 return nbjson
108 return nbjson
109
109
110
110
111 def reads_py(s, **kwargs):
111 def reads_py(s, **kwargs):
112 """Read a .py notebook from a string and return the NotebookNode object."""
112 """Read a .py notebook from a string and return the NotebookNode object."""
113 nbf, nbm, s = parse_py(s, **kwargs)
113 nbf, nbm, s = parse_py(s, **kwargs)
114 if nbf in (2, 3):
114 if nbf in (2, 3):
115 nb = versions[nbf].to_notebook_py(s, **kwargs)
115 nb = versions[nbf].to_notebook_py(s, **kwargs)
116 else:
116 else:
117 raise NBFormatError('Unsupported PY nbformat version: %i' % nbf)
117 raise NBFormatError('Unsupported PY nbformat version: %i' % nbf)
118 return nb
118 return nb
119
119
120
120
121 def writes_py(nb, **kwargs):
121 def writes_py(nb, **kwargs):
122 # nbformat 3 is the latest format that supports py
122 # nbformat 3 is the latest format that supports py
123 return versions[3].writes_py(nb, **kwargs)
123 return versions[3].writes_py(nb, **kwargs)
124
124
125
125
126 # High level API
126 # High level API
127
127
128
128
129 def reads(s, format, **kwargs):
129 def reads(s, format, **kwargs):
130 """Read a notebook from a string and return the NotebookNode object.
130 """Read a notebook from a string and return the NotebookNode object.
131
131
132 This function properly handles notebooks of any version. The notebook
132 This function properly handles notebooks of any version. The notebook
133 returned will always be in the current version's format.
133 returned will always be in the current version's format.
134
134
135 Parameters
135 Parameters
136 ----------
136 ----------
137 s : unicode
137 s : unicode
138 The raw unicode string to read the notebook from.
138 The raw unicode string to read the notebook from.
139 format : (u'json', u'ipynb', u'py')
139 format : (u'json', u'ipynb', u'py')
140 The format that the string is in.
140 The format that the string is in.
141
141
142 Returns
142 Returns
143 -------
143 -------
144 nb : NotebookNode
144 nb : NotebookNode
145 The notebook that was read.
145 The notebook that was read.
146 """
146 """
147 format = unicode_type(format)
147 format = unicode_type(format)
148 if format == u'json' or format == u'ipynb':
148 if format == u'json' or format == u'ipynb':
149 return reads_json(s, **kwargs)
149 return reads_json(s, **kwargs)
150 elif format == u'py':
150 elif format == u'py':
151 return reads_py(s, **kwargs)
151 return reads_py(s, **kwargs)
152 else:
152 else:
153 raise NBFormatError('Unsupported format: %s' % format)
153 raise NBFormatError('Unsupported format: %s' % format)
154
154
155
155
156 def writes(nb, format, **kwargs):
156 def writes(nb, format, **kwargs):
157 """Write a notebook to a string in a given format in the current nbformat version.
157 """Write a notebook to a string in a given format in the current nbformat version.
158
158
159 This function always writes the notebook in the current nbformat version.
159 This function always writes the notebook in the current nbformat version.
160
160
161 Parameters
161 Parameters
162 ----------
162 ----------
163 nb : NotebookNode
163 nb : NotebookNode
164 The notebook to write.
164 The notebook to write.
165 format : (u'json', u'ipynb', u'py')
165 format : (u'json', u'ipynb', u'py')
166 The format to write the notebook in.
166 The format to write the notebook in.
167
167
168 Returns
168 Returns
169 -------
169 -------
170 s : unicode
170 s : unicode
171 The notebook string.
171 The notebook string.
172 """
172 """
173 format = unicode_type(format)
173 format = unicode_type(format)
174 if format == u'json' or format == u'ipynb':
174 if format == u'json' or format == u'ipynb':
175 return writes_json(nb, **kwargs)
175 return writes_json(nb, **kwargs)
176 elif format == u'py':
176 elif format == u'py':
177 return writes_py(nb, **kwargs)
177 return writes_py(nb, **kwargs)
178 else:
178 else:
179 raise NBFormatError('Unsupported format: %s' % format)
179 raise NBFormatError('Unsupported format: %s' % format)
180
180
181
181
182 def read(fp, format, **kwargs):
182 def read(fp, format, **kwargs):
183 """Read a notebook from a file and return the NotebookNode object.
183 """Read a notebook from a file and return the NotebookNode object.
184
184
185 This function properly handles notebooks of any version. The notebook
185 This function properly handles notebooks of any version. The notebook
186 returned will always be in the current version's format.
186 returned will always be in the current version's format.
187
187
188 Parameters
188 Parameters
189 ----------
189 ----------
190 fp : file
190 fp : file
191 Any file-like object with a read method.
191 Any file-like object with a read method.
192 format : (u'json', u'ipynb', u'py')
192 format : (u'json', u'ipynb', u'py')
193 The format that the string is in.
193 The format that the string is in.
194
194
195 Returns
195 Returns
196 -------
196 -------
197 nb : NotebookNode
197 nb : NotebookNode
198 The notebook that was read.
198 The notebook that was read.
199 """
199 """
200 return reads(fp.read(), format, **kwargs)
200 return reads(fp.read(), format, **kwargs)
201
201
202
202
203 def write(nb, fp, format, **kwargs):
203 def write(nb, fp, format, **kwargs):
204 """Write a notebook to a file in a given format in the current nbformat version.
204 """Write a notebook to a file in a given format in the current nbformat version.
205
205
206 This function always writes the notebook in the current nbformat version.
206 This function always writes the notebook in the current nbformat version.
207
207
208 Parameters
208 Parameters
209 ----------
209 ----------
210 nb : NotebookNode
210 nb : NotebookNode
211 The notebook to write.
211 The notebook to write.
212 fp : file
212 fp : file
213 Any file-like object with a write method.
213 Any file-like object with a write method.
214 format : (u'json', u'ipynb', u'py')
214 format : (u'json', u'ipynb', u'py')
215 The format to write the notebook in.
215 The format to write the notebook in.
216
216
217 Returns
217 Returns
218 -------
218 -------
219 s : unicode
219 s : unicode
220 The notebook string.
220 The notebook string.
221 """
221 """
222 return fp.write(writes(nb, format, **kwargs))
222 return fp.write(writes(nb, format, **kwargs))
223
223
224 def _convert_to_metadata():
224 def _convert_to_metadata():
225 """Convert to a notebook having notebook metadata."""
225 """Convert to a notebook having notebook metadata."""
226 import glob
226 import glob
227 for fname in glob.glob('*.ipynb'):
227 for fname in glob.glob('*.ipynb'):
228 print('Converting file:',fname)
228 print('Converting file:',fname)
229 with open(fname,'r') as f:
229 with open(fname,'r') as f:
230 nb = read(f,u'json')
230 nb = read(f,u'json')
231 md = new_metadata()
231 md = new_metadata()
232 if u'name' in nb:
232 if u'name' in nb:
233 md.name = nb.name
233 md.name = nb.name
234 del nb[u'name']
234 del nb[u'name']
235 nb.metadata = md
235 nb.metadata = md
236 with open(fname,'w') as f:
236 with open(fname,'w') as f:
237 write(nb, f, u'json')
237 write(nb, f, u'json')
238
238
General Comments 0
You need to be logged in to leave comments. Login now