Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show the list of voila kernels in the running tabs #611

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/jupyterlab-voila/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
"@jupyterlab/fileeditor": "^2.0.0",
"@jupyterlab/mainmenu": "^2.0.0",
"@jupyterlab/notebook": "^2.0.0",
"@jupyterlab/running": "^2.1.1",
"@jupyterlab/services": "^5.0.0",
"@jupyterlab/ui-components": "^2.1.1",
"react": "~16.9.0",
"react-dom": "~16.9.0"
},
Expand Down
63 changes: 59 additions & 4 deletions packages/jupyterlab-voila/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ import {
INotebookModel
} from "@jupyterlab/notebook";

import { IRunningSessionManagers, IRunningSessions } from "@jupyterlab/running";

import { KernelAPI, KernelManager, ServerConnection } from "@jupyterlab/services";

import { notebookIcon } from "@jupyterlab/ui-components";

import { toArray } from "@lumino/algorithm";

import { CommandRegistry } from "@lumino/commands";

import { ReadonlyJSONObject } from "@lumino/coreutils";
Expand Down Expand Up @@ -81,9 +89,9 @@ class VoilaRenderButton
}

/**
* Initialization data for the jupyterlab-voila extension.
* Initialization data for the jupyterlab-voila preview plugin.
*/
const extension: JupyterFrontEndPlugin<IVoilaPreviewTracker> = {
const preview: JupyterFrontEndPlugin<IVoilaPreviewTracker> = {
id: "@jupyter-voila/jupyterlab-preview:plugin",
autoStart: true,
requires: [INotebookTracker],
Expand Down Expand Up @@ -158,7 +166,7 @@ const extension: JupyterFrontEndPlugin<IVoilaPreviewTracker> = {
};

if (settingRegistry) {
Promise.all([settingRegistry.load(extension.id), app.restored])
Promise.all([settingRegistry.load(preview.id), app.restored])
.then(([settings]) => {
updateSettings(settings);
settings.changed.connect(updateSettings);
Expand Down Expand Up @@ -235,4 +243,51 @@ const extension: JupyterFrontEndPlugin<IVoilaPreviewTracker> = {
}
};

export default extension;
/**
* A plugin to show the list of running Voila kernels.
*/
const kernels: JupyterFrontEndPlugin<void> = {
id: "@jupyter-voila/jupyterlab-preview:kernels",
autoStart: true,
requires: [IRunningSessionManagers],
activate: (app: JupyterFrontEnd, managers: IRunningSessionManagers) => {
const serverSettings = ServerConnection.makeSettings({ baseUrl: "/voila" });
const kernelManager = new KernelManager({ serverSettings });

managers.add({
name: "Voila",
running: () => {
return toArray(kernelManager.running())
.map(model => new RunningKernel(model));
},
shutdownAll: () => kernelManager.shutdownAll(),
refreshRunning: () => kernelManager.refreshRunning(),
runningChanged: kernelManager.runningChanged
});

class RunningKernel implements IRunningSessions.IRunningItem {
constructor(model: KernelAPI.IModel) {
this._model = model;
}
open() {
// no-op
}
shutdown() {
return kernelManager.shutdown(this._model.id);
}
icon() {
return notebookIcon;
}
label() {
return this._model.id;
}
labelTitle() {
return `name: ${this._model.name}`;
}

private _model: KernelAPI.IModel;
}
}
};

export default [preview, kernels];
55 changes: 54 additions & 1 deletion packages/jupyterlab-voila/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,31 @@
react-dom "~16.9.0"
sanitize-html "~1.20.1"

"@jupyterlab/apputils@^2.1.1":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@jupyterlab/apputils/-/apputils-2.1.1.tgz#069dc8214261c01c9e2ef58209137430649d4c01"
integrity sha512-orGzvW2S1k/FjW42dhygq8XJZbQRBTsNXXKFWsqewSn9sNTd3irKjDEwS3Ilce1w+LsS/t3H03xCnsOYPu8LSQ==
dependencies:
"@jupyterlab/coreutils" "^4.1.0"
"@jupyterlab/services" "^5.1.0"
"@jupyterlab/settingregistry" "^2.1.0"
"@jupyterlab/statedb" "^2.1.0"
"@jupyterlab/ui-components" "^2.1.1"
"@lumino/algorithm" "^1.2.3"
"@lumino/commands" "^1.10.1"
"@lumino/coreutils" "^1.4.2"
"@lumino/disposable" "^1.3.5"
"@lumino/domutils" "^1.1.7"
"@lumino/messaging" "^1.3.3"
"@lumino/properties" "^1.1.6"
"@lumino/signaling" "^1.3.5"
"@lumino/virtualdom" "^1.6.1"
"@lumino/widgets" "^1.11.1"
"@types/react" "~16.9.16"
react "~16.9.0"
react-dom "~16.9.0"
sanitize-html "~1.20.1"

"@jupyterlab/attachments@^2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@jupyterlab/attachments/-/attachments-2.1.0.tgz#86dd6c02a0ac2e5b6c1221056bed67bd4d933de1"
Expand Down Expand Up @@ -392,7 +417,19 @@
lodash.escape "^4.0.1"
marked "^0.8.0"

"@jupyterlab/services@^5.1.0":
"@jupyterlab/running@^2.1.1":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@jupyterlab/running/-/running-2.1.1.tgz#232029d96e671d8d0b73ad1335220438d6e3ff3d"
integrity sha512-4gzXDIq7UWeVDPjVaOZNz7hB5KnFqy1AscjkCCCCEqSEDp3L6te4e5vkni34CpVKiLDaL0ts2IKcY9omSBcFKw==
dependencies:
"@jupyterlab/apputils" "^2.1.1"
"@jupyterlab/ui-components" "^2.1.1"
"@lumino/coreutils" "^1.4.2"
"@lumino/disposable" "^1.3.5"
"@lumino/signaling" "^1.3.5"
react "~16.9.0"

"@jupyterlab/services@^5.0.0", "@jupyterlab/services@^5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@jupyterlab/services/-/services-5.1.0.tgz#891607d87cbe9413219cfe4ceb9905193b85b657"
integrity sha512-xhtDvAdgw+sWNSbpkExCYyJbHxlwhiZYqc07+zhOdYrpxO19k/ZmmyNoYCyfvNLcMQ4JWVBoczI714u1QNLj4w==
Expand Down Expand Up @@ -471,6 +508,22 @@
react-dom "~16.9.0"
typestyle "^2.0.4"

"@jupyterlab/ui-components@^2.1.1":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@jupyterlab/ui-components/-/ui-components-2.1.1.tgz#ace65290ebe3e913e85e574d5d94f3c9f55d244c"
integrity sha512-VZWtJud5XXzSTK6HJebbqg7TkJmvuRk5K+F30u+pgX7PStC4j8OFD7IXCreLWmrvxoVvEXd4GFH2sVng5cgsQA==
dependencies:
"@blueprintjs/core" "^3.22.2"
"@blueprintjs/select" "^3.11.2"
"@jupyterlab/coreutils" "^4.1.0"
"@lumino/coreutils" "^1.4.2"
"@lumino/signaling" "^1.3.5"
"@lumino/virtualdom" "^1.6.1"
"@lumino/widgets" "^1.11.1"
react "~16.9.0"
react-dom "~16.9.0"
typestyle "^2.0.4"

"@lumino/algorithm@^1.2.3":
version "1.2.3"
resolved "https://registry.yarnpkg.com/@lumino/algorithm/-/algorithm-1.2.3.tgz#4ab9883d7e9a5b1845372a752dcaee2a35a770c6"
Expand Down
2 changes: 1 addition & 1 deletion share/jupyter/voila/templates/classic/index.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
{%- set kernel_id = kernel_start() -%}
<script id="jupyter-config-data" type="application/json">
{
"baseUrl": "{{resources.base_url}}",
"baseUrl": "{{resources.base_url}}voila/",
"kernelId": "{{kernel_id}}"
}
</script>
Expand Down
2 changes: 1 addition & 1 deletion share/jupyter/voila/templates/lab/index.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var voila_process = function(cell_index, cell_count) {
{%- with kernel_id = kernel_start() -%}
<script id="jupyter-config-data" type="application/json">
{
"baseUrl": "{{resources.base_url}}",
"baseUrl": "{{resources.base_url}}voila/",
"kernelId": "{{kernel_id}}"
}
</script>
Expand Down
54 changes: 41 additions & 13 deletions voila/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
from traitlets import Unicode, Integer, Bool, Dict, List, default

from jupyter_server.services.kernels.kernelmanager import AsyncMappingKernelManager
from jupyter_server.services.kernels.handlers import KernelHandler, ZMQChannelsHandler
from jupyter_server.services.kernels.handlers import MainKernelHandler, KernelHandler, ZMQChannelsHandler
from jupyter_server.services.contents.largefilemanager import LargeFileManager
from jupyter_server.base.handlers import FileFindHandler, path_regex
from jupyter_server.config_manager import recursive_update
Expand All @@ -62,6 +62,7 @@
from .execute import VoilaExecutor
from .exporter import VoilaExporter
from .csspreprocessor import VoilaCSSPreprocessor
from .utils import add_base_url_to_handlers

ioloop.install()
_kernel_id_regex = r"(?P<kernel_id>\w+-\w+-\w+-\w+-\w+)"
Expand All @@ -71,6 +72,24 @@ def _(x):
return x


class VoilaMainKernelHandler(MainKernelHandler):
@property
def kernel_manager(self):
return self.settings['voila_kernel_manager']


class VoilaKernelHandler(KernelHandler):
@property
def kernel_manager(self):
return self.settings['voila_kernel_manager']


class VoilaZMQChannelsHandler(ZMQChannelsHandler):
@property
def kernel_manager(self):
return self.settings['voila_kernel_manager']


class Voila(Application):
name = 'voila'
version = __version__
Expand Down Expand Up @@ -388,6 +407,7 @@ def start(self):
'comm_msg',
'comm_info_request',
'kernel_info_request',
'custom_message',
'shutdown_request'
]
)
Expand All @@ -409,7 +429,7 @@ def start(self):
self.app = tornado.web.Application(
base_url=self.base_url,
server_url=self.server_url or self.base_url,
kernel_manager=self.kernel_manager,
voila_kernel_manager=self.kernel_manager,
kernel_spec_manager=self.kernel_spec_manager,
allow_remote_access=True,
autoreload=self.autoreload,
Expand All @@ -426,10 +446,8 @@ def start(self):
handlers = []

handlers.extend([
(url_path_join(self.server_url, r'/api/kernels/%s' % _kernel_id_regex), KernelHandler),
(url_path_join(self.server_url, r'/api/kernels/%s/channels' % _kernel_id_regex), ZMQChannelsHandler),
(
url_path_join(self.server_url, r'/voila/static/(.*)'),
r'/voila/static/(.*)',
MultiStaticFileHandler,
{
'paths': self.static_paths,
Expand All @@ -438,11 +456,13 @@ def start(self):
)
])

handlers.extend(base_handlers)

# Serving notebook extensions
if self.voila_configuration.enable_nbextensions:
handlers.append(
(
url_path_join(self.server_url, r'/voila/nbextensions/(.*)'),
r'/voila/nbextensions/(.*)',
FileFindHandler,
{
'path': self.nbextensions_path,
Expand All @@ -452,7 +472,7 @@ def start(self):
)
handlers.append(
(
url_path_join(self.server_url, r'/voila/files/(.*)'),
r'/voila/files/(.*)',
WhiteListFileHandler,
{
'whitelist': self.voila_configuration.file_whitelist,
Expand All @@ -467,7 +487,7 @@ def start(self):
}
if self.notebook_path:
handlers.append((
url_path_join(self.server_url, r'/(.*)'),
r'/(.*)',
VoilaHandler,
{
'notebook_path': os.path.relpath(self.notebook_path, self.root_dir),
Expand All @@ -479,10 +499,9 @@ def start(self):
else:
self.log.debug('serving directory: %r', self.root_dir)
handlers.extend([
(self.server_url, VoilaTreeHandler, tree_handler_conf),
(url_path_join(self.server_url, r'/voila/tree' + path_regex),
VoilaTreeHandler, tree_handler_conf),
(url_path_join(self.server_url, r'/voila/render/(.*)'),
('', VoilaTreeHandler, tree_handler_conf),
(r'/voila/tree' + path_regex, VoilaTreeHandler, tree_handler_conf),
(r'/voila/render/(.*)',
VoilaHandler,
{
'template_paths': self.template_paths,
Expand All @@ -491,7 +510,7 @@ def start(self):
}),
])

self.app.add_handlers('.*$', handlers)
self.app.add_handlers('.*$', add_base_url_to_handlers(self.server_url, handlers))
self.listen()

def stop(self):
Expand Down Expand Up @@ -574,3 +593,12 @@ def target():


main = Voila.launch_instance

base_handlers = [
(r'/voila/api/kernels', VoilaMainKernelHandler),
(r'/voila/api/kernels/%s' % _kernel_id_regex, VoilaKernelHandler),
(r'/voila/api/kernels/%s/channels' % _kernel_id_regex, VoilaZMQChannelsHandler),
]

if __name__ == '__main__':
main()
4 changes: 4 additions & 0 deletions voila/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ def initialize(self, **kwargs):
# we want to avoid starting multiple kernels due to template mistakes
self.kernel_started = False

@property
def kernel_manager(self):
return self.settings['voila_kernel_manager']

@tornado.web.authenticated
async def get(self, path=None):
# if the handler got a notebook_path argument, always serve that
Expand Down
Loading