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