Technical Overview
Please read the JupyterHub Technical Overview and Configuration Basics for a high-level view of:
JupyterHub’s Subsystems: Hub, Proxy, Single-User Notebook Server
how the subsystems interact
the process from JupyterHub access to user login
JupyterHub’s default behavior/configuration
customizing JupyterHub
Understanding this will help you understand how JupyterHub was customized to support integration with XNAT.
There are two main extension points for JupyterHub:
How users are authenticated by Authenticators
How user’s single-user notebook server processes are started by Spawners
Each is governed by a customizable class, and JupyterHub ships with basic defaults for each.
To enable custom authentication and spawning we've created:
- An authenticator for basic password authentication with XNAT
- A SwarmSpawner which spawns single user Jupyter containers on a Docker swarm with bind mounts to parts of the XNAT archive.
- A configuration file for quickly deploying the custom authenticator and spawner.
A Docker image has been created with this custom authenticator, spawner, and configuration file.
We have developed a plugin for XNAT which handles interactions with this customized JupyterHub using the JupyterHub REST API.
Authentication
Authentication with JupyterHub is tied to an XNAT user. If a user needs to log into JupyterHub, they can use their XNAT username and password. A custom authentication class was developed for basic password authentication with XNAT. It uses XNAT's User Auth Service API for authenticating a user. User's cannot access one another's Jupyter servers.
JupyterHub has its own cookie for logging into and out of JupyterHub. Logging out of XNAT doesn't log a user out of JupyterHub, but a user can log out of JupyterHub directly.
For those using the OpenId Plugin there is a known issue blocking use of Jupyter functionality with OpenId users.
Spawner
A Spawner [JupyterHub Documentation] [Github] starts each single-user notebook server. The Spawner represents an abstract interface to a process, and a custom Spawner needs to be able to take three actions:
start the process
poll whether the process is still running
stop the process
This plugin currently uses the SwarmSpawner, used to launch single user notebook servers as Docker Swarm mode services. This allows for running JupyterHub in a swarm so that notebook containers can be run on any of multiple servers.
To configure the single-user Jupyter containers, the SwarmSpawner.pre_spawn_hook method has been setup to call XNAT's REST API for bind mounts to portions of the XNAT archive.
JupyterHub Plugin For XNAT
The JupyterHub Plugin for XNAT connects an XNAT to a properly setup JupyterHub instance. The plugin is designed to work with JupyterHub's REST API and will spawn single user Jupyter containers for XNAT users. The plugin is responsible for providing JupyterHub the configuration meta-data it needs to start the single user Jupyter container. This includes the Docker image, any CPU and memory requirements, bind mounts to a subset of the XNAT archive, environmental variables, etc.