Skip to content
This repository has been archived by the owner on Aug 26, 2020. It is now read-only.
/ bindilla Public archive

πŸ¦– A Stencila to Binder bridge

Notifications You must be signed in to change notification settings

stencila/bindilla

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

43 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ¦– Bindilla

Bindilla. Aaarrrrgh!

⚠️ Deprecated

This project is deprecated and no longer maintained. Please see, our main repository, stencila/stencila, for other projects that provide similar or alternative functionality.

What?

Bindilla acts as a bridge between Stencila interfaces and execution contexts hosted by Binder. Using this bridge, clients such as Stencila Desktop or eLife RDS Reader can launch, and interact with, alternative execution envionments provided by Binder.

Why?

Binder supports launching a Git repository containing a Dar archive directly. But what if you want to have the content of a reproducible article served from somewhere else and only use Binder for code execution?

Stencila clients talk to execution contexts using an API. This API is implemented by several packages including stencila/py, stencila/r, and stencila/node. These packages are available within a Binder container via nbstencilaproxy. You can embed a reproducible document into the container and launch it via a per-user Binder container.

However, in some cases you don't want to rely on having a running container to deliver your reproducible document to each reader. Instead, you can use a progressive enhancement approach to reproducibility in which reproducible elements can be made dynamic, on demand, based on user interaction. The API is designed to allow for this use case, allowing user interfaces to connect to alternative execution contexts both local and remote. By exposing the API as a bridge Bindilla enables this use case for execution contexts hosted on Binder.

This bridge relies on nbstencilaproxy being in the container image that is launched by Binder. repo2docker will detect Dar folders in a repo and install nbstencilaproxy and other necessary requirements automatically.

Use

To use Bindilla to connect a Stencila interface with a Binder container add the hosts URL parameter. For example:

FAQ

Why is this implemented in Python instead of Node.js, Go, or ...?

BinderHub, and much of the wider Jupyter ecosystem, is implemented in Python. We want to have an implementation that is familiar to that community.

Why use Tornado as a server framework instead of Werkzeug, Flask, or ...

For the same reason we are using Python, because BinderHub uses Tornado.

Why separate host and host_http_server files?

The Host is implemented in bindilla/host.py and a HTTP server is implemented in bindilla/host_http_server.py. This is to maintain consistency with the code and file structure in other implementations of the Stencila Host API e.g. stencila/py, stencila/node. Although for Bindilla it probably only makes sense to have a HTTP server, in these other implementations there may be more than one server protocol providing access to the host and this structure provides for separation of concerns.

Are there any funny, circa 1969, short films about Godzilla?

As it happens, yes!

API

Host

Host(self, binder_host='https://mybinder.org', proxy=True)

A Stencila Host that launches, and then proxies to, a container on Binder.

manifest

Host.manifest(self, extra_environs=None)

Return the manifest for this host.

parse_environ

Host.parse_environ(environ_id)

Parse an environ id into an environment spec to include in manifest.

Also split out the parts needed for a Binder repo path, which have the pattern <provider-name>/<org-name>/<repo-name>/<branch|commit|tag> The <branch|commit|tag> part is optional and defaults to master`.

launch_environ

Host.launch_environ(self, environ_id)

Launch an environment on Binder.

This sends a request to Binder to create a new container based on the environment identifier.

proxy_environ

Host.proxy_environ(self, method, binder_id, token, path, body=None)

Proxy requests through to the binder.

This methods appends /stencila-host to the Binder container's URL e.g https://hub.mybinder.org/user/org-repo-mukdlnm5/stencila-host and puts the token into the header for authorization.

bindilla.host_http_server

BaseHandler

BaseHandler(self, application, request, **kwargs)

A base class for all request handlers.

Adds necessary headers and handles OPTIONS requests needed for CORS. Handles errors.

IndexHandler

IndexHandler(self, application, request, **kwargs)

Handles requests to the index/home page.

Just redirect to the Github repo. Don't use a 301, or 302, because that can cause load balancer helth checks to fail.

ManifestHandler

ManifestHandler(self, application, request, **kwargs)

Handles requests for Bindilla's Host manifest.

EnvironHandler

EnvironHandler(self, application, request, **kwargs)

Handles requests to launch and shutdown an environment on Binder.

post
EnvironHandler.post(self, environ_id)

Launch a Binder for the environment.

delete
EnvironHandler.delete(self, environ_id)

Shutdown a Binder for the environment.

Currently, this is a no-op, but is provided for API compatability (clients may request for an environ to be stopped).

ProxyHandler

ProxyHandler(self, application, request, **kwargs)

Proxies requests through to the container running on Binder.

make

make()

Make the Tornado RuleRouter.

run

run()

Run the HTTP server.