Skip to content

Commit

Permalink
Move hooks to VoilaConfiguration
Browse files Browse the repository at this point in the history
  • Loading branch information
trungleduc committed Oct 10, 2024
1 parent d8f0cbf commit 7dfaa05
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 91 deletions.
16 changes: 8 additions & 8 deletions docs/customize.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,8 @@ def page_config_hook_function(current_page_config,**kwargs):
"""Modify the current_page_config"""
return new_page_config

c.Voila.prelaunch_hook = hook_function
c.Voila.page_config_hook = page_config_hook
c.VoilaConfiguration.prelaunch_hook = hook_function
c.VoilaConfiguration.page_config_hook = page_config_hook

```

Expand Down Expand Up @@ -374,18 +374,18 @@ from voila.config import VoilaConfiguration
# customize config how you like
config = VoilaConfiguration()

# set the prelaunch hook
config.prelaunch_hook = parameterize_with_papermill

# set the page config hook
config.config_page_hook = page_config_hook

# create a voila instance
app = Voila()

# set the config
app.voila_configuration = config

# set the prelaunch hook
app.prelaunch_hook = parameterize_with_papermill

# set the page config hook
app.config_page_hook = page_config_hook

# launch
app.start()
```
Expand Down
69 changes: 6 additions & 63 deletions voila/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@

from traitlets import (
Bool,
Callable,
Dict,
Integer,
List,
Expand Down Expand Up @@ -193,6 +192,8 @@ class Voila(Application):
"theme": "VoilaConfiguration.theme",
"classic_tree": "VoilaConfiguration.classic_tree",
"kernel_spec_manager_class": "VoilaConfiguration.kernel_spec_manager_class",
"prelaunch_hook": "VoilaConfiguration.prelaunch_hook", # For backward compatibility
"page_config_hook": "VoilaConfiguration.page_config_hook",
}
if JUPYTER_SERVER_2:
aliases = {**aliases, "token": "Voila.token"}
Expand Down Expand Up @@ -325,54 +326,6 @@ class Voila(Application):
),
)

prelaunch_hook = Callable(
default_value=None,
allow_none=True,
config=True,
help=_(
"""A function that is called prior to the launch of a new kernel instance
when a user visits the voila webpage. Used for custom user authorization
or any other necessary pre-launch functions.
Should be of the form:
def hook(req: tornado.web.RequestHandler,
notebook: nbformat.NotebookNode,
cwd: str)
Although most customizations can leverage templates, if you need access
to the request object (e.g. to inspect cookies for authentication),
or to modify the notebook itself (e.g. to inject some custom structure,
although much of this can be done by interacting with the kernel
in javascript) the prelaunch hook lets you do that.
"""
),
)

page_config_hook = Callable(
default_value=None,
allow_none=True,
config=True,
help=_(
"""A function that is called to modify the page config for a given notebook.
Should be of the form:
def page_config_hook(
current_page_config: Dict[str, Any],
base_url: str,
settings: Dict[str, Any],
log: Logger,
voila_configuration: VoilaConfiguration,
notebook_path: str
) -> Dict[str, Any]:
The hook receives the default page_config dictionary and all its parameters, it should
return a dictionary that will be passed to the template as the `page_config` variable
and the NotebookRenderer. This can be used to pass custom configuration.
"""
),
)

if JUPYTER_SERVER_2:
cookie_secret = Bytes(
b"",
Expand Down Expand Up @@ -632,14 +585,14 @@ def init_settings(self) -> Dict:
preheat_kernel: bool = self.voila_configuration.preheat_kernel
pool_size: int = self.voila_configuration.default_pool_size

if preheat_kernel and self.prelaunch_hook:
if preheat_kernel and self.voila_configuration.prelaunch_hook:
raise Exception("`preheat_kernel` and `prelaunch_hook` are incompatible")

kernel_manager_class = voila_kernel_manager_factory(
self.voila_configuration.multi_kernel_manager_class,
preheat_kernel,
pool_size,
page_config_hook=self.page_config_hook,
page_config_hook=self.voila_configuration.page_config_hook,
)
self.kernel_manager = kernel_manager_class(
parent=self,
Expand Down Expand Up @@ -814,8 +767,6 @@ def init_handlers(self) -> List:
"template_paths": self.template_paths,
"config": self.config,
"voila_configuration": self.voila_configuration,
"prelaunch_hook": self.prelaunch_hook,
"page_config_hook": self.page_config_hook,
},
)
)
Expand All @@ -826,18 +777,12 @@ def init_handlers(self) -> List:
(
self.server_url,
TornadoVoilaTreeHandler,
{
"voila_configuration": self.voila_configuration,
"page_config_hook": self.page_config_hook,
},
{"voila_configuration": self.voila_configuration},
),
(
url_path_join(self.server_url, r"/voila/tree" + path_regex),
TornadoVoilaTreeHandler,
{
"voila_configuration": self.voila_configuration,
"page_config_hook": self.page_config_hook,
},
{"voila_configuration": self.voila_configuration},
),
(
url_path_join(self.server_url, r"/voila/render/(.*)"),
Expand All @@ -846,8 +791,6 @@ def init_handlers(self) -> List:
"template_paths": self.template_paths,
"config": self.config,
"voila_configuration": self.voila_configuration,
"prelaunch_hook": self.prelaunch_hook,
"page_config_hook": self.page_config_hook,
},
),
# On serving a directory, expose the content handler.
Expand Down
46 changes: 45 additions & 1 deletion voila/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#############################################################################

import traitlets.config
from traitlets import Bool, Dict, Enum, Int, List, Type, Unicode, validate
from traitlets import Bool, Callable, Dict, Enum, Int, List, Type, Unicode, validate

from warnings import warn

Expand Down Expand Up @@ -217,3 +217,47 @@ def _valid_file_blacklist(self, proposal):
config=True,
help="""Whether or not voila should attempt to fix and resolve a notebooks kernelspec metadata""",
)

prelaunch_hook = Callable(
default_value=None,
allow_none=True,
config=True,
help="""A function that is called prior to the launch of a new kernel instance
when a user visits the voila webpage. Used for custom user authorization
or any other necessary pre-launch functions.
Should be of the form:
def hook(req: tornado.web.RequestHandler,
notebook: nbformat.NotebookNode,
cwd: str)
Although most customizations can leverage templates, if you need access
to the request object (e.g. to inspect cookies for authentication),
or to modify the notebook itself (e.g. to inject some custom structure,
although much of this can be done by interacting with the kernel
in javascript) the prelaunch hook lets you do that.
""",
)

page_config_hook = Callable(
default_value=None,
allow_none=True,
config=True,
help="""A function that is called to modify the page config for a given notebook.
Should be of the form:
def page_config_hook(
current_page_config: Dict[str, Any],
base_url: str,
settings: Dict[str, Any],
log: Logger,
voila_configuration: VoilaConfiguration,
notebook_path: str
) -> Dict[str, Any]:
The hook receives the default page_config dictionary and all its parameters, it should
return a dictionary that will be passed to the template as the `page_config` variable
and the NotebookRenderer. This can be used to pass custom configuration.
""",
)
4 changes: 2 additions & 2 deletions voila/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ def initialize(self, **kwargs):
self.template_paths = kwargs.pop("template_paths", [])
self.traitlet_config = kwargs.pop("config", None)
self.voila_configuration: VoilaConfiguration = kwargs["voila_configuration"]
self.prelaunch_hook = kwargs.get("prelaunch_hook", None)
self.page_config_hook = kwargs.get("page_config_hook", None)
self.prelaunch_hook = self.voila_configuration.prelaunch_hook
self.page_config_hook = self.voila_configuration.page_config_hook

# we want to avoid starting multiple kernels due to template mistakes
self.kernel_started = False
Expand Down
2 changes: 1 addition & 1 deletion voila/notebook_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def __init__(self, **kwargs):
self.config_manager = kwargs.get("config_manager")
self.contents_manager = kwargs.get("contents_manager")
self.kernel_spec_manager = kwargs.get("kernel_spec_manager")
self.prelaunch_hook = kwargs.get("prelaunch_hook")
self.prelaunch_hook = self.voila_configuration.prelaunch_hook
self.base_url = kwargs.get("base_url")
self.page_config = deepcopy(kwargs.get("page_config"))
self.default_kernel_name = "python3"
Expand Down
18 changes: 5 additions & 13 deletions voila/server_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,6 @@ def _load_jupyter_server_extension(server_app: ServerApp):
voila_configuration = VoilaConfiguration(
parent=server_app, config=load_config_file()
)
page_config_hook = voila_configuration.config.Voila.get("page_config_hook", None)
prelaunch_hook = voila_configuration.config.Voila.get("prelaunch_hook", None)

template_name = voila_configuration.template
template_paths = collect_template_paths(["voila", "nbconvert"], template_name)
Expand All @@ -104,6 +102,8 @@ def _load_jupyter_server_extension(server_app: ServerApp):
host_pattern = ".*$"
base_url = url_path_join(web_app.settings["base_url"])

tree_handler_conf = {"voila_configuration": voila_configuration}

themes_dir = pjoin(get_data_dir(), "themes")
web_app.add_handlers(
host_pattern,
Expand All @@ -115,25 +115,17 @@ def _load_jupyter_server_extension(server_app: ServerApp):
"config": server_app.config,
"template_paths": template_paths,
"voila_configuration": voila_configuration,
"prelaunch_hook": prelaunch_hook,
"page_config_hook": page_config_hook,
},
),
(
url_path_join(base_url, "/voila"),
TornadoVoilaTreeHandler,
{
"voila_configuration": voila_configuration,
"page_config_hook": page_config_hook,
},
tree_handler_conf,
),
(
url_path_join(base_url, "/voila/tree" + path_regex),
TornadoVoilaTreeHandler,
{
"voila_configuration": voila_configuration,
"page_config_hook": page_config_hook,
},
tree_handler_conf,
),
(
url_path_join(base_url, "/voila/templates/(.*)"),
Expand Down Expand Up @@ -170,7 +162,7 @@ def _load_jupyter_server_extension(server_app: ServerApp):
(
url_path_join(base_url, r"/voila/api/contents%s" % path_regex),
VoilaContentsHandler,
{"voila_configuration": voila_configuration},
tree_handler_conf,
),
],
)
Expand Down
2 changes: 1 addition & 1 deletion voila/tornado/treehandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
class TornadoVoilaTreeHandler(VoilaTreeHandler):
def initialize(self, **kwargs):
super().initialize(**kwargs)
self.page_config_hook = kwargs.get("page_config_hook", None)
self.page_config_hook = self.voila_configuration.page_config_hook

@web.authenticated
async def get(self, path=""):
Expand Down
4 changes: 2 additions & 2 deletions voila/voila_kernel_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import os
import re
from pathlib import Path
from typing import Awaitable, Callable
from typing import Awaitable, Callable, Optional
from typing import Dict as TypeDict
from typing import List as TypeList
from typing import Tuple, Type, TypeVar, Union
Expand All @@ -37,7 +37,7 @@ def voila_kernel_manager_factory(
base_class: Type[T],
preheat_kernel: bool,
default_pool_size: int,
page_config_hook: Callable = None,
page_config_hook: Optional[Callable] = None,
) -> T:
"""
Decorator used to make a normal kernel manager compatible with pre-heated
Expand Down

0 comments on commit 7dfaa05

Please sign in to comment.