##// END OF EJS Templates
fix github milestone link
fix github milestone link

File last commit:

r19839:6ab8853b
r20443:f6509fc5
Show More
manager.py
468 lines | 14.5 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
MinRK
add dialogs for failed save/load...
r18249 import json
Brian Granger
Fixing minor things for the Azure backed nb storage.
r8181 import os
Min RK
adjustments to filename increment...
r18813 import re
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
MinRK
support deleting empty directories...
r17530 from tornado.web import HTTPError
Scott Sanderson
STY: s/CheckpointManager/Checkpoints...
r19839 from .checkpoints import Checkpoints
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180 from IPython.config.configurable import LoggingConfigurable
MinRK
don't use nbformat.current in IPython.html...
r18607 from IPython.nbformat import sign, validate, ValidationError
from IPython.nbformat.v4 import new_notebook
Min RK
add pre/post-save hooks...
r19299 from IPython.utils.importstring import import_item
Scott Sanderson
DEV: Refactor checkpoint logic from FileContentsManager....
r19727 from IPython.utils.traitlets import (
Any,
Dict,
Instance,
List,
TraitError,
Type,
Unicode,
)
Min RK
add pre/post-save hooks...
r19299 from IPython.utils.py3compat import string_types
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
Min RK
adjustments to filename increment...
r18813 copy_pat = re.compile(r'\-Copy\d*\.')
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
Scott Sanderson
DEV: Refactor checkpoint logic from FileContentsManager....
r19727
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.
"""
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."
)
Min RK
add pre/post-save hooks...
r19299 pre_save_hook = Any(None, config=True,
help="""Python callable or importstring thereof
To be called on a contents model prior to save.
This can be used to process the structure,
such as removing notebook outputs or other side effects that
should not be saved.
It will be called as (all arguments passed by keyword):
hook(path=path, model=model, contents_manager=self)
model: the model to be saved. Includes file contents.
modifying this dict will affect the file that is stored.
path: the API path of the save destination
contents_manager: this ContentsManager instance
"""
)
def _pre_save_hook_changed(self, name, old, new):
if new and isinstance(new, string_types):
self.pre_save_hook = import_item(self.pre_save_hook)
elif new:
if not callable(new):
raise TraitError("pre_save_hook must be callable")
def run_pre_save_hook(self, model, path, **kwargs):
"""Run the pre-save hook if defined, and log errors"""
if self.pre_save_hook:
try:
self.log.debug("Running pre-save hook on %s", path)
self.pre_save_hook(model=model, path=path, contents_manager=self, **kwargs)
except Exception:
self.log.error("Pre-save hook failed on %s", path, exc_info=True)
Scott Sanderson
STY: s/CheckpointManager/Checkpoints...
r19839 checkpoints_class = Type(Checkpoints, config=True)
checkpoints = Instance(Checkpoints, config=True)
checkpoints_kwargs = Dict(allow_none=False, config=True)
Scott Sanderson
DEV: Refactor checkpoint logic from FileContentsManager....
r19727
Scott Sanderson
STY: s/CheckpointManager/Checkpoints...
r19839 def _checkpoints_default(self):
return self.checkpoints_class(**self.checkpoints_kwargs)
Scott Sanderson
DEV: Refactor checkpoint logic from FileContentsManager....
r19727
Scott Sanderson
STY: s/CheckpointManager/Checkpoints...
r19839 def _checkpoints_kwargs_default(self):
Scott Sanderson
DEV: Refactor checkpoint logic from FileContentsManager....
r19727 return dict(
parent=self,
log=self.log,
)
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
Remove separate 'path', 'name' in Contents API...
r18749 def dir_exists(self, path):
MinRK
adjust definition of 'path' in notebooks...
r13067 """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
Remove separate 'path', 'name' in Contents API...
r18749 def file_exists(self, path=''):
"""Does a file exist at the given path?
MinRK
updates per review...
r17535
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
Remove separate 'path', 'name' in Contents API...
r18749 def exists(self, path):
Min RK
address review in contents service...
r18758 """Does a file or directory exist at the given 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
----------
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
Remove separate 'path', 'name' in Contents API...
r18749 return self.file_exists(path) or self.dir_exists(path)
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
Min RK
ContentsManager type kwarg to match model key...
r19391 def get(self, path, content=True, type=None, format=None):
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
Remove separate 'path', 'name' in Contents API...
r18749 def save(self, model, path):
Min RK
add pre/post-save hooks...
r19299 """Save the file or directory and return the model with no content.
Save implementations should call self.run_pre_save_hook(model=model, path=path)
prior to writing any data.
"""
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
Scott Sanderson
DEV: Refactor checkpoint logic from FileContentsManager....
r19727 def delete_file(self, path):
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 """Delete file or directory by path."""
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180 raise NotImplementedError('must be implemented in a subclass')
Scott Sanderson
DEV: Refactor checkpoint logic from FileContentsManager....
r19727 def rename_file(self, old_path, new_path):
"""Rename a file."""
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.
Scott Sanderson
DEV: Refactor checkpoint logic from FileContentsManager....
r19727 def delete(self, path):
"""Delete a file/directory and any associated checkpoints."""
self.delete_file(path)
Scott Sanderson
STY: s/CheckpointManager/Checkpoints...
r19839 self.checkpoints.delete_all_checkpoints(path)
Scott Sanderson
DEV: Refactor checkpoint logic from FileContentsManager....
r19727
def rename(self, old_path, new_path):
"""Rename a file and any checkpoints associated with that file."""
self.rename_file(old_path, new_path)
Scott Sanderson
STY: s/CheckpointManager/Checkpoints...
r19839 self.checkpoints.rename_all_checkpoints(old_path, new_path)
Scott Sanderson
DEV: Refactor checkpoint logic from FileContentsManager....
r19727
Scott Sanderson
MAINT: Move `update` from FileContentsManager to ContentsManager....
r19712 def update(self, model, path):
"""Update the file's path
For use in PATCH requests, to enable renaming a file without
re-uploading its contents. Only used for renaming at the moment.
"""
path = path.strip('/')
new_path = model.get('path', path).strip('/')
if path != new_path:
self.rename(path, new_path)
model = self.get(new_path, content=False)
return model
MinRK
updates per review...
r17535 def info_string(self):
return "Serving contents"
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 def get_kernel_path(self, path, model=None):
Min RK
address review in contents service...
r18758 """Return the API path for the kernel
KernelManagers can turn this value into a filesystem path,
or ignore it altogether.
Thomas Kluyver
Clean up get_kernel_path logic
r19136
The default value here will start kernels in the directory of the
notebook server. FileContentsManager overrides this to use the
directory containing the notebook.
Min RK
address review in contents service...
r18758 """
Thomas Kluyver
Clean up get_kernel_path logic
r19136 return ''
Dale Jung
API: Allow NotebookManagers to control kernel startup dir. #5468
r16052
Min RK
adjustments to filename increment...
r18813 def increment_filename(self, filename, path='', insert=''):
MinRK
rename notebooks service to contents service...
r17524 """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():
Min RK
adjustments to filename increment...
r18813 if i:
insert_i = '{}{}'.format(insert, i)
else:
insert_i = ''
name = u'{basename}{insert}{ext}'.format(basename=basename,
insert=insert_i, ext=ext)
Min RK
address review in contents service...
r18758 if not self.exists(u'{}/{}'.format(path, name)):
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 break
return name
MinRK
add dialogs for failed save/load...
r18249 def validate_notebook_model(self, model):
"""Add failed-validation message to model"""
try:
MinRK
don't use nbformat.current in IPython.html...
r18607 validate(model['content'])
except ValidationError as e:
Min RK
unicode!
r18754 model['message'] = u'Notebook Validation failed: {}:\n{}'.format(
MinRK
add dialogs for failed save/load...
r18249 e.message, json.dumps(e.instance, indent=1, default=lambda obj: '<UNKNOWN>'),
)
return model
Min RK
split ContentsManager.new, add ContentsManager.new_untitled
r18759
def new_untitled(self, path='', type='', ext=''):
"""Create a new untitled file or directory in path
path must be a directory
File extension can be specified.
Use `new` to create files with a fully specified path (including filename).
"""
path = path.strip('/')
if not self.dir_exists(path):
raise HTTPError(404, 'No such directory: %s' % path)
model = {}
if type:
model['type'] = type
if ext == '.ipynb':
model.setdefault('type', 'notebook')
else:
model.setdefault('type', 'file')
Min RK
adjustments to filename increment...
r18813 insert = ''
Min RK
split ContentsManager.new, add ContentsManager.new_untitled
r18759 if model['type'] == 'directory':
untitled = self.untitled_directory
Min RK
adjustments to filename increment...
r18813 insert = ' '
Min RK
split ContentsManager.new, add ContentsManager.new_untitled
r18759 elif model['type'] == 'notebook':
untitled = self.untitled_notebook
ext = '.ipynb'
elif model['type'] == 'file':
untitled = self.untitled_file
else:
raise HTTPError(400, "Unexpected model type: %r" % model['type'])
Min RK
adjustments to filename increment...
r18813 name = self.increment_filename(untitled + ext, path, insert=insert)
Min RK
split ContentsManager.new, add ContentsManager.new_untitled
r18759 path = u'{0}/{1}'.format(path, name)
return self.new(model, path)
def new(self, model=None, path=''):
Min RK
address review in contents service...
r18758 """Create a new file or directory and return its model with no content.
Min RK
split ContentsManager.new, add ContentsManager.new_untitled
r18759 To create a new untitled entity in a directory, use `new_untitled`.
Min RK
address review in contents service...
r18758 """
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 = {}
Min RK
address review in contents service...
r18758
Min RK
split ContentsManager.new, add ContentsManager.new_untitled
r18759 if path.endswith('.ipynb'):
Min RK
address review in contents service...
r18758 model.setdefault('type', 'notebook')
Min RK
split ContentsManager.new, add ContentsManager.new_untitled
r18759 else:
model.setdefault('type', 'file')
Min RK
address review in contents service...
r18758
# no content, not a directory, so fill out new-file model
if 'content' not in model and model['type'] != 'directory':
if model['type'] == 'notebook':
MinRK
don't use nbformat.current in IPython.html...
r18607 model['content'] = new_notebook()
MinRK
updates per review...
r17532 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'
Min RK
address review in contents service...
r18758
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 model = self.save(model, path)
Zachary Sailer
refactoring of nbmanager and filenbmanager...
r13046 return model
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 def copy(self, from_path, to_path=None):
MinRK
rename notebooks service to contents service...
r17524 """Copy an existing file and return its new model.
MinRK
mv services/notebooks services/contents
r17523
Min RK
address review in contents service...
r18758 If to_path not specified, it will be the parent directory of from_path.
If to_path is a directory, filename will increment `from_path-Copy#.ext`.
MinRK
updates per review...
r17535
Min RK
address review in contents service...
r18758 from_path must be a full path to a file.
MinRK
allow specifying destination in copy_notebook
r13123 """
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 path = from_path.strip('/')
Scott Sanderson
BUG: Sanitize to_path in ContentsManager.copy....
r19606 if to_path is not None:
to_path = to_path.strip('/')
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 if '/' in path:
from_dir, from_name = path.rsplit('/', 1)
MinRK
updates per review...
r17535 else:
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 from_dir = ''
from_name = path
Thomas Kluyver
Rename get_model() to get()
r18791 model = self.get(path)
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 model.pop('path', None)
model.pop('name', None)
MinRK
support deleting empty directories...
r17530 if model['type'] == 'directory':
raise HTTPError(400, "Can't copy directories")
MinRK
Remove separate 'path', 'name' in Contents API...
r18749
Scott Sanderson
BUG: Allow for the possibility that to_path is empty string....
r19607 if to_path is None:
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 to_path = from_dir
if self.dir_exists(to_path):
Min RK
adjustments to filename increment...
r18813 name = copy_pat.sub(u'.', from_name)
to_name = self.increment_filename(name, to_path, insert='-Copy')
Min RK
unicode!
r18754 to_path = u'{0}/{1}'.format(to_path, to_name)
MinRK
Remove separate 'path', 'name' in Contents API...
r18749
model = self.save(model, to_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
Remove separate 'path', 'name' in Contents API...
r18749 def trust_notebook(self, path):
MinRK
trust method docstrings
r15664 """Explicitly trust a notebook
MinRK
mv services/notebooks services/contents
r17523
MinRK
trust method docstrings
r15664 Parameters
----------
path : string
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 The path of a notebook
MinRK
Add Trust Notebook to File menu
r15655 """
Thomas Kluyver
Rename get_model() to get()
r18791 model = self.get(path)
MinRK
Add Trust Notebook to File menu
r15655 nb = model['content']
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 self.log.warn("Trusting notebook %s", path)
MinRK
Add Trust Notebook to File menu
r15655 self.notary.mark_cells(nb, True)
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 self.save(model, path)
MinRK
mv services/notebooks services/contents
r17523
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 def check_and_sign(self, nb, 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
restore ability to sign v3 notebooks
r18612 The notebook dict
MinRK
trust method docstrings
r15664 path : string
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 The notebook's path (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:
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 self.log.warn("Saving untrusted notebook %s", path)
MinRK
mv services/notebooks services/contents
r17523
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 def mark_trusted_cells(self, nb, 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
don't use nbformat.current in IPython.html...
r18607 The notebook object (in current nbformat)
MinRK
trust method docstrings
r15664 path : string
Min RK
address review in contents service...
r18758 The notebook's path (for logging)
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 """
trusted = self.notary.check_signature(nb)
if not trusted:
MinRK
Remove separate 'path', 'name' in Contents API...
r18749 self.log.warn("Notebook %s is not trusted", path)
Konrad Hinsen
Rearrange the NotebookManager methods for clarity...
r15293 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)
Scott Sanderson
DEV: Refactor checkpoint logic from FileContentsManager....
r19727
# Part 3: Checkpoints API
def create_checkpoint(self, path):
Scott Sanderson
DEV: More checkpoint API refactoring....
r19747 """Create a checkpoint."""
Scott Sanderson
STY: s/CheckpointManager/Checkpoints...
r19839 return self.checkpoints.create_checkpoint(self, path)
Scott Sanderson
DEV: Refactor checkpoint logic from FileContentsManager....
r19727
def restore_checkpoint(self, checkpoint_id, path):
Scott Sanderson
DEV: More checkpoint API refactoring....
r19747 """
Restore a checkpoint.
"""
Scott Sanderson
STY: s/CheckpointManager/Checkpoints...
r19839 self.checkpoints.restore_checkpoint(self, checkpoint_id, path)
Scott Sanderson
DEV: Allow CheckpointManagers to optimize for shared backends....
r19828
def list_checkpoints(self, path):
Scott Sanderson
STY: s/CheckpointManager/Checkpoints...
r19839 return self.checkpoints.list_checkpoints(path)
Scott Sanderson
DEV: More checkpoint API refactoring....
r19747
Scott Sanderson
DEV: Refactor checkpoint logic from FileContentsManager....
r19727 def delete_checkpoint(self, checkpoint_id, path):
Scott Sanderson
STY: s/CheckpointManager/Checkpoints...
r19839 return self.checkpoints.delete_checkpoint(checkpoint_id, path)