Permalink
Browse files

add nbstencilaproxy module and UI button, based on nuest@33b0aa6

  • Loading branch information...
nuest committed May 11, 2018
1 parent d0df78c commit 8e8f3676cd6b4616c4b5cd1bca7a40c6fe399613
Showing with 131 additions and 17 deletions.
  1. +8 −2 Dockerfile
  2. +28 −3 README.md
  3. +18 −0 nbstencilaproxy/__init__.py
  4. +15 −12 jupyter_notebook_config.py → nbstencilaproxy/handlers.py
  5. +45 −0 nbstencilaproxy/static/tree.js
  6. +17 −0 setup.py
@@ -20,8 +20,14 @@ WORKDIR ${HOME}
ADD requirements.txt /tmp/requirements.txt
RUN pip install --no-cache -r /tmp/requirements.txt

RUN test -d ${HOME}/.jupyter/ || mkdir ${HOME}/.jupyter/
ADD jupyter_notebook_config.py ${HOME}/.jupyter/jupyter_notebook_config.py
ADD --chown=1000 setup.py /tmp/nbstencilaproxy/setup.py
ADD --chown=1000 nbstencilaproxy /tmp/nbstencilaproxy/nbstencilaproxy
RUN pip install /tmp/nbstencilaproxy && \
rm -r /tmp/nbstencilaproxy

RUN jupyter serverextension enable --sys-prefix --py nbstencilaproxy
RUN jupyter nbextension install --sys-prefix --py nbstencilaproxy
RUN jupyter nbextension enable --sys-prefix --py nbstencilaproxy

ADD --chown=1000 archive/kitchen-sink ${HOME}/kitchen-sink
ADD --chown=1000 archive/py-jupyter ${HOME}/py-jupyter
@@ -6,6 +6,11 @@

This project is part of the [eLife Innovation Sprint 2018](https://elifesci.org/innovationsprint2018) and [Mozilla Global Sprint 2018](https://mozilla.github.io/global-sprint/) (see [https://github.com/mozilla/global-sprint/issues/317](https://github.com/mozilla/global-sprint/issues/317))

This project comprises two modules:

- a JavaScript package for installing and running Stencila (client/UI and services) in a Jupyter container
- a Python package for installing and running a proxy (based on [`nbserverproxy`](https://github.com/jupyterhub/nbserverproxy)) to access the UI as well as services provided by Stencila; the package also extends the Jupyter UI to add a "New Stencila Session" button

## Team

- [@minrk](https://github.com/minrk)
@@ -27,7 +32,6 @@ Relevant path configurations comprise the local storage path _as well as_ the UR

The `Dockerfile` installs our helper npm package and adds + configures the `nbserverproxy` tool (see `requirements.txt` and `jupyter_notebook_config.py`).


### Connecting Stencila to Jupyter kernels

Stencila has "execution contexts" (the equivalent of Jupyter's "kernels") for R, Python, SQL, Javascript (in the browser), and Node.js. Execution contexts differ from kernels in a number of ways including local execution and dependency analysis of cells. Both of these are necessary for the reactive, functional execution model of Stencila Articles and Sheets.
@@ -36,6 +40,28 @@ We could install these execution contexts in the Docker image. However, Stencila

We have included the [`stencila-node`](https://www.npmjs.com/package/stencila-node) Node.js package in the Docker image which provides the `JupyterContext` as well as a `NodeContext` (for executing Javascript) and a `SqliteContext` (for executing SQL) .

### Making Stencila available via a Proxy

**nbstencilaproxy** provides Jupyter server and notebook extensions to proxy Stencila.
It is based on [**nbrsessionproxy**](https://github.com/jupyterhub/nbrsessionproxy) but does not include the support nbrsessionproxy has for JupyterLab.

**Install**

Install package:

```
pip install git+https://github.com/nuest/nbstencilaproxy
```

Install the extensions for all users on the system:

```
jupyter serverextension enable --py --sys-prefix nbstencilaproxy
jupyter nbextension install --py --sys-prefix nbstencilaproxy
jupyter nbextension enable --py --sys-prefix nbstencilaproxy
```

The Dockerfile contains an example installation on top of [jupyter/r-notebook](https://github.com/jupyter/docker-stacks/tree/master/r-notebook).

## Development

@@ -53,8 +79,7 @@ docker run -p 8888:8888 jupyter-dar

- Login by visiting the tokenized URL displayed e.g. `http://localhost:8888/?token=99a7bc13...`

- Go to http://localhost:8888/stencila/

- Go to http://localhost:8888/stencila/ or click on the "New > Stencila Session" button on the Jupyter start page

## License

@@ -0,0 +1,18 @@
from nbstencilaproxy.handlers import setup_handlers

# Jupyter Extension points
def _jupyter_server_extension_paths():
return [{
'module': 'nbstencilaproxy',
}]

def _jupyter_nbextension_paths():
return [{
"section": "tree",
"dest": "nbstencilaproxy",
"src": "static",
"require": "nbstencilaproxy/tree"
}]

def load_jupyter_server_extension(nbapp):
setup_handlers(nbapp)
@@ -1,8 +1,22 @@
import pipes
import sys

from tornado import web
from urllib.parse import urlunparse, urlparse

from notebook.utils import url_path_join as ujoin
from notebook.base.handlers import IPythonHandler

from nbserverproxy.handlers import SuperviseAndProxyHandler

class AddSlashHandler(IPythonHandler):
"""Handler for adding trailing slash to URLs that need them"""
@web.authenticated
def get(self, *args):
src = urlparse(self.request.uri)
dest = src._replace(path=src.path + '/')
self.redirect(urlunparse(dest))

# define our proxy handler for proxying the application

class StencilaProxyHandler(SuperviseAndProxyHandler):
@@ -37,7 +51,7 @@ def get_cmd(self):
]


def add_handlers(app):
def setup_handlers(app):
app.web_app.add_handlers('.*', [
(
app.base_url + 'stencila/(.*)',
@@ -56,14 +70,3 @@ def add_handlers(app):
)),
),
])


# fake a module to load the proxy handler as an extension
module_name = '_myproxymod'
import types
mod = types.ModuleType(module_name)
sys.modules[module_name] = mod
mod.load_jupyter_server_extension = add_handlers
c.NotebookApp.nbserver_extensions.update({
module_name: True,
})
@@ -0,0 +1,45 @@
define(function(require) {
var $ = require('jquery');
var Jupyter = require('base/js/namespace');
var utils = require('base/js/utils');

var base_url = utils.get_body_data('baseUrl');


function load() {
if (!Jupyter.notebook_list) return;

/* locate the right-side dropdown menu of apps and notebooks */
var menu = $('.tree-buttons').find('.dropdown-menu');

/* create a divider */
var divider = $('<li>')
.attr('role', 'presentation')
.addClass('divider');

/* add the divider */
menu.append(divider);

/* create our list item */
var stencilasession_item = $('<li>')
.attr('role', 'presentation')
.addClass('new-stencila');

/* create our list item's link */
var stencilasession_link = $('<a>')
.attr('role', 'menuitem')
.attr('tabindex', '-1')
.attr('href', base_url + 'stencila/')
.attr('target', '_blank')
.text('Stencila Session');

/* add the link to the item and
* the item to the menu */
stencilasession_item.append(stencilasession_link);
menu.append(stencilasession_item);
}

return {
load_ipython_extension: load
};
});
@@ -0,0 +1,17 @@
import setuptools

setuptools.setup(
name="nbstencilaproxy",
version='0.1.0',
url="https://github.com/nuest/nbstencilaproxy",
author="Min RK, Daniel Nüst, Ryan Lovett",
description="Jupyter extension to proxy Stencila",
packages=setuptools.find_packages(),
keywords=['Jupyter'],
classifiers=['Framework :: Jupyter'],
install_requires=[
'notebook',
'nbserverproxy >= 0.8.2'
],
package_data={'nbstencilaproxy': ['static/*']},
)

0 comments on commit 8e8f367

Please sign in to comment.