##// END OF EJS Templates
Review and refactoring of notebooks web service.
Brian E. Granger -
Show More
@@ -72,23 +72,16 b' class FileNotebookManager(NotebookManager):'
72 72 os.mkdir(new)
73 73 except:
74 74 raise TraitError("Couldn't create checkpoint dir %r" % new)
75
76 filename_ext = Unicode(u'.ipynb')
77 75
78 def get_notebook_names(self, path):
79 """List all notebook names in the notebook dir."""
76 def get_notebook_names(self, path='/'):
77 """List all notebook names in the notebook dir and path."""
80 78 names = glob.glob(self.get_os_path('*'+self.filename_ext, path))
81 79 names = [os.path.basename(name)
82 80 for name in names]
83 81 return names
84 82
85 83 def increment_filename(self, basename, path='/'):
86 """Return a non-used filename of the form basename<int>.
87
88 This searches through the filenames (basename0, basename1, ...)
89 until is find one that is not already being used. It is used to
90 create Untitled and Copy names that are unique.
91 """
84 """Return a non-used filename of the form basename<int>."""
92 85 i = 0
93 86 while True:
94 87 name = u'%s%i.ipynb' % (basename,i)
@@ -99,7 +92,7 b' class FileNotebookManager(NotebookManager):'
99 92 i = i+1
100 93 return name
101 94
102 def notebook_exists(self, name, path):
95 def notebook_exists(self, name, path='/'):
103 96 """Returns a True if the notebook exists. Else, returns False.
104 97
105 98 Parameters
@@ -113,7 +106,7 b' class FileNotebookManager(NotebookManager):'
113 106 -------
114 107 bool
115 108 """
116 path = self.get_os_path(name, path)
109 path = self.get_os_path(name, path='/')
117 110 return os.path.isfile(path)
118 111
119 112 def list_notebooks(self, path):
@@ -165,15 +158,13 b' class FileNotebookManager(NotebookManager):'
165 158 model ={}
166 159 model['name'] = name
167 160 model['path'] = path
168 model['last_modified'] = last_modified.ctime()
161 model['last_modified'] = last_modified
169 162 if content is True:
170 with open(os_path,'r') as f:
171 s = f.read()
163 with open(os_path, 'r') as f:
172 164 try:
173 # v1 and v2 and json in the .ipynb files.
174 nb = current.reads(s, u'json')
175 except ValueError as e:
176 raise web.HTTPError(400, u"Unreadable Notebook: %s" % e)
165 nb = current.read(f, u'json')
166 except Exception as e:
167 raise web.HTTPError(400, u"Unreadable Notebook: %s %s" % (os_path, e))
177 168 model['content'] = nb
178 169 return model
179 170
@@ -190,27 +181,26 b' class FileNotebookManager(NotebookManager):'
190 181 self.rename_notebook(name, path, new_name, new_path)
191 182
192 183 # Save the notebook file
193 ospath = self.get_os_path(new_name, new_path)
194 nb = model['content']
184 os_path = self.get_os_path(new_name, new_path)
185 nb = current.to_notebook_json(model['content'])
195 186 if 'name' in nb['metadata']:
196 187 nb['metadata']['name'] = u''
197 188 try:
198 self.log.debug("Autosaving notebook %s", ospath)
199 with open(ospath,'w') as f:
189 self.log.debug("Autosaving notebook %s", os_path)
190 with open(os_path, 'w') as f:
200 191 current.write(nb, f, u'json')
201 192 except Exception as e:
202 #raise web.HTTPError(400, u'Unexpected error while autosaving notebook: %s' % ospath)
203 raise e
193 raise web.HTTPError(400, u'Unexpected error while autosaving notebook: %s %s' % (os_path, e))
204 194
205 195 # Save .py script as well
206 196 if self.save_script:
207 pypath = os.path.splitext(path)[0] + '.py'
208 self.log.debug("Writing script %s", pypath)
197 py_path = os.path.splitext(os_path)[0] + '.py'
198 self.log.debug("Writing script %s", py_path)
209 199 try:
210 with io.open(pypath, 'w', encoding='utf-8') as f:
200 with io.open(py_path, 'w', encoding='utf-8') as f:
211 201 current.write(model, f, u'py')
212 202 except Exception as e:
213 raise web.HTTPError(400, u'Unexpected error while saving notebook as script: %s' % pypath)
203 raise web.HTTPError(400, u'Unexpected error while saving notebook as script: %s %s' % (py_path, e))
214 204
215 205 model = self.get_notebook_model(name, path, content=False)
216 206 return model
@@ -226,15 +216,14 b' class FileNotebookManager(NotebookManager):'
226 216
227 217 def delete_notebook_model(self, name, path='/'):
228 218 """Delete notebook by name and path."""
229 nb_path = self.get_os_path(name, path)
230 if not os.path.isfile(nb_path):
231 raise web.HTTPError(404, u'Notebook does not exist: %s' % nb_path)
219 os_path = self.get_os_path(name, path)
220 if not os.path.isfile(os_path):
221 raise web.HTTPError(404, u'Notebook does not exist: %s' % os_path)
232 222
233 223 # clear checkpoints
234 for checkpoint in self.list_checkpoints(name):
224 for checkpoint in self.list_checkpoints(name, path):
235 225 checkpoint_id = checkpoint['checkpoint_id']
236 226 cp_path = self.get_checkpoint_path(checkpoint_id, name, path)
237 self.log.debug(cp_path)
238 227 if os.path.isfile(cp_path):
239 228 self.log.debug("Unlinking checkpoint %s", cp_path)
240 229 os.unlink(cp_path)
@@ -247,23 +236,23 b' class FileNotebookManager(NotebookManager):'
247 236 if new_name == old_name and new_path == old_path:
248 237 return
249 238
250 new_full_path = self.get_os_path(new_name, new_path)
251 old_full_path = self.get_os_path(old_name, old_path)
239 new_os_path = self.get_os_path(new_name, new_path)
240 old_os_path = self.get_os_path(old_name, old_path)
252 241
253 242 # Should we proceed with the move?
254 if os.path.isfile(new_full_path):
255 raise web.HTTPError(409, u'Notebook with name already exists: ' % new_full_path)
243 if os.path.isfile(new_os_path):
244 raise web.HTTPError(409, u'Notebook with name already exists: ' % new_os_path)
256 245 if self.save_script:
257 old_pypath = os.path.splitext(old_full_path)[0] + '.py'
258 new_pypath = os.path.splitext(new_full_path)[0] + '.py'
259 if os.path.isfile(new_pypath):
260 raise web.HTTPError(409, u'Python script with name already exists: %s' % new_pypath)
246 old_py_path = os.path.splitext(old_os_path)[0] + '.py'
247 new_py_path = os.path.splitext(new_os_path)[0] + '.py'
248 if os.path.isfile(new_py_path):
249 raise web.HTTPError(409, u'Python script with name already exists: %s' % new_py_path)
261 250
262 251 # Move the notebook file
263 252 try:
264 os.rename(old_full_path, new_full_path)
265 except:
266 raise web.HTTPError(400, u'Unknown error renaming notebook: %s' % old_full_path)
253 os.rename(old_os_path, new_os_path)
254 except Exception as e:
255 raise web.HTTPError(400, u'Unknown error renaming notebook: %s %s' % (old_os_path, e))
267 256
268 257 # Move the checkpoints
269 258 old_checkpoints = self.list_checkpoints(old_name, old_path)
@@ -277,7 +266,7 b' class FileNotebookManager(NotebookManager):'
277 266
278 267 # Move the .py script
279 268 if self.save_script:
280 os.rename(old_pypath, new_pypath)
269 os.rename(old_py_path, new_py_path)
281 270
282 271 # Checkpoint-related utilities
283 272
@@ -352,7 +341,7 b' class FileNotebookManager(NotebookManager):'
352 341 cp_path = self.get_checkpoint_path(checkpoint_id, name, path)
353 342 if not os.path.isfile(cp_path):
354 343 raise web.HTTPError(404,
355 u'Notebook checkpoint does not exist: %s-%s' % (name, checkpoint_id)
344 u'Notebook checkpoint does not exist: %s%s-%s' % (path, name, checkpoint_id)
356 345 )
357 346 self.log.debug("unlinking %s", cp_path)
358 347 os.unlink(cp_path)
@@ -221,4 +221,4 b' class NotebookManager(LoggingConfigurable):'
221 221 self.log.info(self.info_string())
222 222
223 223 def info_string(self):
224 return "Serving notebooks" No newline at end of file
224 return "Serving notebooks"
@@ -29,7 +29,7 b' from IPython.nbformat.v3 import ('
29 29 NotebookNode,
30 30 new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet,
31 31 parse_filename, new_metadata, new_author, new_heading_cell, nbformat,
32 nbformat_minor,
32 nbformat_minor, to_notebook_json
33 33 )
34 34
35 35 #-----------------------------------------------------------------------------
General Comments 0
You need to be logged in to leave comments. Login now