Skip to content

Commit

Permalink
Restore pre/post_save_hook traits, add register_pre/post_save_hook()
Browse files Browse the repository at this point in the history
  • Loading branch information
davidbrochart committed Mar 8, 2022
1 parent f5688a7 commit adfe0d0
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 19 deletions.
3 changes: 0 additions & 3 deletions docs/source/developers/savehooks.rst
Expand Up @@ -16,9 +16,6 @@ They are both called with keyword arguments::
pre_save_hook(model=model, path=path, contents_manager=cm)
post_save_hook(model=model, os_path=os_path, contents_manager=cm)

Assigning to ``pre_save_hook`` (or ``post_save_hook``) multiple times will
register hooks, not override them. They will then be called sequentially.

Examples
--------

Expand Down
25 changes: 17 additions & 8 deletions jupyter_server/services/contents/filemanager.py
Expand Up @@ -82,16 +82,25 @@ def _validate_post_save_hook(self, proposal):
value = import_item(value)
if not callable(value):
raise TraitError("post_save_hook must be callable")
self._post_save_hooks.append(value)
return value

def register_post_save_hook(self, hook):
if isinstance(hook, str):
hook = import_item(hook)
if not callable(hook):
raise RuntimeError("post_save_hook must be callable")
self._post_save_hooks.append(hook)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._post_save_hooks = []

def run_post_save_hook(self, model, os_path):
"""Run the post-save hook if defined, and log errors"""
for post_save_hook in self._post_save_hooks:
def run_post_save_hooks(self, model, os_path):
"""Run the post-save hooks if any, and log errors"""
post_save_hooks = self._post_save_hooks
if self.post_save_hook:
post_save_hooks.append(self.post_save_hook)
for post_save_hook in post_save_hooks:
try:
self.log.debug("Running post-save hook on %s", os_path)
post_save_hook(os_path=os_path, model=model, contents_manager=self)
Expand Down Expand Up @@ -461,7 +470,7 @@ def save(self, model, path=""):
"""Save the file model and return the model with no content."""
path = path.strip("/")

self.run_pre_save_hook(model=model, path=path)
self.run_pre_save_hooks(model=model, path=path)

if "type" not in model:
raise web.HTTPError(400, "No file type provided")
Expand Down Expand Up @@ -501,7 +510,7 @@ def save(self, model, path=""):
if validation_message:
model["message"] = validation_message

self.run_post_save_hook(model=model, os_path=os_path)
self.run_post_save_hooks(model=model, os_path=os_path)

return model

Expand Down Expand Up @@ -787,7 +796,7 @@ async def save(self, model, path=""):

os_path = self._get_os_path(path)
self.log.debug("Saving %s", os_path)
self.run_pre_save_hook(model=model, path=path)
self.run_pre_save_hooks(model=model, path=path)

if "type" not in model:
raise web.HTTPError(400, "No file type provided")
Expand Down Expand Up @@ -824,7 +833,7 @@ async def save(self, model, path=""):
if validation_message:
model["message"] = validation_message

self.run_post_save_hook(model=model, os_path=os_path)
self.run_post_save_hooks(model=model, os_path=os_path)

return model

Expand Down
8 changes: 4 additions & 4 deletions jupyter_server/services/contents/largefilemanager.py
Expand Up @@ -18,7 +18,7 @@ def save(self, model, path=""):
if chunk is not None:
path = path.strip("/")

self.run_pre_save_hook(model=model, path=path)
self.run_pre_save_hooks(model=model, path=path)

if "type" not in model:
raise web.HTTPError(400, "No file type provided")
Expand Down Expand Up @@ -52,7 +52,7 @@ def save(self, model, path=""):

# Last chunk
if chunk == -1:
self.run_post_save_hook(model=model, os_path=os_path)
self.run_post_save_hooks(model=model, os_path=os_path)
return model
else:
return super(LargeFileManager, self).save(model, path)
Expand Down Expand Up @@ -91,7 +91,7 @@ async def save(self, model, path=""):

os_path = self._get_os_path(path)
self.log.debug("Saving %s", os_path)
self.run_pre_save_hook(model=model, path=path)
self.run_pre_save_hooks(model=model, path=path)

if "type" not in model:
raise web.HTTPError(400, "No file type provided")
Expand Down Expand Up @@ -122,7 +122,7 @@ async def save(self, model, path=""):

# Last chunk
if chunk == -1:
self.run_post_save_hook(model=model, os_path=os_path)
self.run_post_save_hooks(model=model, os_path=os_path)
return model
else:
return await super(AsyncLargeFileManager, self).save(model, path)
Expand Down
17 changes: 13 additions & 4 deletions jupyter_server/services/contents/manager.py
Expand Up @@ -126,16 +126,25 @@ def _validate_pre_save_hook(self, proposal):
value = import_item(self.pre_save_hook)
if not callable(value):
raise TraitError("pre_save_hook must be callable")
self._pre_save_hooks.append(value)
return value

def register_pre_save_hook(self, hook):
if isinstance(hook, str):
hook = import_item(hook)
if not callable(hook):
raise RuntimeError("pre_save_hook must be callable")
self._pre_save_hooks.append(hook)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._pre_save_hooks = []

def run_pre_save_hook(self, model, path, **kwargs):
"""Run the pre-save hook if defined, and log errors"""
for pre_save_hook in self._pre_save_hooks:
def run_pre_save_hooks(self, model, path, **kwargs):
"""Run the pre-save hooks if defined, and log errors"""
pre_save_hooks = self._pre_save_hooks
if self.pre_save_hook:
pre_save_hooks.append(self.pre_save_hook)
for pre_save_hook in pre_save_hooks:
try:
self.log.debug("Running pre-save hook on %s", path)
pre_save_hook(model=model, path=path, contents_manager=self, **kwargs)
Expand Down

0 comments on commit adfe0d0

Please sign in to comment.