##// END OF EJS Templates
API: Allow NotebookManagers to control kernel startup dir. #5468
API: Allow NotebookManagers to control kernel startup dir. #5468

File last commit:

r16052:538b918c
r16052:538b918c
Show More
nbmanager.py
287 lines | 9.5 KiB | text/x-python | PythonLexer
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180 """A base class notebook manager.
Authors:
* Brian Granger
Zachary Sailer
refactoring of nbmanager and filenbmanager...
r13046 * Zach Sailer
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180 """
#-----------------------------------------------------------------------------
# Copyright (C) 2011 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
Thomas Kluyver
Make hidden directories configurable
r15525 from fnmatch import fnmatch
Konrad Hinsen
Move method increment_filename from FileNotebookManager to NotebookManager...
r15292 import itertools
Brian Granger
Fixing minor things for the Azure backed nb storage.
r8181 import os
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
from IPython.config.configurable import LoggingConfigurable
MinRK
add nbformat.sign.NotebookNotary
r14857 from IPython.nbformat import current, sign
Thomas Kluyver
Make hidden directories configurable
r15525 from IPython.utils.traitlets import Instance, Unicode, List
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
#-----------------------------------------------------------------------------
# Classes
#-----------------------------------------------------------------------------
Brian Granger
Renaming BaseNotebookManager->NotebookManager to preserve config.
r8194 class NotebookManager(LoggingConfigurable):
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
Zachary Sailer
refactoring of nbmanager and filenbmanager...
r13046 filename_ext = Unicode(u'.ipynb')
MinRK
adjust definition of 'path' in notebooks...
r13067
MinRK
add nbformat.sign.NotebookNotary
r14857 notary = Instance(sign.NotebookNotary)
def _notary_default(self):
return sign.NotebookNotary(parent=self)
MinRK
sign notebooks
r14856
Thomas Kluyver
Make hidden directories configurable
r15525 hide_globs = List(Unicode, [u'__pycache__'], config=True, help="""
Glob patterns to hide in file and directory listings.
""")
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 # NotebookManager API part 1: methods that must be
# implemented in subclasses.
MinRK
adjust definition of 'path' in notebooks...
r13067 def path_exists(self, path):
"""Does the API-style path (directory) actually exist?
MinRK
move os_path to FileNBMan...
r13070 Override this method in subclasses.
MinRK
adjust definition of 'path' in notebooks...
r13067
Paul Ivanov
cleaning up named_notebook_path
r13026 Parameters
----------
MinRK
adjust definition of 'path' in notebooks...
r13067 path : string
MinRK
trust method docstrings
r15664 The path to check
MinRK
adjust definition of 'path' in notebooks...
r13067
Paul Ivanov
cleaning up named_notebook_path
r13026 Returns
-------
MinRK
adjust definition of 'path' in notebooks...
r13067 exists : bool
Whether the path does indeed exist.
Paul Ivanov
cleaning up named_notebook_path
r13026 """
MinRK
move os_path to FileNBMan...
r13070 raise NotImplementedError
Brian E. Granger
Creating and testing IPython.html.utils.is_hidden.
r15097
def is_hidden(self, path):
"""Does the API style path correspond to a hidden directory or file?
Parameters
----------
path : string
The path to check. This is an API path (`/` separated,
relative to base notebook-dir).
Returns
-------
exists : bool
Whether the path is hidden.
"""
raise NotImplementedError
Konrad Hinsen
Add method notebook_exists to NotebookManager....
r15291 def notebook_exists(self, name, path=''):
"""Returns a True if the notebook exists. Else, returns False.
Parameters
----------
name : string
The name of the notebook you are checking.
path : string
The relative path to the notebook (with '/' as separator)
Returns
-------
bool
"""
raise NotImplementedError('must be implemented in a subclass')
Brian E. Granger
Addressing review comments....
r15093 # TODO: Remove this after we create the contents web service and directories are
# no longer listed by the notebook web service.
def list_dirs(self, path):
"""List the directory models for a given API style path."""
raise NotImplementedError('must be implemented in a subclass')
# TODO: Remove this after we create the contents web service and directories are
# no longer listed by the notebook web service.
def get_dir_model(self, name, path=''):
"""Get the directory model given a directory name and its API style path.
The keys in the model should be:
* name
* path
* last_modified
* created
* type='directory'
"""
raise NotImplementedError('must be implemented in a subclass')
MinRK
update upload and copy...
r13074 def list_notebooks(self, path=''):
Zachary Sailer
refactoring of nbmanager and filenbmanager...
r13046 """Return a list of notebook dicts without content.
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
This returns a list of dicts, each of the form::
dict(notebook_id=notebook,name=name)
This list of dicts should be sorted by name::
data = sorted(data, key=lambda item: item['name'])
"""
raise NotImplementedError('must be implemented in a subclass')
Konrad Hinsen
NotebookManager API: rename *notebook_model methods to *notebook
r15290 def get_notebook(self, name, path='', content=True):
Zachary Sailer
refactoring of nbmanager and filenbmanager...
r13046 """Get the notebook model with or without content."""
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180 raise NotImplementedError('must be implemented in a subclass')
Konrad Hinsen
NotebookManager API: rename *notebook_model methods to *notebook
r15290 def save_notebook(self, model, name, path=''):
"""Save the notebook and return the model with no content."""
Zachary Sailer
refactoring of nbmanager and filenbmanager...
r13046 raise NotImplementedError('must be implemented in a subclass')
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
Konrad Hinsen
NotebookManager API: rename *notebook_model methods to *notebook
r15290 def update_notebook(self, model, name, path=''):
"""Update the notebook and return the model with no content."""
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180 raise NotImplementedError('must be implemented in a subclass')
Konrad Hinsen
NotebookManager API: rename *notebook_model methods to *notebook
r15290 def delete_notebook(self, name, path=''):
Zachary Sailer
refactoring of nbmanager and filenbmanager...
r13046 """Delete notebook by name and path."""
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180 raise NotImplementedError('must be implemented in a subclass')
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 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.
Dale Jung
API: Allow NotebookManagers to control kernel startup dir. #5468
r16052 def get_kernel_path(self, name, path='', model=None):
""" Return the path to start kernel in """
return path
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 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
Konrad Hinsen
NotebookManager API: rename *notebook_model methods to *notebook
r15290 def create_notebook(self, model=None, path=''):
MinRK
notebooks should always have one checkpoint...
r13245 """Create a new notebook and return its model with no content."""
MinRK
ensure 'path' never has leading or trailing slash in nbmanager...
r13078 path = path.strip('/')
Zachary Sailer
refactoring of nbmanager and filenbmanager...
r13046 if model is None:
model = {}
MinRK
update upload and copy...
r13074 if 'content' not in model:
Zachary Sailer
refactoring of nbmanager and filenbmanager...
r13046 metadata = current.new_metadata(name=u'')
MinRK
update upload and copy...
r13074 model['content'] = current.new_notebook(metadata=metadata)
if 'name' not in model:
model['name'] = self.increment_filename('Untitled', path)
model['path'] = path
Konrad Hinsen
NotebookManager API: rename *notebook_model methods to *notebook
r15290 model = self.save_notebook(model, model['name'], model['path'])
Zachary Sailer
refactoring of nbmanager and filenbmanager...
r13046 return model
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
MinRK
allow specifying destination in copy_notebook
r13123 def copy_notebook(self, from_name, to_name=None, path=''):
"""Copy an existing notebook and return its new model.
If to_name not specified, increment `from_name-Copy#.ipynb`.
"""
MinRK
ensure 'path' never has leading or trailing slash in nbmanager...
r13078 path = path.strip('/')
Konrad Hinsen
NotebookManager API: rename *notebook_model methods to *notebook
r15290 model = self.get_notebook(from_name, path)
MinRK
allow specifying destination in copy_notebook
r13123 if not to_name:
base = os.path.splitext(from_name)[0] + '-Copy'
to_name = self.increment_filename(base, path)
model['name'] = to_name
Konrad Hinsen
NotebookManager API: rename *notebook_model methods to *notebook
r15290 model = self.save_notebook(model, to_name, path)
Zachary Sailer
refactoring of nbmanager and filenbmanager...
r13046 return model
MinRK
add checkpoint API to FileNBManager
r10497
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 def log_info(self):
self.log.info(self.info_string())
MinRK
Add Trust Notebook to File menu
r15655 def trust_notebook(self, name, path=''):
MinRK
trust method docstrings
r15664 """Explicitly trust a notebook
MinRK
Add Trust Notebook to File menu
r15655
MinRK
trust method docstrings
r15664 Parameters
----------
name : string
The filename of the notebook
path : string
The notebook's directory
MinRK
Add Trust Notebook to File menu
r15655 """
model = self.get_notebook(name, path)
nb = model['content']
self.log.warn("Trusting notebook %s/%s", path, name)
self.notary.mark_cells(nb, True)
self.save_notebook(model, name, path)
def check_and_sign(self, nb, name, path=''):
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 """Check for trusted cells, and sign the notebook.
MinRK
add checkpoint API to FileNBManager
r10497
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 Called as a part of saving notebooks.
MinRK
trust method docstrings
r15664
Parameters
----------
nb : dict
The notebook structure
name : string
The filename of the notebook
path : string
The notebook's directory
MinRK
add checkpoint API to FileNBManager
r10497 """
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 if self.notary.check_cells(nb):
self.notary.sign(nb)
else:
self.log.warn("Saving untrusted notebook %s/%s", path, name)
MinRK
add checkpoint API to FileNBManager
r10497
MinRK
Add Trust Notebook to File menu
r15655 def mark_trusted_cells(self, nb, name, path=''):
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 """Mark cells as trusted if the notebook signature matches.
Called as a part of loading notebooks.
MinRK
trust method docstrings
r15664
Parameters
----------
nb : dict
The notebook structure
name : string
The filename of the notebook
path : string
The notebook's directory
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 """
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)
Brian Granger
Fixing minor things for the Azure backed nb storage.
r8181
Thomas Kluyver
Make hidden directories configurable
r15525 def should_list(self, name):
"""Should this file/directory name be displayed in a listing?"""
return not any(fnmatch(name, glob) for glob in self.hide_globs)