##// END OF EJS Templates
Merge pull request #6571 from Carreau/jsonable...
Merge pull request #6571 from Carreau/jsonable cast unicode to allow json dump

File last commit:

r17535:920c0ba6
r18042:0e7a4bfb merge
Show More
manager.py
333 lines | 10.6 KiB | text/x-python | PythonLexer
MinRK
rename notebooks service to contents service...
r17524 """A base class for contents managers."""
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
MinRK
rename notebooks service to contents service...
r17524 # Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
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
MinRK
support deleting empty directories...
r17530 from tornado.web import HTTPError
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
MinRK
rename notebooks service to contents service...
r17524 class ContentsManager(LoggingConfigurable):
MinRK
updates per review...
r17535 """Base class for serving files and directories.
This serves any text or binary file,
as well as directories,
with special handling for JSON notebook documents.
Most APIs take a path argument,
which is always an API-style unicode path,
and always refers to a directory.
- unicode, not url-escaped
- '/'-separated
- leading and trailing '/' will be stripped
- if unspecified, path defaults to '',
indicating the root path.
name is also unicode, and refers to a specfic target:
- unicode, not url-escaped
- must not contain '/'
- It refers to an individual filename
- It may refer to a directory name,
in the case of listing or creating directories.
"""
MinRK
mv services/notebooks services/contents
r17523
MinRK
add nbformat.sign.NotebookNotary
r14857 notary = Instance(sign.NotebookNotary)
def _notary_default(self):
return sign.NotebookNotary(parent=self)
MinRK
mv services/notebooks services/contents
r17523
MinRK
contents service review...
r17529 hide_globs = List(Unicode, [
u'__pycache__', '*.pyc', '*.pyo',
'.DS_Store', '*.so', '*.dylib', '*~',
], config=True, help="""
Thomas Kluyver
Make hidden directories configurable
r15525 Glob patterns to hide in file and directory listings.
""")
MinRK
updates per review...
r17535 untitled_notebook = Unicode("Untitled", config=True,
help="The base name used when creating untitled notebooks."
)
untitled_file = Unicode("untitled", config=True,
help="The base name used when creating untitled files."
)
untitled_directory = Unicode("Untitled Folder", config=True,
help="The base name used when creating untitled directories."
)
MinRK
rename notebooks service to contents service...
r17524 # ContentsManager API part 1: methods that must be
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 # 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
mv services/notebooks services/contents
r17523
MinRK
updates per review...
r17535 Like os.path.isdir
MinRK
move os_path to FileNBMan...
r13070 Override this method in subclasses.
MinRK
mv services/notebooks services/contents
r17523
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
mv services/notebooks services/contents
r17523
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?
MinRK
mv services/notebooks services/contents
r17523
Brian E. Granger
Creating and testing IPython.html.utils.is_hidden.
r15097 Parameters
----------
path : string
The path to check. This is an API path (`/` separated,
MinRK
rename notebooks service to contents service...
r17524 relative to root dir).
MinRK
mv services/notebooks services/contents
r17523
Brian E. Granger
Creating and testing IPython.html.utils.is_hidden.
r15097 Returns
-------
MinRK
updates per review...
r17535 hidden : bool
Brian E. Granger
Creating and testing IPython.html.utils.is_hidden.
r15097 Whether the path is hidden.
MinRK
mv services/notebooks services/contents
r17523
Brian E. Granger
Creating and testing IPython.html.utils.is_hidden.
r15097 """
raise NotImplementedError
MinRK
rename notebooks service to contents service...
r17524 def file_exists(self, name, path=''):
MinRK
updates per review...
r17535 """Does a file exist at the given name and path?
Like os.path.isfile
Override this method in subclasses.
Konrad Hinsen
Add method notebook_exists to NotebookManager....
r15291
Parameters
----------
name : string
MinRK
contents service review...
r17529 The name of the file you are checking.
Konrad Hinsen
Add method notebook_exists to NotebookManager....
r15291 path : string
MinRK
contents service review...
r17529 The relative path to the file's directory (with '/' as separator)
Konrad Hinsen
Add method notebook_exists to NotebookManager....
r15291
Returns
-------
MinRK
updates per review...
r17535 exists : bool
Whether the file exists.
Konrad Hinsen
Add method notebook_exists to NotebookManager....
r15291 """
raise NotImplementedError('must be implemented in a subclass')
MinRK
updates per review...
r17535 def exists(self, name, path=''):
"""Does a file or directory exist at the given name and path?
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
MinRK
updates per review...
r17535 Like os.path.exists
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
MinRK
updates per review...
r17535 Parameters
----------
name : string
The name of the file you are checking.
path : string
The relative path to the file's directory (with '/' as separator)
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
MinRK
updates per review...
r17535 Returns
-------
exists : bool
Whether the target exists.
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180 """
MinRK
updates per review...
r17535 return self.file_exists(name, path) or self.path_exists("%s/%s" % (path, name))
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
MinRK
rename notebooks service to contents service...
r17524 def get_model(self, name, path='', content=True):
MinRK
contents service review...
r17529 """Get the model of a file or directory with or without content."""
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180 raise NotImplementedError('must be implemented in a subclass')
MinRK
rename notebooks service to contents service...
r17524 def save(self, model, name, path=''):
MinRK
contents service review...
r17529 """Save the file or directory 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
MinRK
rename notebooks service to contents service...
r17524 def update(self, model, name, path=''):
MinRK
updates per review...
r17535 """Update the file or directory and return the model with no content.
For use in PATCH requests, to enable renaming a file without
re-uploading its contents. Only used for renaming at the moment.
"""
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180 raise NotImplementedError('must be implemented in a subclass')
MinRK
rename notebooks service to contents service...
r17524 def delete(self, name, path=''):
MinRK
contents service review...
r17529 """Delete file or directory 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=''):
MinRK
contents service review...
r17529 """Create a checkpoint of the current state of a file
MinRK
mv services/notebooks services/contents
r17523
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 Returns a checkpoint_id for the new checkpoint.
"""
raise NotImplementedError("must be implemented in a subclass")
MinRK
mv services/notebooks services/contents
r17523
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 def list_checkpoints(self, name, path=''):
MinRK
contents service review...
r17529 """Return a list of checkpoints for a given file"""
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 return []
MinRK
mv services/notebooks services/contents
r17523
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 def restore_checkpoint(self, checkpoint_id, name, path=''):
MinRK
contents service review...
r17529 """Restore a file from one of its checkpoints"""
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 raise NotImplementedError("must be implemented in a subclass")
def delete_checkpoint(self, checkpoint_id, name, path=''):
MinRK
contents service review...
r17529 """delete a checkpoint for a file"""
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 raise NotImplementedError("must be implemented in a subclass")
MinRK
mv services/notebooks services/contents
r17523
MinRK
rename notebooks service to contents service...
r17524 # ContentsManager API part 2: methods that have useable default
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 # implementations, but can be overridden in subclasses.
MinRK
updates per review...
r17535 def info_string(self):
return "Serving contents"
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
MinRK
rename notebooks service to contents service...
r17524 def increment_filename(self, filename, path=''):
"""Increment a filename until it is unique.
MinRK
mv services/notebooks services/contents
r17523
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 Parameters
----------
MinRK
rename notebooks service to contents service...
r17524 filename : unicode
The name of a file, including extension
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 path : unicode
MinRK
updates per review...
r17535 The API path of the target's directory
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293
Returns
-------
name : unicode
MinRK
rename notebooks service to contents service...
r17524 A filename that is unique, based on the input filename.
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 """
path = path.strip('/')
MinRK
rename notebooks service to contents service...
r17524 basename, ext = os.path.splitext(filename)
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 for i in itertools.count():
name = u'{basename}{i}{ext}'.format(basename=basename, i=i,
MinRK
rename notebooks service to contents service...
r17524 ext=ext)
if not self.file_exists(name, path):
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 break
return name
MinRK
add support and tests for uploading and saving regular files
r17527 def create_file(self, model=None, path='', ext='.ipynb'):
MinRK
contents service review...
r17529 """Create a new file or directory 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
updates per review...
r17532 if 'content' not in model and model.get('type', None) != 'directory':
MinRK
add support and tests for uploading and saving regular files
r17527 if ext == '.ipynb':
metadata = current.new_metadata(name=u'')
model['content'] = current.new_notebook(metadata=metadata)
MinRK
updates per review...
r17532 model['type'] = 'notebook'
model['format'] = 'json'
MinRK
add support and tests for uploading and saving regular files
r17527 else:
model['content'] = ''
MinRK
updates per review...
r17532 model['type'] = 'file'
model['format'] = 'text'
MinRK
update upload and copy...
r13074 if 'name' not in model:
MinRK
updates per review...
r17535 if model['type'] == 'directory':
untitled = self.untitled_directory
elif model['type'] == 'notebook':
untitled = self.untitled_notebook
elif model['type'] == 'file':
untitled = self.untitled_file
else:
raise HTTPError(400, "Unexpected model type: %r" % model['type'])
model['name'] = self.increment_filename(untitled + ext, path)
MinRK
mv services/notebooks services/contents
r17523
MinRK
update upload and copy...
r13074 model['path'] = path
MinRK
rename notebooks service to contents service...
r17524 model = self.save(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
rename notebooks service to contents service...
r17524 def copy(self, from_name, to_name=None, path=''):
"""Copy an existing file and return its new model.
MinRK
mv services/notebooks services/contents
r17523
MinRK
updates per review...
r17532 If to_name not specified, increment `from_name-Copy#.ext`.
MinRK
updates per review...
r17535
copy_from can be a full path to a file,
or just a base name. If a base name, `path` is used.
MinRK
allow specifying destination in copy_notebook
r13123 """
MinRK
ensure 'path' never has leading or trailing slash in nbmanager...
r13078 path = path.strip('/')
MinRK
updates per review...
r17535 if '/' in from_name:
from_path, from_name = from_name.rsplit('/', 1)
else:
from_path = path
model = self.get_model(from_name, from_path)
MinRK
support deleting empty directories...
r17530 if model['type'] == 'directory':
raise HTTPError(400, "Can't copy directories")
MinRK
allow specifying destination in copy_notebook
r13123 if not to_name:
MinRK
rename notebooks service to contents service...
r17524 base, ext = os.path.splitext(from_name)
copy_name = u'{0}-Copy{1}'.format(base, ext)
to_name = self.increment_filename(copy_name, path)
MinRK
allow specifying destination in copy_notebook
r13123 model['name'] = to_name
MinRK
updates per review...
r17535 model['path'] = path
MinRK
rename notebooks service to contents service...
r17524 model = self.save(model, to_name, path)
Zachary Sailer
refactoring of nbmanager and filenbmanager...
r13046 return model
MinRK
mv services/notebooks services/contents
r17523
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
mv services/notebooks services/contents
r17523
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 """
MinRK
teach contents service about non-notebook files
r17525 model = self.get_model(name, path)
MinRK
Add Trust Notebook to File menu
r15655 nb = model['content']
self.log.warn("Trusting notebook %s/%s", path, name)
self.notary.mark_cells(nb, True)
MinRK
rename notebooks service to contents service...
r17524 self.save(model, name, path)
MinRK
mv services/notebooks services/contents
r17523
MinRK
updates per review...
r17535 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
mv services/notebooks services/contents
r17523
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 Called as a part of saving notebooks.
MinRK
mv services/notebooks services/contents
r17523
MinRK
trust method docstrings
r15664 Parameters
----------
nb : dict
MinRK
updates per review...
r17535 The notebook object (in nbformat.current format)
MinRK
trust method docstrings
r15664 name : string
MinRK
updates per review...
r17535 The filename of the notebook (for logging)
MinRK
trust method docstrings
r15664 path : string
MinRK
updates per review...
r17535 The notebook's directory (for logging)
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
mv services/notebooks services/contents
r17523
MinRK
updates per review...
r17535 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.
MinRK
mv services/notebooks services/contents
r17523
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 Called as a part of loading notebooks.
MinRK
mv services/notebooks services/contents
r17523
MinRK
trust method docstrings
r15664 Parameters
----------
nb : dict
MinRK
updates per review...
r17535 The notebook object (in nbformat.current format)
MinRK
trust method docstrings
r15664 name : string
MinRK
updates per review...
r17535 The filename of the notebook (for logging)
MinRK
trust method docstrings
r15664 path : string
MinRK
updates per review...
r17535 The notebook's directory (for logging)
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)