mirror of
https://github.com/jupyter/notebook.git
synced 2025-01-30 12:11:32 +08:00
Rearrange the NotebookManager methods for clarity
Methods are organized into three categories: - Methods that must be implemented in subclasses - Methods that have default implementations, but can be overridden if required. - Support methods meant to be called by methods in subclasses
This commit is contained in:
parent
b1c6ba2c97
commit
fdb8ab37ae
@ -47,25 +47,8 @@ class NotebookManager(LoggingConfigurable):
|
|||||||
def _notary_default(self):
|
def _notary_default(self):
|
||||||
return sign.NotebookNotary(parent=self)
|
return sign.NotebookNotary(parent=self)
|
||||||
|
|
||||||
def check_and_sign(self, nb, path, name):
|
# NotebookManager API part 1: methods that must be
|
||||||
"""Check for trusted cells, and sign the notebook.
|
# implemented in subclasses.
|
||||||
|
|
||||||
Called as a part of saving notebooks.
|
|
||||||
"""
|
|
||||||
if self.notary.check_cells(nb):
|
|
||||||
self.notary.sign(nb)
|
|
||||||
else:
|
|
||||||
self.log.warn("Saving untrusted notebook %s/%s", path, name)
|
|
||||||
|
|
||||||
def mark_trusted_cells(self, nb, path, name):
|
|
||||||
"""Mark cells as trusted if the notebook signature matches.
|
|
||||||
|
|
||||||
Called as a part of loading notebooks.
|
|
||||||
"""
|
|
||||||
trusted = self.notary.check_signature(nb)
|
|
||||||
if not trusted:
|
|
||||||
self.log.warn("Notebook %s/%s is not trusted", path, name)
|
|
||||||
self.notary.mark_cells(nb, trusted)
|
|
||||||
|
|
||||||
def path_exists(self, path):
|
def path_exists(self, path):
|
||||||
"""Does the API-style path (directory) actually exist?
|
"""Does the API-style path (directory) actually exist?
|
||||||
@ -101,47 +84,6 @@ class NotebookManager(LoggingConfigurable):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def _notebook_dir_changed(self, name, old, new):
|
|
||||||
"""Do a bit of validation of the notebook dir."""
|
|
||||||
if not os.path.isabs(new):
|
|
||||||
# If we receive a non-absolute path, make it absolute.
|
|
||||||
self.notebook_dir = os.path.abspath(new)
|
|
||||||
return
|
|
||||||
if os.path.exists(new) and not os.path.isdir(new):
|
|
||||||
raise TraitError("notebook dir %r is not a directory" % new)
|
|
||||||
if not os.path.exists(new):
|
|
||||||
self.log.info("Creating notebook dir %s", new)
|
|
||||||
try:
|
|
||||||
os.mkdir(new)
|
|
||||||
except:
|
|
||||||
raise TraitError("Couldn't create notebook dir %r" % new)
|
|
||||||
|
|
||||||
# Main notebook API
|
|
||||||
|
|
||||||
def increment_filename(self, basename, path=''):
|
|
||||||
"""Increment a notebook filename without the .ipynb to make it unique.
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
basename : unicode
|
|
||||||
The name of a notebook without the ``.ipynb`` file extension.
|
|
||||||
path : unicode
|
|
||||||
The URL path of the notebooks directory
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
name : unicode
|
|
||||||
A notebook name (with the .ipynb extension) that starts
|
|
||||||
with basename and does not refer to any existing notebook.
|
|
||||||
"""
|
|
||||||
path = path.strip('/')
|
|
||||||
for i in itertools.count():
|
|
||||||
name = u'{basename}{i}{ext}'.format(basename=basename, i=i,
|
|
||||||
ext=self.filename_ext)
|
|
||||||
if not self.notebook_exists(name, path):
|
|
||||||
break
|
|
||||||
return name
|
|
||||||
|
|
||||||
def notebook_exists(self, name, path=''):
|
def notebook_exists(self, name, path=''):
|
||||||
"""Returns a True if the notebook exists. Else, returns False.
|
"""Returns a True if the notebook exists. Else, returns False.
|
||||||
|
|
||||||
@ -207,6 +149,55 @@ class NotebookManager(LoggingConfigurable):
|
|||||||
"""Delete notebook by name and path."""
|
"""Delete notebook by name and path."""
|
||||||
raise NotImplementedError('must be implemented in a subclass')
|
raise NotImplementedError('must be implemented in a subclass')
|
||||||
|
|
||||||
|
def create_checkpoint(self, name, path=''):
|
||||||
|
"""Create a checkpoint of the current state of a notebook
|
||||||
|
|
||||||
|
Returns a checkpoint_id for the new checkpoint.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError("must be implemented in a subclass")
|
||||||
|
|
||||||
|
def list_checkpoints(self, name, path=''):
|
||||||
|
"""Return a list of checkpoints for a given notebook"""
|
||||||
|
return []
|
||||||
|
|
||||||
|
def restore_checkpoint(self, checkpoint_id, name, path=''):
|
||||||
|
"""Restore a notebook from one of its checkpoints"""
|
||||||
|
raise NotImplementedError("must be implemented in a subclass")
|
||||||
|
|
||||||
|
def delete_checkpoint(self, checkpoint_id, name, path=''):
|
||||||
|
"""delete a checkpoint for a notebook"""
|
||||||
|
raise NotImplementedError("must be implemented in a subclass")
|
||||||
|
|
||||||
|
def info_string(self):
|
||||||
|
return "Serving notebooks"
|
||||||
|
|
||||||
|
# NotebookManager API part 2: methods that have useable default
|
||||||
|
# implementations, but can be overridden in subclasses.
|
||||||
|
|
||||||
|
def increment_filename(self, basename, path=''):
|
||||||
|
"""Increment a notebook filename without the .ipynb to make it unique.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
basename : unicode
|
||||||
|
The name of a notebook without the ``.ipynb`` file extension.
|
||||||
|
path : unicode
|
||||||
|
The URL path of the notebooks directory
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
name : unicode
|
||||||
|
A notebook name (with the .ipynb extension) that starts
|
||||||
|
with basename and does not refer to any existing notebook.
|
||||||
|
"""
|
||||||
|
path = path.strip('/')
|
||||||
|
for i in itertools.count():
|
||||||
|
name = u'{basename}{i}{ext}'.format(basename=basename, i=i,
|
||||||
|
ext=self.filename_ext)
|
||||||
|
if not self.notebook_exists(name, path):
|
||||||
|
break
|
||||||
|
return name
|
||||||
|
|
||||||
def create_notebook(self, model=None, path=''):
|
def create_notebook(self, model=None, path=''):
|
||||||
"""Create a new notebook and return its model with no content."""
|
"""Create a new notebook and return its model with no content."""
|
||||||
path = path.strip('/')
|
path = path.strip('/')
|
||||||
@ -236,29 +227,43 @@ class NotebookManager(LoggingConfigurable):
|
|||||||
model = self.save_notebook(model, to_name, path)
|
model = self.save_notebook(model, to_name, path)
|
||||||
return model
|
return model
|
||||||
|
|
||||||
# Checkpoint-related
|
|
||||||
|
|
||||||
def create_checkpoint(self, name, path=''):
|
|
||||||
"""Create a checkpoint of the current state of a notebook
|
|
||||||
|
|
||||||
Returns a checkpoint_id for the new checkpoint.
|
|
||||||
"""
|
|
||||||
raise NotImplementedError("must be implemented in a subclass")
|
|
||||||
|
|
||||||
def list_checkpoints(self, name, path=''):
|
|
||||||
"""Return a list of checkpoints for a given notebook"""
|
|
||||||
return []
|
|
||||||
|
|
||||||
def restore_checkpoint(self, checkpoint_id, name, path=''):
|
|
||||||
"""Restore a notebook from one of its checkpoints"""
|
|
||||||
raise NotImplementedError("must be implemented in a subclass")
|
|
||||||
|
|
||||||
def delete_checkpoint(self, checkpoint_id, name, path=''):
|
|
||||||
"""delete a checkpoint for a notebook"""
|
|
||||||
raise NotImplementedError("must be implemented in a subclass")
|
|
||||||
|
|
||||||
def log_info(self):
|
def log_info(self):
|
||||||
self.log.info(self.info_string())
|
self.log.info(self.info_string())
|
||||||
|
|
||||||
def info_string(self):
|
# NotebookManager methods provided for use in subclasses.
|
||||||
return "Serving notebooks"
|
|
||||||
|
def check_and_sign(self, nb, path, name):
|
||||||
|
"""Check for trusted cells, and sign the notebook.
|
||||||
|
|
||||||
|
Called as a part of saving notebooks.
|
||||||
|
"""
|
||||||
|
if self.notary.check_cells(nb):
|
||||||
|
self.notary.sign(nb)
|
||||||
|
else:
|
||||||
|
self.log.warn("Saving untrusted notebook %s/%s", path, name)
|
||||||
|
|
||||||
|
def mark_trusted_cells(self, nb, path, name):
|
||||||
|
"""Mark cells as trusted if the notebook signature matches.
|
||||||
|
|
||||||
|
Called as a part of loading notebooks.
|
||||||
|
"""
|
||||||
|
trusted = self.notary.check_signature(nb)
|
||||||
|
if not trusted:
|
||||||
|
self.log.warn("Notebook %s/%s is not trusted", path, name)
|
||||||
|
self.notary.mark_cells(nb, trusted)
|
||||||
|
|
||||||
|
def _notebook_dir_changed(self, name, old, new):
|
||||||
|
"""Do a bit of validation of the notebook dir."""
|
||||||
|
if not os.path.isabs(new):
|
||||||
|
# If we receive a non-absolute path, make it absolute.
|
||||||
|
self.notebook_dir = os.path.abspath(new)
|
||||||
|
return
|
||||||
|
if os.path.exists(new) and not os.path.isdir(new):
|
||||||
|
raise TraitError("notebook dir %r is not a directory" % new)
|
||||||
|
if not os.path.exists(new):
|
||||||
|
self.log.info("Creating notebook dir %s", new)
|
||||||
|
try:
|
||||||
|
os.mkdir(new)
|
||||||
|
except:
|
||||||
|
raise TraitError("Couldn't create notebook dir %r" % new)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user