Skip to content

Commit

Permalink
Merge pull request #4 from jtpio/server-proxy
Browse files Browse the repository at this point in the history
Handle multiple servers
  • Loading branch information
jtpio authored Feb 10, 2021
2 parents a0b7983 + a9e477d commit 16b71e2
Show file tree
Hide file tree
Showing 14 changed files with 243 additions and 45 deletions.
9 changes: 6 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ jobs:
with:
python-version: '3.7'
architecture: 'x64'


- name: Setup pip cache
uses: actions/cache@v2
with:
Expand All @@ -43,7 +43,7 @@ jobs:
key: yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-
- name: Install dependencies
run: python -m pip install jupyterlab
- name: Build the extension
Expand All @@ -53,4 +53,7 @@ jobs:
python -m pip install .
jupyter labextension list 2>&1 | grep -ie "jupyterlab-link-share.*OK"
jupyter server extension list 2>&1 | grep -ie "jupyterlab_link_share.*OK"
jupyter serverextension list 2>&1 | grep -ie "jupyterlab_link_share.*OK"
python -m jupyterlab.browser_check
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ node_modules/
*.egg-info/
.ipynb_checkpoints
*.tsbuildinfo
jupyterlab-link-share/labextension
jupyterlab_link_share/labextension

# Created by https://www.gitignore.io/api/python
# Edit at https://www.gitignore.io/?templates=python
Expand Down
5 changes: 3 additions & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
include LICENSE
include README.md
include pyproject.toml
include jupyter-config/jupyterlab-link-share.json
include jupyter-config/jupyter_server_config.d/jupyterlab_link_share.json
include jupyter-config/jupyter_notebook_config.d/jupyterlab_link_share.json

include package.json
include install.json
include ts*.json

graft jupyterlab-link-share/labextension
graft jupyterlab_link_share/labextension

# Javascript files
graft src
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"NotebookApp": {
"nbserver_extensions": {
"jupyterlab_link_share": true
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"ServerApp": {
"jpserver_extensions": {
"jupyterlab_link_share": true
}
}
}
19 changes: 0 additions & 19 deletions jupyterlab-link-share/__init__.py

This file was deleted.

31 changes: 31 additions & 0 deletions jupyterlab_link_share/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

import json
from pathlib import Path

from .handlers import setup_handlers
from ._version import __version__

HERE = Path(__file__).parent.resolve()

with (HERE / "labextension" / "package.json").open() as fid:
data = json.load(fid)


def _jupyter_labextension_paths():
return [{
"src": "labextension",
"dest": data["name"]
}]


def _jupyter_server_extension_points():
return [{
"module": "jupyterlab_link_share"
}]


def _load_jupyter_server_extension(server_app):
setup_handlers(server_app.web_app)
server_app.log.info("Registered JupyterLab Link Share extension at URL path /jupyterlab_link_share")

load_jupyter_server_extension = _load_jupyter_server_extension
File renamed without changes.
26 changes: 26 additions & 0 deletions jupyterlab_link_share/handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import json

import tornado

from jupyter_server.base.handlers import APIHandler
from jupyter_server.serverapp import list_running_servers as list_jupyter_servers
from jupyter_server.utils import url_path_join
from notebook.notebookapp import list_running_servers as list_notebook_servers


class RouteHandler(APIHandler):
@tornado.web.authenticated
def get(self):
servers = list(list_notebook_servers()) + list(list_jupyter_servers())
# sort by pid so PID 1 is first in Docker and Binder
servers.sort(key=lambda x: x["pid"])
self.finish(json.dumps(servers))


def setup_handlers(web_app):
host_pattern = ".*$"

base_url = web_app.settings["base_url"]
route_pattern = url_path_join(base_url, "jupyterlab_link_share", "servers")
handlers = [(route_pattern, RouteHandler)]
web_app.add_handlers(host_pattern, handlers)
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"@jupyterlab/apputils": "^3.0.0",
"@jupyterlab/coreutils": "^5.0.0",
"@jupyterlab/mainmenu": "^3.0.0",
"@jupyterlab/services": "^6.0.0",
"@jupyterlab/translation": "^3.0.0",
"@lumino/widgets": "^1.17.0"
},
Expand All @@ -69,6 +70,6 @@
"styleModule": "style/index.js",
"jupyterlab": {
"extension": true,
"outputDir": "jupyterlab-link-share/labextension"
"outputDir": "jupyterlab_link_share/labextension"
}
}
28 changes: 17 additions & 11 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,48 @@
install_npm,
ensure_targets,
combine_commands,
skip_if_exists
skip_if_exists,
)
import setuptools

HERE = Path(__file__).parent.resolve()

# The name of the project
name = "jupyterlab-link-share"
package = name.replace('-', '_')

# Get our version
with (HERE / "package.json").open() as f:
version = json.load(f)["version"]

lab_path = (HERE / name / "labextension")
lab_path = HERE / package / "labextension"

# Representative files that should exist after a successful build
jstargets = [
str(lab_path / "package.json"),
]

package_data_spec = {
name: [
"*"
]
}
package_data_spec = {package: ["*"]}

labext_name = "jupyterlab-link-share"

data_files_spec = [
("share/jupyter/labextensions/%s" % labext_name, str(lab_path), "**"),
("share/jupyter/labextensions/%s" % labext_name, str(HERE), "install.json"),
(
"etc/jupyter/jupyter_server_config.d",
"jupyter-config/jupyter_server_config.d",
"jupyterlab_link_share.json",
),
(
"etc/jupyter/jupyter_notebook_config.d",
"jupyter-config/jupyter_notebook_config.d",
"jupyterlab_link_share.json",
),
]

cmdclass = create_cmdclass("jsdeps",
package_data_spec=package_data_spec,
data_files_spec=data_files_spec
cmdclass = create_cmdclass(
"jsdeps", package_data_spec=package_data_spec, data_files_spec=data_files_spec
)

js_command = combine_commands(
Expand All @@ -71,7 +77,7 @@
cmdclass=cmdclass,
packages=setuptools.find_packages(),
install_requires=[
"jupyterlab~=3.0",
"jupyterlab~=3.0"
],
zip_safe=False,
include_package_data=True,
Expand Down
45 changes: 45 additions & 0 deletions src/handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { URLExt } from '@jupyterlab/coreutils';

import { ServerConnection } from '@jupyterlab/services';

/**
* Call the API extension
*
* @param endPoint API REST end point for the extension
* @param init Initial values for the request
* @returns The response body interpreted as JSON
*/
export async function requestAPI<T>(
endPoint = '',
init: RequestInit = {}
): Promise<T> {
const settings = ServerConnection.makeSettings();
const requestUrl = URLExt.join(
settings.baseUrl,
'jupyterlab_link_share',
endPoint
);

let response: Response;
try {
response = await ServerConnection.makeRequest(requestUrl, init, settings);
} catch (error) {
throw new ServerConnection.NetworkError(error);
}

let data: any = await response.text();

if (data.length > 0) {
try {
data = JSON.parse(data);
} catch (error) {
console.log('Not a JSON response body.', response);
}
}

if (!response.ok) {
throw new ServerConnection.ResponseError(response, data.message || data);
}

return data;
}
33 changes: 25 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import { IMainMenu } from '@jupyterlab/mainmenu';

import { ITranslator, nullTranslator } from '@jupyterlab/translation';

import { Menu } from '@lumino/widgets';
import { Menu, Widget } from '@lumino/widgets';

import { requestAPI } from './handler';

/**
* The command IDs used by the plugin.
Expand Down Expand Up @@ -44,14 +46,29 @@ const plugin: JupyterFrontEndPlugin<void> = {
commands.addCommand(CommandIDs.share, {
label: trans.__('Share Jupyter Server Link'),
execute: async () => {
const link = URLExt.normalize(
`${PageConfig.getUrl({
workspace: PageConfig.defaultWorkspace
})}?token=${PageConfig.getToken()}`
);
const results: { token: string }[] = await requestAPI<any>('servers');

const links = results.map(server => {
return URLExt.normalize(
`${PageConfig.getUrl({
workspace: PageConfig.defaultWorkspace
})}?token=${server.token}`
);
});

const entries = document.createElement('div');
links.map(link => {
const p = document.createElement('p');
const a = document.createElement('a');
a.href = link;
a.innerText = link;
p.appendChild(a);
entries.appendChild(p);
});

const result = await showDialog({
title: trans.__('Share Jupyter Server Link'),
body: link,
body: new Widget({ node: entries }),
buttons: [
Dialog.cancelButton({ label: trans.__('Cancel') }),
Dialog.okButton({
Expand All @@ -61,7 +78,7 @@ const plugin: JupyterFrontEndPlugin<void> = {
]
});
if (result.button.accept) {
Clipboard.copyToSystem(link);
Clipboard.copyToSystem(links[0]);
}
}
});
Expand Down
Loading

0 comments on commit 16b71e2

Please sign in to comment.