##// END OF EJS Templates
Make sure to pass correct datatype to validate
Jessica B. Hamrick -
Show More
@@ -1,237 +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(s, **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 nbjson = reader_reads(s)
87 nb = reader_reads(nbjson, **kwargs)
88 num_errors = validate(nbjson)
88 nb_current = convert(nb, current_nbformat)
89 num_errors = validate(nb_current)
89 if num_errors > 0:
90 if num_errors > 0:
90 logger.error(
91 logger.error(
91 "Notebook JSON is invalid (%d errors detected)",
92 "Notebook JSON is invalid (%d errors detected)",
92 num_errors)
93 num_errors)
93 return convert(nbjson, current_nbformat)
94 return nb_current
94
95
95
96
96 def writes_json(nb, **kwargs):
97 def writes_json(nb, **kwargs):
97 """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
98 any JSON format errors are detected.
99 any JSON format errors are detected.
99
100
100 """
101 """
101 nbjson = versions[current_nbformat].writes_json(nb, **kwargs)
102 num_errors = validate(nb)
102 num_errors = validate(nbjson)
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)",
106 num_errors)
106 num_errors)
107 nbjson = versions[current_nbformat].writes_json(nb, **kwargs)
107 return nbjson
108 return nbjson
108
109
109
110
110 def reads_py(s, **kwargs):
111 def reads_py(s, **kwargs):
111 """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."""
112 nbf, nbm, s = parse_py(s, **kwargs)
113 nbf, nbm, s = parse_py(s, **kwargs)
113 if nbf in (2, 3):
114 if nbf in (2, 3):
114 nb = versions[nbf].to_notebook_py(s, **kwargs)
115 nb = versions[nbf].to_notebook_py(s, **kwargs)
115 else:
116 else:
116 raise NBFormatError('Unsupported PY nbformat version: %i' % nbf)
117 raise NBFormatError('Unsupported PY nbformat version: %i' % nbf)
117 return nb
118 return nb
118
119
119
120
120 def writes_py(nb, **kwargs):
121 def writes_py(nb, **kwargs):
121 # nbformat 3 is the latest format that supports py
122 # nbformat 3 is the latest format that supports py
122 return versions[3].writes_py(nb, **kwargs)
123 return versions[3].writes_py(nb, **kwargs)
123
124
124
125
125 # High level API
126 # High level API
126
127
127
128
128 def reads(s, format, **kwargs):
129 def reads(s, format, **kwargs):
129 """Read a notebook from a string and return the NotebookNode object.
130 """Read a notebook from a string and return the NotebookNode object.
130
131
131 This function properly handles notebooks of any version. The notebook
132 This function properly handles notebooks of any version. The notebook
132 returned will always be in the current version's format.
133 returned will always be in the current version's format.
133
134
134 Parameters
135 Parameters
135 ----------
136 ----------
136 s : unicode
137 s : unicode
137 The raw unicode string to read the notebook from.
138 The raw unicode string to read the notebook from.
138 format : (u'json', u'ipynb', u'py')
139 format : (u'json', u'ipynb', u'py')
139 The format that the string is in.
140 The format that the string is in.
140
141
141 Returns
142 Returns
142 -------
143 -------
143 nb : NotebookNode
144 nb : NotebookNode
144 The notebook that was read.
145 The notebook that was read.
145 """
146 """
146 format = unicode_type(format)
147 format = unicode_type(format)
147 if format == u'json' or format == u'ipynb':
148 if format == u'json' or format == u'ipynb':
148 return reads_json(s, **kwargs)
149 return reads_json(s, **kwargs)
149 elif format == u'py':
150 elif format == u'py':
150 return reads_py(s, **kwargs)
151 return reads_py(s, **kwargs)
151 else:
152 else:
152 raise NBFormatError('Unsupported format: %s' % format)
153 raise NBFormatError('Unsupported format: %s' % format)
153
154
154
155
155 def writes(nb, format, **kwargs):
156 def writes(nb, format, **kwargs):
156 """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.
157
158
158 This function always writes the notebook in the current nbformat version.
159 This function always writes the notebook in the current nbformat version.
159
160
160 Parameters
161 Parameters
161 ----------
162 ----------
162 nb : NotebookNode
163 nb : NotebookNode
163 The notebook to write.
164 The notebook to write.
164 format : (u'json', u'ipynb', u'py')
165 format : (u'json', u'ipynb', u'py')
165 The format to write the notebook in.
166 The format to write the notebook in.
166
167
167 Returns
168 Returns
168 -------
169 -------
169 s : unicode
170 s : unicode
170 The notebook string.
171 The notebook string.
171 """
172 """
172 format = unicode_type(format)
173 format = unicode_type(format)
173 if format == u'json' or format == u'ipynb':
174 if format == u'json' or format == u'ipynb':
174 return writes_json(nb, **kwargs)
175 return writes_json(nb, **kwargs)
175 elif format == u'py':
176 elif format == u'py':
176 return writes_py(nb, **kwargs)
177 return writes_py(nb, **kwargs)
177 else:
178 else:
178 raise NBFormatError('Unsupported format: %s' % format)
179 raise NBFormatError('Unsupported format: %s' % format)
179
180
180
181
181 def read(fp, format, **kwargs):
182 def read(fp, format, **kwargs):
182 """Read a notebook from a file and return the NotebookNode object.
183 """Read a notebook from a file and return the NotebookNode object.
183
184
184 This function properly handles notebooks of any version. The notebook
185 This function properly handles notebooks of any version. The notebook
185 returned will always be in the current version's format.
186 returned will always be in the current version's format.
186
187
187 Parameters
188 Parameters
188 ----------
189 ----------
189 fp : file
190 fp : file
190 Any file-like object with a read method.
191 Any file-like object with a read method.
191 format : (u'json', u'ipynb', u'py')
192 format : (u'json', u'ipynb', u'py')
192 The format that the string is in.
193 The format that the string is in.
193
194
194 Returns
195 Returns
195 -------
196 -------
196 nb : NotebookNode
197 nb : NotebookNode
197 The notebook that was read.
198 The notebook that was read.
198 """
199 """
199 return reads(fp.read(), format, **kwargs)
200 return reads(fp.read(), format, **kwargs)
200
201
201
202
202 def write(nb, fp, format, **kwargs):
203 def write(nb, fp, format, **kwargs):
203 """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.
204
205
205 This function always writes the notebook in the current nbformat version.
206 This function always writes the notebook in the current nbformat version.
206
207
207 Parameters
208 Parameters
208 ----------
209 ----------
209 nb : NotebookNode
210 nb : NotebookNode
210 The notebook to write.
211 The notebook to write.
211 fp : file
212 fp : file
212 Any file-like object with a write method.
213 Any file-like object with a write method.
213 format : (u'json', u'ipynb', u'py')
214 format : (u'json', u'ipynb', u'py')
214 The format to write the notebook in.
215 The format to write the notebook in.
215
216
216 Returns
217 Returns
217 -------
218 -------
218 s : unicode
219 s : unicode
219 The notebook string.
220 The notebook string.
220 """
221 """
221 return fp.write(writes(nb, format, **kwargs))
222 return fp.write(writes(nb, format, **kwargs))
222
223
223 def _convert_to_metadata():
224 def _convert_to_metadata():
224 """Convert to a notebook having notebook metadata."""
225 """Convert to a notebook having notebook metadata."""
225 import glob
226 import glob
226 for fname in glob.glob('*.ipynb'):
227 for fname in glob.glob('*.ipynb'):
227 print('Converting file:',fname)
228 print('Converting file:',fname)
228 with open(fname,'r') as f:
229 with open(fname,'r') as f:
229 nb = read(f,u'json')
230 nb = read(f,u'json')
230 md = new_metadata()
231 md = new_metadata()
231 if u'name' in nb:
232 if u'name' in nb:
232 md.name = nb.name
233 md.name = nb.name
233 del nb[u'name']
234 del nb[u'name']
234 nb.metadata = md
235 nb.metadata = md
235 with open(fname,'w') as f:
236 with open(fname,'w') as f:
236 write(nb, f, u'json')
237 write(nb, f, u'json')
237
238
General Comments 0
You need to be logged in to leave comments. Login now