def test_save(self): resp = self.nb_api.read('a.ipynb', 'foo') nbcontent = json.loads(resp.text)['content'] nb = to_notebook_json(nbcontent) ws = new_worksheet() nb.worksheets = [ws] ws.cells.append(new_heading_cell(u'Created by test ³')) nbmodel = {'name': 'a.ipynb', 'path': 'foo', 'content': nb} resp = self.nb_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, format='ipynb') self.assertEqual(newnb.worksheets[0].cells[0].source, u'Created by test ³') nbcontent = self.nb_api.read('a.ipynb', 'foo').json()['content'] newnb = to_notebook_json(nbcontent) self.assertEqual(newnb.worksheets[0].cells[0].source, u'Created by test ³') # Save and rename nbmodel = {'name': 'a2.ipynb', 'path': 'foo/bar', 'content': nb} resp = self.nb_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.nb_api.read('a.ipynb', 'foo')
def test_save(self): resp = self.nb_api.read('a.ipynb', 'foo') nbcontent = json.loads(resp.text)['content'] nb = to_notebook_json(nbcontent) ws = new_worksheet() nb.worksheets = [ws] ws.cells.append(new_heading_cell(u'Created by test ³')) nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb} resp = self.nb_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, format='ipynb') self.assertEqual(newnb.worksheets[0].cells[0].source, u'Created by test ³') nbcontent = self.nb_api.read('a.ipynb', 'foo').json()['content'] newnb = to_notebook_json(nbcontent) self.assertEqual(newnb.worksheets[0].cells[0].source, u'Created by test ³') # Save and rename nbmodel= {'name': 'a2.ipynb', 'path':'foo/bar', 'content': nb} resp = self.nb_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.nb_api.read('a.ipynb', 'foo')
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) # Save the notebook file nb = current.to_notebook_json(model['content']) #self.check_and_sign(nb, name, path) 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, model, name, path=''): """Save the notebook and return the model with no content.""" nb = current.to_notebook_json(model['content']) # self.check_and_sign(nb, name, path) key = self.bucket.new_key(self.s3_prefix + name) key.set_contents_from_string(nb) return self.get_notebook(name, name, content=False)
def save_notebook_model(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') # 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 or name != new_name: self.rename_notebook(name, path, new_name, new_path) # Save the notebook file os_path = self.get_os_path(new_name, new_path) nb = current.to_notebook_json(model['content']) if 'name' in nb['metadata']: nb['metadata']['name'] = u'' try: self.log.debug("Autosaving notebook %s", os_path) with io.open(os_path, 'w', encoding='utf-8') as f: current.write(nb, f, u'json') except Exception as e: raise web.HTTPError( 400, u'Unexpected error while autosaving notebook: %s %s' % (os_path, e)) # Save .py script as well if self.save_script: py_path = os.path.splitext(os_path)[0] + '.py' self.log.debug("Writing script %s", py_path) try: with io.open(py_path, 'w', encoding='utf-8') as f: current.write(nb, f, u'py') except Exception as e: raise web.HTTPError( 400, u'Unexpected error while saving notebook as script: %s %s' % (py_path, e)) # Save .ipynb.clean as well. if self.save_clean: py_path = os_path + '.clean' self.log.debug("Writing clean file %s", py_path) try: with io.open(py_path, 'w', encoding='utf-8') as f: current.write(clean_nb(nb), f, u'ipynb') except Exception as e: raise web.HTTPError( 400, u'Unexpected error while saving clean notebook: %s %s' % (py_path, e)) model = self.get_notebook_model(new_name, new_path, content=False) return model
def test_checkpoints(self): resp = self.api.read('a.ipynb', 'foo') r = self.api.new_checkpoint('a.ipynb', 'foo') 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 = to_notebook_json(nbcontent) ws = new_worksheet() nb.worksheets = [ws] hcell = new_heading_cell('Created by test') ws.cells.append(hcell) # Save nbmodel = { 'name': 'a.ipynb', 'path': 'foo', 'content': nb, 'type': 'notebook' } resp = self.api.save('a.ipynb', path='foo', body=json.dumps(nbmodel)) # List checkpoints cps = self.api.get_checkpoints('a.ipynb', 'foo').json() self.assertEqual(cps, [cp1]) nbcontent = self.api.read('a.ipynb', 'foo').json()['content'] nb = to_notebook_json(nbcontent) self.assertEqual(nb.worksheets[0].cells[0].source, 'Created by test') # Restore cp1 r = self.api.restore_checkpoint('a.ipynb', 'foo', cp1['id']) self.assertEqual(r.status_code, 204) nbcontent = self.api.read('a.ipynb', 'foo').json()['content'] nb = to_notebook_json(nbcontent) self.assertEqual(nb.worksheets, []) # Delete cp1 r = self.api.delete_checkpoint('a.ipynb', 'foo', cp1['id']) self.assertEqual(r.status_code, 204) cps = self.api.get_checkpoints('a.ipynb', 'foo').json() self.assertEqual(cps, [])
def _save_notebook(self, os_path, model, name="", path=""): """save a notebook file""" # Save the notebook file nb = current.to_notebook_json(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: current.write(nb, f, u"json")
def _save_notebook(self, os_path, model, name='', path=''): """save a notebook file""" # Save the notebook file nb = current.to_notebook_json(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: current.write(nb, f, u'json')
def _save_notebook(self, os_path, model, name='', path=''): """save a notebook file""" # Save the notebook file nb = current.to_notebook_json(model['content']) self.check_and_sign(nb, name, path) if 'name' in nb['metadata']: nb['metadata']['name'] = u'' with io.open(os_path, 'w', encoding='utf-8') as f: current.write(nb, f, u'json')
def _save_notebook(self, os_path, model, name='', path=''): """save a notebook file""" # Save the notebook file nb = current.to_notebook_json(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: current.write(nb, f, version=nb.nbformat)
def test_checkpoints(self): resp = self.nb_api.read('a.ipynb', 'foo') r = self.nb_api.new_checkpoint('a.ipynb', 'foo') 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 = to_notebook_json(nbcontent) ws = new_worksheet() nb.worksheets = [ws] hcell = new_heading_cell('Created by test') ws.cells.append(hcell) # Save nbmodel = {'name': 'a.ipynb', 'path': 'foo', 'content': nb} resp = self.nb_api.save( 'a.ipynb', path='foo', body=json.dumps(nbmodel)) # List checkpoints cps = self.nb_api.get_checkpoints('a.ipynb', 'foo').json() self.assertEqual(cps, [cp1]) nbcontent = self.nb_api.read('a.ipynb', 'foo').json()['content'] nb = to_notebook_json(nbcontent) self.assertEqual(nb.worksheets[0].cells[0].source, 'Created by test') # Restore cp1 r = self.nb_api.restore_checkpoint('a.ipynb', 'foo', cp1['id']) self.assertEqual(r.status_code, 204) nbcontent = self.nb_api.read('a.ipynb', 'foo').json()['content'] nb = to_notebook_json(nbcontent) self.assertEqual(nb.worksheets, []) # Delete cp1 r = self.nb_api.delete_checkpoint('a.ipynb', 'foo', cp1['id']) self.assertEqual(r.status_code, 204) cps = self.nb_api.get_checkpoints('a.ipynb', 'foo').json() self.assertEqual(cps, [])
def save_notebook(self, model, name, path=''): """Save the notebook model and return the model with no content.""" self.log.debug("save_notebook(%s, '%s', '%s')", model, str(name), str(path)) assert name.endswith(self.filename_ext) path = path.strip('/') if 'content' not in model: raise web.HTTPError(400, u'No notebook JSON data provided') # 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) new_name = model.get('name', name) if path != new_path or name != new_name: self._rename_notebook(name, path, new_name, new_path) # Create the path and notebook entries if necessary if new_path not in self.tree: self.tree[new_path] = {} if new_name not in self.tree[new_path]: self.tree[new_path][new_name] = \ dict(created = tz.utcnow(), checkpoints=[]) notebook = self.tree[new_path][new_name] # Save the notebook file nb = current.to_notebook_json(model['content']) self.check_and_sign(nb, new_path, new_name) if 'name' in nb['metadata']: nb['metadata']['name'] = u'' ipynb_stream = StringIO() current.write(nb, ipynb_stream, u'json') notebook['ipynb'] = ipynb_stream.getvalue() notebook['ipynb_last_modified'] = tz.utcnow() ipynb_stream.close() # Save .py script as well py_stream = StringIO() current.write(nb, py_stream, u'json') notebook['py'] = py_stream.getvalue() notebook['py_last_modified'] = tz.utcnow() py_stream.close() # Return model model = self.get_notebook(new_name, new_path, content=False) self.log.debug("save_notebook -> %s", model) return model
def save_notebook_model(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') # 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 or name != new_name: self.rename_notebook(name, path, new_name, new_path) # Save the notebook file os_path = self.get_os_path(new_name, new_path) nb = current.to_notebook_json(model['content']) if 'name' in nb['metadata']: nb['metadata']['name'] = u'' try: self.log.debug("Autosaving notebook %s", os_path) with io.open(os_path, 'w', encoding='utf-8') as f: current.write(nb, f, u'json') except Exception as e: raise web.HTTPError(400, u'Unexpected error while autosaving notebook: %s %s' % (os_path, e)) # Save .py script as well if self.save_script: py_path = os.path.splitext(os_path)[0] + '.py' self.log.debug("Writing script %s", py_path) try: with io.open(py_path, 'w', encoding='utf-8') as f: current.write(nb, f, u'py') except Exception as e: raise web.HTTPError(400, u'Unexpected error while saving notebook as script: %s %s' % (py_path, e)) # Save .ipynb.clean as well. if self.save_clean: py_path = os_path + '.clean' self.log.debug("Writing clean file %s", py_path) try: with io.open(py_path, 'w', encoding='utf-8') as f: current.write(clean_nb(nb), f, u'ipynb') except Exception as e: raise web.HTTPError(400, u'Unexpected error while saving clean notebook: %s %s' % (py_path, e)) model = self.get_notebook_model(new_name, new_path, content=False) 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.') gist = self._get_gist(name, path) if gist is None: tags = parse_tags(name) if path: tags.append(path) content = current.writes(model['content'], format=u'json') 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') # Save the notebook file nb = current.to_notebook_json(model['content']) # 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, 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_notebook(self, model, name='', path=''): path = path.strip('/') if 'content' not in model: raise web.HTTPError(400, u'No notebook JSON data provided') # 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 or name != new_name: self.rename_notebook(name, path, new_name, new_path) # Save the notebook file nb = current.to_notebook_json(model['content']) self.check_and_sign(nb, new_name, new_path) if 'name' in nb['metadata']: nb['metadata']['name'] = u'' try: with StringIO() as f: current.write(nb, f, u'json') spec = {'path': path, 'name': name} data = { '$set': { 'type': 'notebook', 'content': f.getvalue(), 'lastModified': datetime.datetime.now(), } } f.close() if 'created' in model: data['$set']['created'] = model['created'] else: data['$set']['created'] = datetime.datetime.now() notebook = self._connect_collection( self.notebook_collection).update(spec, data, upsert=True) except Exception as e: raise web.HTTPError( 400, u'Unexpected error while autosaving notebook: %s' % (e)) model = self.get_notebook(new_name, new_path, content=False) return model
def post(self, format): exporter = exporter_map[format](config=self.config) model = self.get_json_body() nbnode = to_notebook_json(model['content']) output, resources = exporter.from_notebook_node(nbnode) if respond_zip(self, nbnode.metadata.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_notebook(self, model, name='', path=''): """Save the notebook model and return the model with no content.""" path = path.strip('/') self.log.debug('File manager: saving notebook %s, %s' % (name, path)) if 'content' not in model: raise web.HTTPError(400, u'No notebook JSON data provided') # 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) new_name = model.get('name', name) if path != new_path or name != new_name: self.log.debug('renaming notebook %s %s->%s %s' (path, name, new_path, new_name)) self.rename_notebook(name, path, new_name, new_path) # Save the notebook file self.log.debug('getting json content') os_path = self._get_os_path(new_name, new_path) nb = current.to_notebook_json(model['content']) self.check_and_sign(nb, new_name, new_path) self.log.debug("checked and signed") if 'name' in nb['metadata']: nb['metadata']['name'] = u'' try: self.log.debug("Autosaving notebook %s", os_path) new_key_from_string(self.bucket, os_path, current.writes(nb, u'json')) except Exception as e: self.log.debug(e) raise web.HTTPError(400, u'Unexpected error while autosaving notebook: %s %s' % (os_path, e)) # Save .py script as well if self.save_script: py_path = os.path.splitext(os_path)[0] + '.py' self.log.debug("Writing script %s", py_path) try: new_key_from_string(self.bucket, py_path, current.writes(nb, u'py')) except Exception as e: self.log.error(e) raise web.HTTPError(400, u'Unexpected error while saving notebook as script: %s %s' % (py_path, e)) return self.get_notebook(new_name, new_path, content=False)
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") # 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 or name != new_name: self.rename_notebook(name, path, new_name, new_path) # Save the notebook file os_path = self._get_os_path(new_name, new_path) nb = current.to_notebook_json(model["content"]) self.check_and_sign(nb, new_name, new_path) if "name" in nb["metadata"]: nb["metadata"]["name"] = u"" try: self.log.debug("Autosaving notebook %s", os_path) with io.open(os_path, "w", encoding="utf-8") as f: current.write(nb, f, u"json") except Exception as e: raise web.HTTPError(400, u"Unexpected error while autosaving notebook: %s %s" % (os_path, e)) # Save .py script as well if self.save_script: py_path = os.path.splitext(os_path)[0] + ".py" self.log.debug("Writing script %s", py_path) try: with io.open(py_path, "w", encoding="utf-8") as f: current.write(nb, f, u"py") except Exception as e: raise web.HTTPError(400, u"Unexpected error while saving notebook as script: %s %s" % (py_path, e)) model = self.get_notebook(new_name, new_path, content=False) return model
def post(self, format): exporter = get_exporter(format, config=self.config) model = self.get_json_body() nbnode = to_notebook_json(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, nbnode.metadata.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_notebook(self, model, name='', path=''): path = path[1:] if path.startswith('/') else path if 'content' not in model: raise web.HTTPError(400, u'No notebook JSON data provided') # 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) new_name = model.get('name', name) if path != new_path or name != new_name: self.rename_notebook(name, path, new_name, new_path) s3_path = self._get_s3_path(new_name, new_path) nb = current.to_notebook_json(model['content']) if 'name' in nb['metadata']: nb['metadata']['name'] = u'' try: self.log.debug("Autosaving notebook %s", s3_path) key = self.bucket.new_key(s3_path) key.set_metadata('nbname', new_name) key.set_contents_from_string(json.dumps(nb)) except Exception as e: raise web.HTTPError(400, u'Unexpected error while autosaving notebook: %s %s' % (s3_path, e)) if self.save_script: py_path = os.path.splitext(s3_path)[0] + '.py' self.log.debug("Writing script %s", py_path) try: key = self.bucket.new_key(py_path) key.set_metadata('nbname', new_name) key.set_contents_from_string(nb) except Exception as e: raise web.HTTPError(400, u'Unexpected error while saving notebook as script: %s %s' % (py_path, e)) model = self.get_notebook(new_name, new_path, content=False) return model
def post(self, format): exporter = get_exporter(format, config=self.config) model = self.get_json_body() nbnode = to_notebook_json(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, nbnode.metadata.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_notebook(self, model, name, path=''): self.log.debug('save_notebook: {}'.format(locals())) if 'content' not in model: raise web.HTTPError(400, u'No notebook JSON data provided') k = boto.s3.key.Key(self.bucket) k.key = self._notebook_s3_key_string(path, name) nb = current.to_notebook_json(model['content']) self.check_and_sign(nb, name, path) try: with tempfile.NamedTemporaryFile() as f: current.write(nb, f, u'json') f.seek(0) k.set_contents_from_file(f) except Exception as e: raise web.HTTPError(400, u"Unexpected Error Writing Notebook: %s %s %s" % (path, name, e)) return self.get_notebook(name, path, content=False)
def save_notebook(self, model, name, path=''): self.log.debug('save_notebook: {}'.format(locals())) if 'content' not in model: raise web.HTTPError(400, u'No notebook JSON data provided') k = boto.s3.key.Key(self.bucket) k.key = self._notebook_s3_key_string(path, name) nb = current.to_notebook_json(model['content']) self.check_and_sign(nb, name, path) try: with tempfile.NamedTemporaryFile() as f: current.write(nb, f, u'json') f.seek(0) k.set_contents_from_file(f) except Exception as e: raise web.HTTPError( 400, u"Unexpected Error Writing Notebook: %s %s %s" % (path, name, e)) return self.get_notebook(name, path, content=False)
def new_notebook(metadata, filepath): content = current.new_notebook(metadata=metadata) nb = current.to_notebook_json(content) with io.open(filepath, 'w', encoding='utf-8') as f: current.write(nb, f, u'json')
def get_notebook(self, path): """Get a notebook""" model = self.contents(path) return current.to_notebook_json(model['content'])