##// END OF EJS Templates
mv services/notebooks services/contents
MinRK -
Show More
1 NO CONTENT: file renamed from IPython/html/services/notebooks/__init__.py to IPython/html/services/contents/__init__.py
@@ -27,10 +27,10 b' def sort_key(item):'
27 27 #-----------------------------------------------------------------------------
28 28
29 29 class FileNotebookManager(NotebookManager):
30
30
31 31 save_script = Bool(False, config=True,
32 32 help="""Automatically create a Python script when saving the notebook.
33
33
34 34 For easier use of import, %run and %load across notebooks, a
35 35 <notebook-name>.py script will be created next to any
36 36 <notebook-name>.ipynb on each save. This can also be set with the
@@ -38,7 +38,7 b' class FileNotebookManager(NotebookManager):'
38 38 """
39 39 )
40 40 notebook_dir = Unicode(getcwd(), config=True)
41
41
42 42 def _notebook_dir_changed(self, name, old, new):
43 43 """Do a bit of validation of the notebook dir."""
44 44 if not os.path.isabs(new):
@@ -47,19 +47,19 b' class FileNotebookManager(NotebookManager):'
47 47 return
48 48 if not os.path.exists(new) or not os.path.isdir(new):
49 49 raise TraitError("notebook dir %r is not a directory" % new)
50
50
51 51 checkpoint_dir = Unicode('.ipynb_checkpoints', config=True,
52 52 help="""The directory name in which to keep notebook checkpoints
53
53
54 54 This is a path relative to the notebook's own directory.
55
55
56 56 By default, it is .ipynb_checkpoints
57 57 """
58 58 )
59
59
60 60 def _copy(self, src, dest):
61 61 """copy src to dest
62
62
63 63 like shutil.copy2, but log errors in copystat
64 64 """
65 65 shutil.copyfile(src, dest)
@@ -67,7 +67,7 b' class FileNotebookManager(NotebookManager):'
67 67 shutil.copystat(src, dest)
68 68 except OSError as e:
69 69 self.log.debug("copystat on %s failed", dest, exc_info=True)
70
70
71 71 def get_notebook_names(self, path=''):
72 72 """List all notebook names in the notebook dir and path."""
73 73 path = path.strip('/')
@@ -80,13 +80,13 b' class FileNotebookManager(NotebookManager):'
80 80
81 81 def path_exists(self, path):
82 82 """Does the API-style path (directory) actually exist?
83
83
84 84 Parameters
85 85 ----------
86 86 path : string
87 87 The path to check. This is an API path (`/` separated,
88 88 relative to base notebook-dir).
89
89
90 90 Returns
91 91 -------
92 92 exists : bool
@@ -98,18 +98,18 b' class FileNotebookManager(NotebookManager):'
98 98
99 99 def is_hidden(self, path):
100 100 """Does the API style path correspond to a hidden directory or file?
101
101
102 102 Parameters
103 103 ----------
104 104 path : string
105 105 The path to check. This is an API path (`/` separated,
106 106 relative to base notebook-dir).
107
107
108 108 Returns
109 109 -------
110 110 exists : bool
111 111 Whether the path is hidden.
112
112
113 113 """
114 114 path = path.strip('/')
115 115 os_path = self._get_os_path(path=path)
@@ -204,13 +204,13 b' class FileNotebookManager(NotebookManager):'
204 204 def list_notebooks(self, path):
205 205 """Returns a list of dictionaries that are the standard model
206 206 for all notebooks in the relative 'path'.
207
207
208 208 Parameters
209 209 ----------
210 210 path : str
211 211 the URL path that describes the relative path for the
212 212 listed notebooks
213
213
214 214 Returns
215 215 -------
216 216 notebooks : list of dicts
@@ -225,7 +225,7 b' class FileNotebookManager(NotebookManager):'
225 225
226 226 def get_notebook(self, name, path='', content=True):
227 227 """ Takes a path and name for a notebook and returns its model
228
228
229 229 Parameters
230 230 ----------
231 231 name : str
@@ -233,11 +233,11 b' class FileNotebookManager(NotebookManager):'
233 233 path : str
234 234 the URL path that describes the relative path for
235 235 the notebook
236
236
237 237 Returns
238 238 -------
239 239 model : dict
240 the notebook model. If contents=True, returns the 'contents'
240 the notebook model. If contents=True, returns the 'contents'
241 241 dict in the model as well.
242 242 """
243 243 path = path.strip('/')
@@ -284,9 +284,9 b' class FileNotebookManager(NotebookManager):'
284 284 # Save the notebook file
285 285 os_path = self._get_os_path(new_name, new_path)
286 286 nb = current.to_notebook_json(model['content'])
287
287
288 288 self.check_and_sign(nb, new_name, new_path)
289
289
290 290 if 'name' in nb['metadata']:
291 291 nb['metadata']['name'] = u''
292 292 try:
@@ -325,7 +325,7 b' class FileNotebookManager(NotebookManager):'
325 325 os_path = self._get_os_path(name, path)
326 326 if not os.path.isfile(os_path):
327 327 raise web.HTTPError(404, u'Notebook does not exist: %s' % os_path)
328
328
329 329 # clear checkpoints
330 330 for checkpoint in self.list_checkpoints(name, path):
331 331 checkpoint_id = checkpoint['id']
@@ -333,7 +333,7 b' class FileNotebookManager(NotebookManager):'
333 333 if os.path.isfile(cp_path):
334 334 self.log.debug("Unlinking checkpoint %s", cp_path)
335 335 os.unlink(cp_path)
336
336
337 337 self.log.debug("Unlinking notebook %s", os_path)
338 338 os.unlink(os_path)
339 339
@@ -343,7 +343,7 b' class FileNotebookManager(NotebookManager):'
343 343 new_path = new_path.strip('/')
344 344 if new_name == old_name and new_path == old_path:
345 345 return
346
346
347 347 new_os_path = self._get_os_path(new_name, new_path)
348 348 old_os_path = self._get_os_path(old_name, old_path)
349 349
@@ -375,9 +375,9 b' class FileNotebookManager(NotebookManager):'
375 375 # Move the .py script
376 376 if self.save_script:
377 377 shutil.move(old_py_path, new_py_path)
378
378
379 379 # Checkpoint-related utilities
380
380
381 381 def get_checkpoint_path(self, checkpoint_id, name, path=''):
382 382 """find the path to a checkpoint"""
383 383 path = path.strip('/')
@@ -404,9 +404,9 b' class FileNotebookManager(NotebookManager):'
404 404 last_modified = last_modified,
405 405 )
406 406 return info
407
407
408 408 # public checkpoint API
409
409
410 410 def create_checkpoint(self, name, path=''):
411 411 """Create a checkpoint from the current state of a notebook"""
412 412 path = path.strip('/')
@@ -416,13 +416,13 b' class FileNotebookManager(NotebookManager):'
416 416 cp_path = self.get_checkpoint_path(checkpoint_id, name, path)
417 417 self.log.debug("creating checkpoint for notebook %s", name)
418 418 self._copy(nb_path, cp_path)
419
419
420 420 # return the checkpoint info
421 421 return self.get_checkpoint_model(checkpoint_id, name, path)
422
422
423 423 def list_checkpoints(self, name, path=''):
424 424 """list the checkpoints for a given notebook
425
425
426 426 This notebook manager currently only supports one checkpoint per notebook.
427 427 """
428 428 path = path.strip('/')
@@ -432,8 +432,8 b' class FileNotebookManager(NotebookManager):'
432 432 return []
433 433 else:
434 434 return [self.get_checkpoint_model(checkpoint_id, name, path)]
435
436
435
436
437 437 def restore_checkpoint(self, checkpoint_id, name, path=''):
438 438 """restore a notebook to a checkpointed state"""
439 439 path = path.strip('/')
@@ -450,7 +450,7 b' class FileNotebookManager(NotebookManager):'
450 450 current.read(f, u'json')
451 451 self._copy(cp_path, nb_path)
452 452 self.log.debug("copying %s -> %s", cp_path, nb_path)
453
453
454 454 def delete_checkpoint(self, checkpoint_id, name, path=''):
455 455 """delete a notebook's checkpoint"""
456 456 path = path.strip('/')
@@ -461,7 +461,7 b' class FileNotebookManager(NotebookManager):'
461 461 )
462 462 self.log.debug("unlinking %s", cp_path)
463 463 os.unlink(cp_path)
464
464
465 465 def info_string(self):
466 466 return "Serving notebooks from local directory: %s" % self.notebook_dir
467 467
@@ -38,7 +38,7 b' class NotebookHandler(IPythonHandler):'
38 38
39 39 def notebook_location(self, name, path=''):
40 40 """Return the full URL location of a notebook based.
41
41
42 42 Parameters
43 43 ----------
44 44 name : unicode
@@ -57,7 +57,7 b' class NotebookHandler(IPythonHandler):'
57 57 self.set_header('Location', location)
58 58 self.set_header('Last-Modified', model['last_modified'])
59 59 self.finish(json.dumps(model, default=date_default))
60
60
61 61 @web.authenticated
62 62 @json_errors
63 63 def get(self, path='', name=None):
@@ -99,10 +99,10 b' class NotebookHandler(IPythonHandler):'
99 99 raise web.HTTPError(400, u'JSON body missing')
100 100 model = nbm.update_notebook(model, name, path)
101 101 self._finish_model(model)
102
102
103 103 def _copy_notebook(self, copy_from, path, copy_to=None):
104 104 """Copy a notebook in path, optionally specifying the new name.
105
105
106 106 Only support copying within the same directory.
107 107 """
108 108 self.log.info(u"Copying notebook from %s/%s to %s/%s",
@@ -112,23 +112,23 b' class NotebookHandler(IPythonHandler):'
112 112 model = self.notebook_manager.copy_notebook(copy_from, copy_to, path)
113 113 self.set_status(201)
114 114 self._finish_model(model)
115
115
116 116 def _upload_notebook(self, model, path, name=None):
117 117 """Upload a notebook
118
118
119 119 If name specified, create it in path/name.
120 120 """
121 121 self.log.info(u"Uploading notebook to %s/%s", path, name or '')
122 122 if name:
123 123 model['name'] = name
124
124
125 125 model = self.notebook_manager.create_notebook(model, path)
126 126 self.set_status(201)
127 127 self._finish_model(model)
128
128
129 129 def _create_empty_notebook(self, path, name=None):
130 130 """Create an empty notebook in path
131
131
132 132 If name specified, create it in path/name.
133 133 """
134 134 self.log.info(u"Creating new notebook in %s/%s", path, name or '')
@@ -138,7 +138,7 b' class NotebookHandler(IPythonHandler):'
138 138 model = self.notebook_manager.create_notebook(model, path=path)
139 139 self.set_status(201)
140 140 self._finish_model(model)
141
141
142 142 def _save_notebook(self, model, path, name):
143 143 """Save an existing notebook."""
144 144 self.log.info(u"Saving notebook at %s/%s", path, name)
@@ -149,26 +149,26 b' class NotebookHandler(IPythonHandler):'
149 149 else:
150 150 location = False
151 151 self._finish_model(model, location)
152
152
153 153 @web.authenticated
154 154 @json_errors
155 155 def post(self, path='', name=None):
156 156 """Create a new notebook in the specified path.
157
157
158 158 POST creates new notebooks. The server always decides on the notebook name.
159
159
160 160 POST /api/notebooks/path
161 161 New untitled notebook in path. If content specified, upload a
162 162 notebook, otherwise start empty.
163 163 POST /api/notebooks/path?copy=OtherNotebook.ipynb
164 164 New copy of OtherNotebook in path
165 165 """
166
166
167 167 if name is not None:
168 168 raise web.HTTPError(400, "Only POST to directories. Use PUT for full names.")
169
169
170 170 model = self.get_json_body()
171
171
172 172 if model is not None:
173 173 copy_from = model.get('copy_from')
174 174 if copy_from:
@@ -184,10 +184,10 b' class NotebookHandler(IPythonHandler):'
184 184 @json_errors
185 185 def put(self, path='', name=None):
186 186 """Saves the notebook in the location specified by name and path.
187
187
188 188 PUT is very similar to POST, but the requester specifies the name,
189 189 whereas with POST, the server picks the name.
190
190
191 191 PUT /api/notebooks/path/Name.ipynb
192 192 Save notebook at ``path/Name.ipynb``. Notebook structure is specified
193 193 in `content` key of JSON request body. If content is not specified,
@@ -197,7 +197,7 b' class NotebookHandler(IPythonHandler):'
197 197 """
198 198 if name is None:
199 199 raise web.HTTPError(400, "Only PUT to full names. Use POST for directories.")
200
200
201 201 model = self.get_json_body()
202 202 if model:
203 203 copy_from = model.get('copy_from')
@@ -223,9 +223,9 b' class NotebookHandler(IPythonHandler):'
223 223
224 224
225 225 class NotebookCheckpointsHandler(IPythonHandler):
226
226
227 227 SUPPORTED_METHODS = ('GET', 'POST')
228
228
229 229 @web.authenticated
230 230 @json_errors
231 231 def get(self, path='', name=None):
@@ -234,7 +234,7 b' class NotebookCheckpointsHandler(IPythonHandler):'
234 234 checkpoints = nbm.list_checkpoints(name, path)
235 235 data = json.dumps(checkpoints, default=date_default)
236 236 self.finish(data)
237
237
238 238 @web.authenticated
239 239 @json_errors
240 240 def post(self, path='', name=None):
@@ -250,9 +250,9 b' class NotebookCheckpointsHandler(IPythonHandler):'
250 250
251 251
252 252 class ModifyNotebookCheckpointsHandler(IPythonHandler):
253
253
254 254 SUPPORTED_METHODS = ('POST', 'DELETE')
255
255
256 256 @web.authenticated
257 257 @json_errors
258 258 def post(self, path, name, checkpoint_id):
@@ -261,7 +261,7 b' class ModifyNotebookCheckpointsHandler(IPythonHandler):'
261 261 nbm.restore_checkpoint(checkpoint_id, name, path)
262 262 self.set_status(204)
263 263 self.finish()
264
264
265 265 @web.authenticated
266 266 @json_errors
267 267 def delete(self, path, name, checkpoint_id):
@@ -270,7 +270,7 b' class ModifyNotebookCheckpointsHandler(IPythonHandler):'
270 270 nbm.delete_checkpoint(checkpoint_id, name, path)
271 271 self.set_status(204)
272 272 self.finish()
273
273
274 274 #-----------------------------------------------------------------------------
275 275 # URL to handler mappings
276 276 #-----------------------------------------------------------------------------
@@ -285,4 +285,3 b' default_handlers = ['
285 285 (r"/api/notebooks%s" % notebook_path_regex, NotebookHandler),
286 286 (r"/api/notebooks%s" % path_regex, NotebookHandler),
287 287 ]
288
@@ -32,11 +32,11 b' from IPython.utils.traitlets import Instance, Unicode, List'
32 32 class NotebookManager(LoggingConfigurable):
33 33
34 34 filename_ext = Unicode(u'.ipynb')
35
35
36 36 notary = Instance(sign.NotebookNotary)
37 37 def _notary_default(self):
38 38 return sign.NotebookNotary(parent=self)
39
39
40 40 hide_globs = List(Unicode, [u'__pycache__'], config=True, help="""
41 41 Glob patterns to hide in file and directory listings.
42 42 """)
@@ -46,14 +46,14 b' class NotebookManager(LoggingConfigurable):'
46 46
47 47 def path_exists(self, path):
48 48 """Does the API-style path (directory) actually exist?
49
49
50 50 Override this method in subclasses.
51
51
52 52 Parameters
53 53 ----------
54 54 path : string
55 55 The path to check
56
56
57 57 Returns
58 58 -------
59 59 exists : bool
@@ -63,18 +63,18 b' class NotebookManager(LoggingConfigurable):'
63 63
64 64 def is_hidden(self, path):
65 65 """Does the API style path correspond to a hidden directory or file?
66
66
67 67 Parameters
68 68 ----------
69 69 path : string
70 70 The path to check. This is an API path (`/` separated,
71 71 relative to base notebook-dir).
72
72
73 73 Returns
74 74 -------
75 75 exists : bool
76 76 Whether the path is hidden.
77
77
78 78 """
79 79 raise NotImplementedError
80 80
@@ -104,7 +104,7 b' class NotebookManager(LoggingConfigurable):'
104 104 # no longer listed by the notebook web service.
105 105 def get_dir_model(self, name, path=''):
106 106 """Get the directory model given a directory name and its API style path.
107
107
108 108 The keys in the model should be:
109 109 * name
110 110 * path
@@ -145,15 +145,15 b' class NotebookManager(LoggingConfigurable):'
145 145
146 146 def create_checkpoint(self, name, path=''):
147 147 """Create a checkpoint of the current state of a notebook
148
148
149 149 Returns a checkpoint_id for the new checkpoint.
150 150 """
151 151 raise NotImplementedError("must be implemented in a subclass")
152
152
153 153 def list_checkpoints(self, name, path=''):
154 154 """Return a list of checkpoints for a given notebook"""
155 155 return []
156
156
157 157 def restore_checkpoint(self, checkpoint_id, name, path=''):
158 158 """Restore a notebook from one of its checkpoints"""
159 159 raise NotImplementedError("must be implemented in a subclass")
@@ -161,7 +161,7 b' class NotebookManager(LoggingConfigurable):'
161 161 def delete_checkpoint(self, checkpoint_id, name, path=''):
162 162 """delete a checkpoint for a notebook"""
163 163 raise NotImplementedError("must be implemented in a subclass")
164
164
165 165 def info_string(self):
166 166 return "Serving notebooks"
167 167
@@ -174,7 +174,7 b' class NotebookManager(LoggingConfigurable):'
174 174
175 175 def increment_filename(self, basename, path=''):
176 176 """Increment a notebook filename without the .ipynb to make it unique.
177
177
178 178 Parameters
179 179 ----------
180 180 basename : unicode
@@ -206,14 +206,14 b' class NotebookManager(LoggingConfigurable):'
206 206 model['content'] = current.new_notebook(metadata=metadata)
207 207 if 'name' not in model:
208 208 model['name'] = self.increment_filename('Untitled', path)
209
209
210 210 model['path'] = path
211 211 model = self.save_notebook(model, model['name'], model['path'])
212 212 return model
213 213
214 214 def copy_notebook(self, from_name, to_name=None, path=''):
215 215 """Copy an existing notebook and return its new model.
216
216
217 217 If to_name not specified, increment `from_name-Copy#.ipynb`.
218 218 """
219 219 path = path.strip('/')
@@ -224,13 +224,13 b' class NotebookManager(LoggingConfigurable):'
224 224 model['name'] = to_name
225 225 model = self.save_notebook(model, to_name, path)
226 226 return model
227
227
228 228 def log_info(self):
229 229 self.log.info(self.info_string())
230 230
231 231 def trust_notebook(self, name, path=''):
232 232 """Explicitly trust a notebook
233
233
234 234 Parameters
235 235 ----------
236 236 name : string
@@ -243,12 +243,12 b' class NotebookManager(LoggingConfigurable):'
243 243 self.log.warn("Trusting notebook %s/%s", path, name)
244 244 self.notary.mark_cells(nb, True)
245 245 self.save_notebook(model, name, path)
246
246
247 247 def check_and_sign(self, nb, name, path=''):
248 248 """Check for trusted cells, and sign the notebook.
249
249
250 250 Called as a part of saving notebooks.
251
251
252 252 Parameters
253 253 ----------
254 254 nb : dict
@@ -262,12 +262,12 b' class NotebookManager(LoggingConfigurable):'
262 262 self.notary.sign(nb)
263 263 else:
264 264 self.log.warn("Saving untrusted notebook %s/%s", path, name)
265
265
266 266 def mark_trusted_cells(self, nb, name, path=''):
267 267 """Mark cells as trusted if the notebook signature matches.
268
268
269 269 Called as a part of loading notebooks.
270
270
271 271 Parameters
272 272 ----------
273 273 nb : dict
1 NO CONTENT: file renamed from IPython/html/services/notebooks/tests/__init__.py to IPython/html/services/contents/tests/__init__.py
@@ -55,7 +55,7 b' class TestFileNotebookManager(TestCase):'
55 55 path = fm._get_os_path('test.ipynb', '////')
56 56 fs_path = os.path.join(fm.notebook_dir, 'test.ipynb')
57 57 self.assertEqual(path, fs_path)
58
58
59 59 def test_checkpoint_subdir(self):
60 60 subd = u'sub ∂ir'
61 61 cp_name = 'test-cp.ipynb'
@@ -68,10 +68,10 b' class TestFileNotebookManager(TestCase):'
68 68 self.assertNotEqual(cp_dir, cp_subdir)
69 69 self.assertEqual(cp_dir, os.path.join(nbdir, fm.checkpoint_dir, cp_name))
70 70 self.assertEqual(cp_subdir, os.path.join(nbdir, subd, fm.checkpoint_dir, cp_name))
71
71
72 72
73 73 class TestNotebookManager(TestCase):
74
74
75 75 def setUp(self):
76 76 self._temp_dir = TemporaryDirectory()
77 77 self.td = self._temp_dir.name
@@ -79,10 +79,10 b' class TestNotebookManager(TestCase):'
79 79 notebook_dir=self.td,
80 80 log=logging.getLogger()
81 81 )
82
82
83 83 def tearDown(self):
84 84 self._temp_dir.cleanup()
85
85
86 86 def make_dir(self, abs_path, rel_path):
87 87 """make subdirectory, rel_path is the relative path
88 88 to that directory from the location where the server started"""
@@ -91,27 +91,27 b' class TestNotebookManager(TestCase):'
91 91 os.makedirs(os_path)
92 92 except OSError:
93 93 print("Directory already exists: %r" % os_path)
94
94
95 95 def add_code_cell(self, nb):
96 96 output = current.new_output("display_data", output_javascript="alert('hi');")
97 97 cell = current.new_code_cell("print('hi')", outputs=[output])
98 98 if not nb.worksheets:
99 99 nb.worksheets.append(current.new_worksheet())
100 100 nb.worksheets[0].cells.append(cell)
101
101
102 102 def new_notebook(self):
103 103 nbm = self.notebook_manager
104 104 model = nbm.create_notebook()
105 105 name = model['name']
106 106 path = model['path']
107
107
108 108 full_model = nbm.get_notebook(name, path)
109 109 nb = full_model['content']
110 110 self.add_code_cell(nb)
111
111
112 112 nbm.save_notebook(full_model, name, path)
113 113 return nb, name, path
114
114
115 115 def test_create_notebook(self):
116 116 nm = self.notebook_manager
117 117 # Test in root directory
@@ -158,7 +158,7 b' class TestNotebookManager(TestCase):'
158 158 self.assertIn('content', model2)
159 159 self.assertEqual(model2['name'], 'Untitled0.ipynb')
160 160 self.assertEqual(model2['path'], sub_dir.strip('/'))
161
161
162 162 def test_update_notebook(self):
163 163 nm = self.notebook_manager
164 164 # Create a notebook
@@ -184,7 +184,7 b' class TestNotebookManager(TestCase):'
184 184 model = nm.create_notebook(None, sub_dir)
185 185 name = model['name']
186 186 path = model['path']
187
187
188 188 # Change the name in the model for rename
189 189 model['name'] = 'test_in_sub.ipynb'
190 190 model = nm.update_notebook(model, name, path)
@@ -193,7 +193,7 b' class TestNotebookManager(TestCase):'
193 193 self.assertIn('path', model)
194 194 self.assertEqual(model['name'], 'test_in_sub.ipynb')
195 195 self.assertEqual(model['path'], sub_dir.strip('/'))
196
196
197 197 # Make sure the old name is gone
198 198 self.assertRaises(HTTPError, nm.get_notebook, name, path)
199 199
@@ -255,50 +255,50 b' class TestNotebookManager(TestCase):'
255 255 nm = self.notebook_manager
256 256 # Create a notebook
257 257 nb, name, path = self.new_notebook()
258
258
259 259 # Delete the notebook
260 260 nm.delete_notebook(name, path)
261
261
262 262 # Check that a 'get' on the deleted notebook raises and error
263 263 self.assertRaises(HTTPError, nm.get_notebook, name, path)
264
264
265 265 def test_copy_notebook(self):
266 266 nm = self.notebook_manager
267 267 path = u'å b'
268 268 name = u'nb √.ipynb'
269 269 os.mkdir(os.path.join(nm.notebook_dir, path))
270 270 orig = nm.create_notebook({'name' : name}, path=path)
271
271
272 272 # copy with unspecified name
273 273 copy = nm.copy_notebook(name, path=path)
274 274 self.assertEqual(copy['name'], orig['name'].replace('.ipynb', '-Copy0.ipynb'))
275
275
276 276 # copy with specified name
277 277 copy2 = nm.copy_notebook(name, u'copy 2.ipynb', path=path)
278 278 self.assertEqual(copy2['name'], u'copy 2.ipynb')
279
279
280 280 def test_trust_notebook(self):
281 281 nbm = self.notebook_manager
282 282 nb, name, path = self.new_notebook()
283
283
284 284 untrusted = nbm.get_notebook(name, path)['content']
285 285 assert not nbm.notary.check_cells(untrusted)
286
286
287 287 # print(untrusted)
288 288 nbm.trust_notebook(name, path)
289 289 trusted = nbm.get_notebook(name, path)['content']
290 290 # print(trusted)
291 291 assert nbm.notary.check_cells(trusted)
292
292
293 293 def test_mark_trusted_cells(self):
294 294 nbm = self.notebook_manager
295 295 nb, name, path = self.new_notebook()
296
296
297 297 nbm.mark_trusted_cells(nb, name, path)
298 298 for cell in nb.worksheets[0].cells:
299 299 if cell.cell_type == 'code':
300 300 assert not cell.trusted
301
301
302 302 nbm.trust_notebook(name, path)
303 303 nb = nbm.get_notebook(name, path)['content']
304 304 for cell in nb.worksheets[0].cells:
@@ -308,11 +308,11 b' class TestNotebookManager(TestCase):'
308 308 def test_check_and_sign(self):
309 309 nbm = self.notebook_manager
310 310 nb, name, path = self.new_notebook()
311
311
312 312 nbm.mark_trusted_cells(nb, name, path)
313 313 nbm.check_and_sign(nb, name, path)
314 314 assert not nbm.notary.check_signature(nb)
315
315
316 316 nbm.trust_notebook(name, path)
317 317 nb = nbm.get_notebook(name, path)['content']
318 318 nbm.mark_trusted_cells(nb, name, path)
@@ -163,7 +163,7 b' class APITest(NotebookTestBase):'
163 163 expected = [ u'a.ipynb', u'b.ipynb', u'name with spaces.ipynb', u'unicodé.ipynb']
164 164 expected = { normalize('NFC', name) for name in expected }
165 165 self.assertEqual(nbnames, expected)
166
166
167 167 nbs = notebooks_only(self.nb_api.list('ordering').json())
168 168 nbnames = [n['name'] for n in nbs]
169 169 expected = ['A.ipynb', 'b.ipynb', 'C.ipynb']
@@ -344,4 +344,3 b' class APITest(NotebookTestBase):'
344 344 self.assertEqual(r.status_code, 204)
345 345 cps = self.nb_api.get_checkpoints('a.ipynb', 'foo').json()
346 346 self.assertEqual(cps, [])
347
General Comments 0
You need to be logged in to leave comments. Login now