def test_save(self): resp = self.api.read('a.ipynb', 'foo') nbcontent = json.loads(resp.text)['content'] nb = from_dict(nbcontent) nb.cells.append(new_markdown_cell(u'Created by test ³')) nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb, 'type': 'notebook'} resp = self.api.save('a.ipynb', path='foo', body=json.dumps(nbmodel)) nbfile = pjoin(self.notebook_dir.name, 'foo', 'a.ipynb') with io.open(nbfile, 'r', encoding='utf-8') as f: newnb = read(f, as_version=4) self.assertEqual(newnb.cells[0].source, u'Created by test ³') nbcontent = self.api.read('a.ipynb', 'foo').json()['content'] newnb = from_dict(nbcontent) self.assertEqual(newnb.cells[0].source, u'Created by test ³') # Save and rename nbmodel= {'name': 'a2.ipynb', 'path':'foo/bar', 'content': nb, 'type': 'notebook'} resp = self.api.save('a.ipynb', path='foo', body=json.dumps(nbmodel)) saved = resp.json() self.assertEqual(saved['name'], 'a2.ipynb') self.assertEqual(saved['path'], 'foo/bar') assert os.path.isfile(pjoin(self.notebook_dir.name,'foo','bar','a2.ipynb')) assert not os.path.isfile(pjoin(self.notebook_dir.name, 'foo', 'a.ipynb')) with assert_http_error(404): self.api.read('a.ipynb', 'foo')
def test_save(self): resp = self.api.read('foo/a.ipynb') nbcontent = json.loads(resp.text)['content'] nb = from_dict(nbcontent) nb.cells.append(new_markdown_cell(u'Created by test ³')) nbmodel = {'content': nb, 'type': 'notebook'} resp = self.api.save('foo/a.ipynb', body=json.dumps(nbmodel)) nbcontent = self.api.read('foo/a.ipynb').json()['content'] newnb = from_dict(nbcontent) self.assertEqual(newnb.cells[0].source, u'Created by test ³')
def test_save(self): resp = self.api.read('foo/a.ipynb') nbcontent = json.loads(resp.text)['content'] nb = from_dict(nbcontent) nb.cells.append(new_markdown_cell(u'Created by test ³')) nbmodel= {'content': nb, 'type': 'notebook'} resp = self.api.save('foo/a.ipynb', body=json.dumps(nbmodel)) nbcontent = self.api.read('foo/a.ipynb').json()['content'] newnb = from_dict(nbcontent) self.assertEqual(newnb.cells[0].source, u'Created by test ³')
def rename(self, old_path, new_path): """ Renames a notebook """ old_path = old_path.strip('/') new_path = new_path.strip('/') fs = self._get_fs_instance() if new_path == old_path: return if self.file_exists(new_path): raise web.HTTPError(409, u'Notebook already exists: %s' % new_path) # Move the file try: grid_file = fs.get_version(old_path)._id nb = nbformat.from_dict( json.loads(fs.get(grid_file).read())) fs.put(json.dumps(nb), filename=new_path) self.delete(old_path) except Exception as e: raise web.HTTPError(500, u'Unknown error renaming file: %s %s' % ( old_path, e)) # Move the checkpoints spec = { 'path': old_path, } modify = { '$set': { 'path': new_path, } } self._connect_collection( self.checkpoint_collection).update(spec, modify, multi=True)
def test_checkpoints_follow_file(self): # Read initial file state orig = self.api.read('foo/a.ipynb') # Create a checkpoint of initial state r = self.api.new_checkpoint('foo/a.ipynb') cp1 = r.json() # Modify file and save nbcontent = json.loads(orig.text)['content'] nb = from_dict(nbcontent) hcell = new_markdown_cell('Created by test') nb.cells.append(hcell) nbmodel = {'content': nb, 'type': 'notebook'} self.api.save('foo/a.ipynb', body=json.dumps(nbmodel)) # Rename the file. self.api.rename('foo/a.ipynb', 'foo/z.ipynb') # Looking for checkpoints in the old location should yield no results. self.assertEqual(self.api.get_checkpoints('foo/a.ipynb').json(), []) # Looking for checkpoints in the new location should work. cps = self.api.get_checkpoints('foo/z.ipynb').json() self.assertEqual(cps, [cp1]) # Delete the file. The checkpoint should be deleted as well. self.api.delete('foo/z.ipynb') cps = self.api.get_checkpoints('foo/z.ipynb').json() self.assertEqual(cps, [])
def rename(self, old_path, new_path): """ Renames a notebook """ old_path = old_path.strip('/') new_path = new_path.strip('/') fs = self._get_fs_instance() if new_path == old_path: return if self.file_exists(new_path): raise web.HTTPError(409, u'Notebook already exists: %s' % new_path) # Move the file try: grid_file = fs.get_version(old_path)._id nb = nbformat.from_dict(json.loads(fs.get(grid_file).read())) fs.put(json.dumps(nb), filename=new_path) self.delete(old_path) except Exception as e: raise web.HTTPError( 500, u'Unknown error renaming file: %s %s' % (old_path, e)) # Move the checkpoints spec = { 'path': old_path, } modify = { '$set': { 'path': new_path, } } self._connect_collection(self.checkpoint_collection).update(spec, modify, multi=True)
def test_save(self): resp = self.api.read('foo/a.ipynb') nbcontent = json.loads(resp.text)['content'] nb = from_dict(nbcontent) nb.cells.append(new_markdown_cell(u'Created by test ³')) nbmodel = {'content': nb, 'type': 'notebook'} resp = self.api.save('foo/a.ipynb', body=json.dumps(nbmodel)) nbfile = pjoin(self.notebook_dir.name, 'foo', 'a.ipynb') with io.open(nbfile, 'r', encoding='utf-8') as f: newnb = read(f, as_version=4) self.assertEqual(newnb.cells[0].source, u'Created by test ³') nbcontent = self.api.read('foo/a.ipynb').json()['content'] newnb = from_dict(nbcontent) self.assertEqual(newnb.cells[0].source, u'Created by test ³')
def test_save(self): resp = self.api.read("foo/a.ipynb") nbcontent = json.loads(resp.text)["content"] nb = from_dict(nbcontent) nb.cells.append(new_markdown_cell(u"Created by test ³")) nbmodel = {"content": nb, "type": "notebook"} resp = self.api.save("foo/a.ipynb", body=json.dumps(nbmodel)) nbfile = pjoin(self.notebook_dir.name, "foo", "a.ipynb") with io.open(nbfile, "r", encoding="utf-8") as f: newnb = read(f, as_version=4) self.assertEqual(newnb.cells[0].source, u"Created by test ³") nbcontent = self.api.read("foo/a.ipynb").json()["content"] newnb = from_dict(nbcontent) self.assertEqual(newnb.cells[0].source, u"Created by test ³")
def _save_notebook(self, os_path, model, path=''): """save a notebook file""" # Save the notebook file nb = nbformat.from_dict(model['content']) self.check_and_sign(nb, path) with self.atomic_writing(os_path, encoding='utf-8') as f: nbformat.write(nb, f, version=nbformat.NO_CONVERT)
def test_save(self): resp = self.api.read('foo/a.ipynb') nbcontent = json.loads(resp.text)['content'] nb = from_dict(nbcontent) nb.cells.append(new_markdown_cell(u'Created by test ³')) nbmodel= {'content': nb, 'type': 'notebook'} resp = self.api.save('foo/a.ipynb', body=json.dumps(nbmodel)) nbfile = pjoin(self.notebook_dir.name, 'foo', 'a.ipynb') with io.open(nbfile, 'r', encoding='utf-8') as f: newnb = read(f, as_version=4) self.assertEqual(newnb.cells[0].source, u'Created by test ³') nbcontent = self.api.read('foo/a.ipynb').json()['content'] newnb = from_dict(nbcontent) self.assertEqual(newnb.cells[0].source, u'Created by test ³')
def save(self, model, path=''): """ Save the file model and return the model with no content. """ path = path.strip('/') if 'type' not in model: raise web.HTTPError(400, u'No file type provided') if 'content' not in model and model['type'] != 'directory': raise web.HTTPError(400, u'No file content provided') # One checkpoint should always exist if self.file_exists(path) and not self.list_checkpoints(path): self.create_checkpoint(path) self.log.debug("Saving %s", path) self.run_pre_save_hook(model=model, path=path) try: if model['type'] == 'notebook': nb = nbformat.from_dict(model['content']) self.check_and_sign(nb, path) self._save_notebook(path, nb) # One checkpoint should always exist for notebooks. # if not self.list_checkpoints(path): # self.create_checkpoint(path) elif model['type'] == 'file': # Missing format will be handled internally by _save_file. self._save_file(path, model['content'], model.get('format')) elif model['type'] == 'directory': self._save_directory(path, model, path) else: raise web.HTTPError( 400, "Unhandled contents type: %s" % model['type']) except web.HTTPError: raise except Exception as e: self.log.error(u'Error while saving file: %s %s', path, e, exc_info=True) raise web.HTTPError( 500, u'Unexpected error while saving file: %s %s' % (path, e)) validation_message = None if model['type'] == 'notebook': self.validate_notebook_model(model) validation_message = model.get('message', None) model = self.get(path, content=False) if validation_message: model['message'] = validation_message return model
def _save_notebook(self, db, model, path): """ Save a notebook. Returns a validation message. """ nb_contents = from_dict(model['content']) self.check_and_sign(nb_contents, path) save_notebook(db, self.user_id, path, writes_base64(nb_contents)) # It's awkward that this writes to the model instead of returning. self.validate_notebook_model(model) return model.get('message')
def _save_notebook(self, os_path, model, name='', path=''): """save a notebook file""" # Save the notebook file nb = nbformat.from_dict(model['content']) self.check_and_sign(nb, name, path) if 'name' in nb['metadata']: nb['metadata']['name'] = u'' with atomic_writing(os_path, encoding='utf-8') as f: nbformat.write(nb, f, version=nbformat.NO_CONVERT)
def save(self, model, path=''): """ Save the file model and return the model with no content. """ path = path.strip('/') if 'type' not in model: raise web.HTTPError(400, u'No file type provided') if 'content' not in model and model['type'] != 'directory': raise web.HTTPError(400, u'No file content provided') # One checkpoint should always exist if self.file_exists(path) and not self.list_checkpoints(path): self.create_checkpoint(path) self.log.debug("Saving %s", path) self.run_pre_save_hook(model=model, path=path) try: if model['type'] == 'notebook': nb = nbformat.from_dict(model['content']) self.check_and_sign(nb, path) self._save_notebook(path, nb) # One checkpoint should always exist for notebooks. # if not self.list_checkpoints(path): # self.create_checkpoint(path) elif model['type'] == 'file': # Missing format will be handled internally by _save_file. self._save_file(path, model['content'], model.get('format')) elif model['type'] == 'directory': self._save_directory(path, model, path) else: raise web.HTTPError( 400, "Unhandled contents type: %s" % model['type']) except web.HTTPError: raise except Exception as e: self.log.error( u'Error while saving file: %s %s', path, e, exc_info=True) raise web.HTTPError( 500, u'Unexpected error while saving file: %s %s' % (path, e)) validation_message = None if model['type'] == 'notebook': self.validate_notebook_model(model) validation_message = model.get('message', None) model = self.get(path, content=False) if validation_message: model['message'] = validation_message return model
def save_notebook(self, model, name='', path=''): """Save the notebook model and return the model with no content.""" path = path.strip('/') if 'content' not in model: raise web.HTTPError(400, u'No notebook JSON data provided') if not path: raise web.HTTPError(400, u'We require path for saving.') nb = nbformat.from_dict(model['content']) gist = self._get_gist(name, path) if gist is None: tags = parse_tags(name) if path: tags.append(path) content = nbformat.writes(nb, version=nbformat.NO_CONVERT) gist = self.gisthub.create_gist(name, tags, content) # One checkpoint should always exist #if self.notebook_exists(name, path) and not self.list_checkpoints(name, path): # self.create_checkpoint(name, path) new_path = model.get('path', path).strip('/') new_name = model.get('name', name) if path != new_path: raise web.HTTPError(400, u'Gist backend does not support path change') # remove [gist_id] if we're being sent old key_name gist.name = gist.strip_gist_id(new_name) gist.notebook_content = nb self.check_and_sign(nb, self.fullpath(new_path, new_name)) if 'name' in nb['metadata']: nb['metadata']['name'] = u'' try: self.log.debug("Autosaving notebook %s %s", path, name) self.gisthub.save(gist) except Exception as e: raise web.HTTPError( 400, u'Unexpected error while autosaving notebook: %s %s %s' % (path, name, e)) # NOTE: since gist.name might not have [gist_id] suffix on rename # we use gist.key_name model = self.get_notebook(gist.key_name, new_path, content=False) return model
def test_checkpoints(self): resp = self.api.read('foo/a.ipynb') r = self.api.new_checkpoint('foo/a.ipynb') self.assertEqual(r.status_code, 201) cp1 = r.json() self.assertEqual(set(cp1), {'id', 'last_modified'}) self.assertEqual(r.headers['Location'].split('/')[-1], cp1['id']) # Modify it nbcontent = json.loads(resp.text)['content'] nb = from_dict(nbcontent) hcell = new_markdown_cell('Created by test') nb.cells.append(hcell) # Save nbmodel= {'content': nb, 'type': 'notebook'} resp = self.api.save('foo/a.ipynb', body=json.dumps(nbmodel)) # List checkpoints cps = self.api.get_checkpoints('foo/a.ipynb').json() self.assertEqual(cps, [cp1]) nbcontent = self.api.read('foo/a.ipynb').json()['content'] nb = from_dict(nbcontent) self.assertEqual(nb.cells[0].source, 'Created by test') # Restore cp1 r = self.api.restore_checkpoint('foo/a.ipynb', cp1['id']) self.assertEqual(r.status_code, 204) nbcontent = self.api.read('foo/a.ipynb').json()['content'] nb = from_dict(nbcontent) self.assertEqual(nb.cells, []) # Delete cp1 r = self.api.delete_checkpoint('foo/a.ipynb', cp1['id']) self.assertEqual(r.status_code, 204) cps = self.api.get_checkpoints('foo/a.ipynb').json() self.assertEqual(cps, [])
def test_checkpoints(self): resp = self.api.read("foo/a.ipynb") r = self.api.new_checkpoint("foo/a.ipynb") self.assertEqual(r.status_code, 201) cp1 = r.json() self.assertEqual(set(cp1), {"id", "last_modified"}) self.assertEqual(r.headers["Location"].split("/")[-1], cp1["id"]) # Modify it nbcontent = json.loads(resp.text)["content"] nb = from_dict(nbcontent) hcell = new_markdown_cell("Created by test") nb.cells.append(hcell) # Save nbmodel = {"content": nb, "type": "notebook"} resp = self.api.save("foo/a.ipynb", body=json.dumps(nbmodel)) # List checkpoints cps = self.api.get_checkpoints("foo/a.ipynb").json() self.assertEqual(cps, [cp1]) nbcontent = self.api.read("foo/a.ipynb").json()["content"] nb = from_dict(nbcontent) self.assertEqual(nb.cells[0].source, "Created by test") # Restore cp1 r = self.api.restore_checkpoint("foo/a.ipynb", cp1["id"]) self.assertEqual(r.status_code, 204) nbcontent = self.api.read("foo/a.ipynb").json()["content"] nb = from_dict(nbcontent) self.assertEqual(nb.cells, []) # Delete cp1 r = self.api.delete_checkpoint("foo/a.ipynb", cp1["id"]) self.assertEqual(r.status_code, 204) cps = self.api.get_checkpoints("foo/a.ipynb").json() self.assertEqual(cps, [])
def test_checkpoints(self): resp = self.api.read('foo/a.ipynb') r = self.api.new_checkpoint('foo/a.ipynb') self.assertEqual(r.status_code, 201) cp1 = r.json() self.assertEqual(set(cp1), {'id', 'last_modified'}) self.assertEqual(r.headers['Location'].split('/')[-1], cp1['id']) # Modify it nbcontent = json.loads(resp.text)['content'] nb = from_dict(nbcontent) hcell = new_markdown_cell('Created by test') nb.cells.append(hcell) # Save nbmodel = {'content': nb, 'type': 'notebook'} resp = self.api.save('foo/a.ipynb', body=json.dumps(nbmodel)) # List checkpoints cps = self.api.get_checkpoints('foo/a.ipynb').json() self.assertEqual(cps, [cp1]) nbcontent = self.api.read('foo/a.ipynb').json()['content'] nb = from_dict(nbcontent) self.assertEqual(nb.cells[0].source, 'Created by test') # Restore cp1 r = self.api.restore_checkpoint('foo/a.ipynb', cp1['id']) self.assertEqual(r.status_code, 204) nbcontent = self.api.read('foo/a.ipynb').json()['content'] nb = from_dict(nbcontent) self.assertEqual(nb.cells, []) # Delete cp1 r = self.api.delete_checkpoint('foo/a.ipynb', cp1['id']) self.assertEqual(r.status_code, 204) cps = self.api.get_checkpoints('foo/a.ipynb').json() self.assertEqual(cps, [])
def save_notebook(self, model, name='', path=''): """Save the notebook model and return the model with no content.""" path = path.strip('/') if 'content' not in model: raise web.HTTPError(400, u'No notebook JSON data provided') if not path: raise web.HTTPError(400, u'We require path for saving.') nb = nbformat.from_dict(model['content']) gist = self._get_gist(name, path) if gist is None: tags = parse_tags(name) if path: tags.append(path) content = nbformat.writes(nb, version=nbformat.NO_CONVERT) gist = self.gisthub.create_gist(name, tags, content) # One checkpoint should always exist #if self.notebook_exists(name, path) and not self.list_checkpoints(name, path): # self.create_checkpoint(name, path) new_path = model.get('path', path).strip('/') new_name = model.get('name', name) if path != new_path: raise web.HTTPError(400, u'Gist backend does not support path change') # remove [gist_id] if we're being sent old key_name gist.name = gist.strip_gist_id(new_name) gist.notebook_content = nb self.check_and_sign(nb, self.fullpath(new_path, new_name)) if 'name' in nb['metadata']: nb['metadata']['name'] = u'' try: self.log.debug("Autosaving notebook %s %s", path, name) self.gisthub.save(gist) except Exception as e: raise web.HTTPError(400, u'Unexpected error while autosaving notebook: %s %s %s' % (path, name, e)) # NOTE: since gist.name might not have [gist_id] suffix on rename # we use gist.key_name model = self.get_notebook(gist.key_name, new_path, content=False) return model
def save(self, model, path=""): """Save the file model and return the model with no content.""" path = path.strip("/") if "type" not in model: raise web.HTTPError(400, u"No file type provided") if "content" not in model and model["type"] != "directory": raise web.HTTPError(400, u"No file content provided") self.run_pre_save_hook(model=model, path=path) os_path = self._get_os_path(path) self.log.debug("Saving %s", os_path) try: if model["type"] == "notebook": nb = nbformat.from_dict(model["content"]) self.check_and_sign(nb, path) self._save_notebook(os_path, nb) # One checkpoint should always exist for notebooks. if not self.checkpoints.list_checkpoints(path): self.create_checkpoint(path) elif model["type"] == "file": # Missing format will be handled internally by _save_file. self._save_file(os_path, model["content"], model.get("format")) elif model["type"] == "directory": self._save_directory(os_path, model, path) else: raise web.HTTPError(400, "Unhandled contents type: %s" % model["type"]) except web.HTTPError: raise except Exception as e: self.log.error(u"Error while saving file: %s %s", path, e, exc_info=True) raise web.HTTPError(500, u"Unexpected error while saving file: %s %s" % (path, e)) validation_message = None if model["type"] == "notebook": self.validate_notebook_model(model) validation_message = model.get("message", None) model = self.get(path, content=False) if validation_message: model["message"] = validation_message self.run_post_save_hook(model=model, os_path=os_path) return model
def _save_notebook(self, db, model, path): """ Save a notebook. Returns a validation message. """ nb_contents = from_dict(model['content']) self.check_and_sign(nb_contents, path) save_file( db, self.user_id, path, writes_base64(nb_contents), self.max_file_size_bytes, ) # It's awkward that this writes to the model instead of returning. self.validate_notebook_model(model) return model.get('message')
def post(self, format): exporter = get_exporter(format, config=self.config) model = self.get_json_body() name = model.get("name", "notebook.ipynb") nbnode = from_dict(model["content"]) try: output, resources = exporter.from_notebook_node(nbnode) except Exception as e: raise web.HTTPError(500, "nbconvert failed: %s" % e) if respond_zip(self, name, output, resources): return # MIME type if exporter.output_mimetype: self.set_header("Content-Type", "%s; charset=utf-8" % exporter.output_mimetype) self.finish(output)
def post(self, format): exporter = get_exporter(format, config=self.config) model = self.get_json_body() name = model.get('name', 'notebook.ipynb') nbnode = from_dict(model['content']) try: output, resources = exporter.from_notebook_node(nbnode) except Exception as e: raise web.HTTPError(500, "nbconvert failed: %s" % e) if respond_zip(self, name, output, resources): return # MIME type if exporter.output_mimetype: self.set_header('Content-Type', '%s; charset=utf-8' % exporter.output_mimetype) self.finish(output)
def save(self, model, path): """ very similar to filemanager.save """ self.log.debug('save: %s', locals()) if 'type' not in model: raise web.HTTPError(400, u'No file type provided') if 'content' not in model and model['type'] != 'directory': raise web.HTTPError(400, u'No file content provided') # self.run_pre_save_hook(model=model, path=path) if model['type'] == 'notebook': nb = nbformat.from_dict(model['content']) self.check_and_sign(nb, path) self._save_notebook(path, nb) elif model['type'] == 'file': self._save_file(path, model['content'], model.get('format')) elif model['type'] == 'directory': pass # keep symmetry with filemanager.save else: raise web.HTTPError(400, "Unhandled contents type: %s" % model['type']) validation_message = None if model['type'] == 'notebook': self.validate_notebook_model(model) validation_message = model.get('message', None) model = self.get(path, content=False, type=model['type']) if validation_message: model['message'] = validation_message # self.run_post_save_hook(model=model, os_path=path) model['content'] = None return model
def save_notebook(self, model, name='', path=''): """ Save notebook model to file system. Note: This differs from the NotebookManager.save_notebook in that it doesn't have a rename check. """ if not self.is_writable(name, path): raise Exception("Notebook target is not writable") bundle_path = self._get_bundle_path(name, path) if not os.path.exists(bundle_path): os.mkdir(bundle_path) nb = nbformat.from_dict(model['content']) notary = sign.NotebookNotary() if notary.check_cells(nb): notary.sign(nb) self.write_notebook(bundle_path, name, nb) if '__files' in model: self.write_files(bundle_path, model)
def _save_notebook(self, os_path, model, path): """save a notebook to shock""" # Get name name = path.rsplit('/', 1)[-1] # Get attributes attr = {} attr['name'] = self._strip_ext(name) attr['type'] = self.node_type attr['format'] = 'json' attr['last_modified'] = tz.utcnow().isoformat() # creation timestamp if 'created' in model: attr['created'] = model['created'].isoformat() elif name in self.nb_list: attr['created'] = self.nb_list[name]['attributes']['created'] else: attr['created'] = attr['last_modified'] # original id if name in self.nb_list: attr['original'] = self.nb_list[name]['attributes']['original'] else: attr['original'] = str(uuid.uuid4()) attr_str = json.dumps(attr) # Get the notebook content nb = nbformat.from_dict(model['content']) self.check_and_sign(nb, name) nb_str = nbformat.writes(nb, version=nbformat.NO_CONVERT) # Save to shock try: self.log.debug("Saving %s to Shock", name) node = self._post_shock_node(name, nb_str, attr_str) except Exception as e: raise web.HTTPError(400, u'Unexpected error while saving notebook: %s' %e) # update lists self.nb_list[name] = node open(os_path, 'w').close()
def save(self, model, path): """ very similar to filemanager.save """ self.log.debug('save: {}'.format(locals())) if 'type' not in model: raise web.HTTPError(400, u'No file type provided') if 'content' not in model and model['type'] != 'directory': raise web.HTTPError(400, u'No file content provided') # self.run_pre_save_hook(model=model, path=path) if model['type'] == 'notebook': nb = nbformat.from_dict(model['content']) self.check_and_sign(nb, path) self._save_notebook(path, nb) elif model['type'] == 'file': self._save_file(path, model['content'], model.get('format')) elif model['type'] == 'directory': pass # keep symmetry with filemanager.save else: raise web.HTTPError(400, "Unhandled contents type: %s" % model['type']) validation_message = None if model['type'] == 'notebook': self.validate_notebook_model(model) validation_message = model.get('message', None) model = self.get(path, content=False, type=model['type']) if validation_message: model['message'] = validation_message # self.run_post_save_hook(model=model, os_path=path) model['content'] = None return model
def save_notebook(self, model, name="", path=""): """ Save notebook model to file system. Note: This differs from the NotebookManager.save_notebook in that it doesn't have a rename check. """ if not self.is_writable(name, path): raise Exception("Notebook target is not writable") bundle_path = self._get_bundle_path(name, path) if not os.path.exists(bundle_path): os.mkdir(bundle_path) nb = nbformat.from_dict(model["content"]) notary = sign.NotebookNotary() if notary.check_cells(nb): notary.sign(nb) self.write_notebook(bundle_path, name, nb) if "__files" in model: self.write_files(bundle_path, model)
def save(self, model, path): """ very similar to filemanager.save """ self.log.debug("save: %s", locals()) if "type" not in model: raise web.HTTPError(400, u"No file type provided") if "content" not in model and model["type"] != "directory": raise web.HTTPError(400, u"No file content provided") # self.run_pre_save_hook(model=model, path=path) if model["type"] == "notebook": nb = nbformat.from_dict(model["content"]) self.check_and_sign(nb, path) self._save_notebook(path, nb) elif model["type"] == "file": self._save_file(path, model["content"], model.get("format")) elif model["type"] == "directory": pass # keep symmetry with filemanager.save else: raise web.HTTPError(400, "Unhandled contents type: %s" % model["type"]) validation_message = None if model["type"] == "notebook": self.validate_notebook_model(model) validation_message = model.get("message", None) model = self.get(path, content=False, type=model["type"]) if validation_message: model["message"] = validation_message # self.run_post_save_hook(model=model, os_path=path) model["content"] = None return model
def save(self, model, path=''): """Save the file model and return the model with no content.""" path = path.strip('/') if 'type' not in model: raise web.HTTPError(400, u'No file type provided') if 'content' not in model and model['type'] != 'directory': raise web.HTTPError(400, u'No file content provided') self.run_pre_save_hook(model=model, path=path) os_path = self._get_os_path(path) self.log.debug("Saving %s", os_path) try: if model['type'] == 'notebook': # NEW file_ext = _file_extension(os_path) if file_ext == '.ipynb': nb = nbformat.from_dict(model['content']) self.check_and_sign(nb, path) self._save_notebook(os_path, nb) else: contents = convert(model['content'], from_='notebook', to=self.format) # Save a text file. if (format_manager().file_type(self.format) in ('text', 'json')): self._save_file(os_path, contents, 'text') # Save to a binary file. else: format_manager().save(os_path, contents, name=self.format, overwrite=True) # One checkpoint should always exist for notebooks. if not self.checkpoints.list_checkpoints(path): self.create_checkpoint(path) elif model['type'] == 'file': # Missing format will be handled internally by _save_file. self._save_file(os_path, model['content'], model.get('format')) elif model['type'] == 'directory': self._save_directory(os_path, model, path) else: raise web.HTTPError(400, "Unhandled contents type: %s" % model['type']) except web.HTTPError: raise except Exception as e: self.log.error(u'Error while saving file: %s %s', path, e, exc_info=True) raise web.HTTPError(500, u'Unexpected error while saving file: %s %s' % (path, e)) validation_message = None if model['type'] == 'notebook': self.validate_notebook_model(model) validation_message = model.get('message', None) model = self.get(path, content=False) if validation_message: model['message'] = validation_message self.run_post_save_hook(model=model, os_path=os_path) return model
def get_notebook(self, path): """Get a notebook""" model = self.contents(path) return nbformat.from_dict(model['content'])