Thebe
takes the Jupyter (formerly ipython) front end, and make it work outside of the notebook context.
In short, this is an easy way to let users on a web page run code examples on a server.
Four things are required:
- A server, either a tmpnb server, for lots of users, or simply an ipython notebook server.
- A web page with some code examples
- A script tag in the page that includes the compiled javascript of
Thebe
, which is in this repo atstatic/main-built.js
- node-js and bower to install external javascript dependencies.
To install the javascript dependencies, simply run bower install
in the root of the repository.
Here is a very simple example/demo. There are more complicated examples in the examples directory but you'll need to run a notebook server with the appropriate dependencies installed for them to work.
Also, Thebe is a moon of Jupiter in case you were wondering. Naming things is hard.
shift
+return
executes the example that is currently focused
shift
+space
moves the focus to the next example
shift
+click
ing a run button will execute all preceding code examples as well as the current one
ctrl
+c
works like a keyboard interrupt (in case of infinite loops and such)
You can change the first two by passing options to Thebe when you instantiate it (see below)
Currently Thebe is imported via an HTML script tag. Since Thebe is an
alternative Jupyter notebook front-end, the notebook server version and
ipywidgets version of the tmpnb instance are important and must be specified.
The following example will load Thebe for the notebook version 4.1.0 and
ipywidgets 4.0.3:
<script src="http://cdn.jupyter.org/thebe/notebook4.1.0/ipywidgets4.0.3/static/main-built.js" type="text/javascript" charset="utf-8"></script>
or for the notebook version 3.x:
<script src="http://cdn.jupyter.org/thebe/notebook3.0.0/static/main-built.js" type="text/javascript" charset="utf-8"></script>
and then, to instantiate Thebe:
<script>
$(function(){
new Thebe({url:"http://some.tmpnb.server.com:8000"});
});
</script>
Any pre
tags with the data-executable
attribute will be turned into editable, executable examples, and a run button will be added for each. Once run is clicked, Thebe
will try to connect to the notebook server url you supplied, start the kernel, and execute the code in that example.
If append_kernel_controls_to
is set to a dom selector, clicking run will also add kernel controls to that element, which will allow users to interrupt and restart the kernel. (Interrupting is equivalent to a keyboard interrupt, whereas restarting will lose all the user's variables and data.)
Opt-in auto instantiation: When loaded, the script will automatically start Thebe
with the default options if the body
has a data-runnable
attribute that is set to true.
You can override the below default options when you instantiate Thebe: Thebe(options)
default_options =
# jquery selector for elements we want to make runnable
selector: 'pre[data-executable]'
# the url of either a tmnb server or a notebook server
# (default url assumes user is running tmpnb via boot2docker)
url: '//192.168.59.103:8000/'
# is the url for tmpnb or for a notebook
tmpnb_mode: true
# the kernel name to use, must exist on notebook server
kernel_name: "python2"
# set to false to prevent kernel_controls from being added
append_kernel_controls_to: false
# Automatically inject basic default css we need, no highlighting
inject_css: true
# Automatically load other necessary css (jquery ui)
load_css: true
# Automatically load mathjax js
load_mathjax: true
# Default keyboard shortcut for focusing next cell, shift+ this keycode, default (32) is spacebar
# Set to false to disable
next_cell_shortcut: 32
# Default keyboard shortcut for executing cell, shift+ this keycode, default (13) is return
# Set to false to disable
run_cell_shortcut: 13
# For when you want a pre to become a CM instance, but not be runnable
not_executable_selector: "pre[data-not-executable]"
# For when you want a pre to become a CM instance, but not be writable
read_only_selector: "pre[data-read-only]"
# if set to false, no addendum added, if a string, use that instead
error_addendum: true
# adds interrupt to every cell control, when it's running
add_interrupt_button: false
# hack to set the codemirror mode correctly
codemirror_mode_name: "ipython"
# hack to set the codemirror theme
codemirror_theme_name: "default"
# totally different mode for running a terminal instead of a notebook
terminal_mode: false
# where are our cell elements (that are created from the selector option above)
container_selector: "body"
# for setting what docker image you want to run on the back end
image_name: "jupyter/notebook"
# should we remember the url that we connect to
set_url_cookie: true
# show messages from @log()
debug: false
For example,
$(function(){
var thebe = new Thebe({
selector:"pre.cool",
url: 'http://localhost:8888/'
});
});
will make each pre
tag with class cool
runnable, and will try to connect with an ipython notebook server running locally at the ipython notebook default address and port.
Because the url of your notebook server or tmpnb server may change quite often during development, you can override the url
and tmpnb_mode
options that are set when thebe is instantiated.
Do this by adding url
and/or tmpnb_mode
params as a query string to the page location. For instance, if you are serving a page at localhost:8000
, accessing localhost:8000?url=https://tmp38.tmpnb.org
in your browser instead will cause thebe to use https://tmp38.tmpnb.org
rather than the options passed when thebe was instantiated. This is only for debugging and should not be used for production.
Thebe now includes terminal functionality, via termjs. To run a terminal in the browser, make sure you only have one instance of the selector (which defaults to pre[data-executable]
) and set terminal_mode
to true. Now, clicking on the element will connect and launch a terminal.
Terminal mode only works with the most up to date version of jupyter notebook. For now, you can run this docker image and it should work.
For simplicity, several codemirror language modes (i.e. syntax highlighting) are bundled with Thebe. Here's a list of them.
The easiest way to get this running locally requires setting a few options in your Thebe declaration.
$(function(){
var thebe = new Thebe({
tmpnb_mode: false,
url: 'http://localhost:8888/'
});
});
to point to your server's address url
option to the url of a running ipython notebook server, as above.
After installing ipython, run it like so:
ipython notebook --NotebookApp.allow_origin='*' --no-browser
Which defaults to running at http://localhost:8888/, and should tell you that.
Most of the actual development takes place in static/main.coffee
. I've tried to make as few changes to the rest of the jupyter front end as possible, but there were some cases where it was unavoidable (see #2 for more info on this).
After making a change to the javascript in static/
, you'll need to recompile it to see your changes in built.html
or to use it in production. index.html
will reflect your changes that last r.js
step.
npm install -g requirejs
npm install -g coffee-script
bower install
coffee -cbm .
cd static
r.js -o build.js baseUrl=. name=almond include=main out=main-built.js
First, you need docker (and boot2docker if you're on a OS X) installed.
Pull the images. This version is a slightly different fork of the main repo, which adds a API route for /spawn
( /api/spawn
).
docker pull jupyter/configurable-http-proxy
docker pull zischwartz/tmpnb
docker pull zischwartz/scipyserver
Then startup the docker containers for the proxy and tmpnb like so:
export TOKEN=$( head -c 30 /dev/urandom | xxd -p )
docker run --net=host -d -e CONFIGPROXY_AUTH_TOKEN=$TOKEN jupyter/configurable-http-proxy --default-target http://127.0.0.1:9999
docker run --net=host -d -e CONFIGPROXY_AUTH_TOKEN=$TOKEN -v /var/run/docker.sock:/docker.sock zischwartz/tmpnb python orchestrate.py --image="zischwartz/scipyserver" --allow_origin="*" --command="ipython3 notebook --no-browser --port {port} --ip=* --NotebookApp.allow_origin=* --NotebookApp.base_url={base_path}" --cull-timeout=300 --cull_period=60
Next, start a normal server in this directory
python -m SimpleHTTPServer
Or with python3,
python -m http.server
and visit it at localhost:8000 and localhost:8000/built.html
Run the proxy like so
docker run --net=host -d -e CONFIGPROXY_AUTH_TOKEN=$TOKEN zischwartz/configurable-http-proxy configurable-http-proxy --default-target=http://127.0.0.1:9999 --ssl-key=key.pem --ssl-cert=cert.pem
And run the tmpnb image as above/usual. Then start up a local server that supports https
, like this one with the -S
option. It still won't work until you visit both the local server and the proxy address in your browser and say that you understand that the certs aren't valid and you want to proceed anyway.