Files
jupyterhub/docs/source/reference/api-only.md
Min RK 88f31c29bb add api-only doc
Describe how to use JupyterHub as a "behind the scenes" implementation detail,
rather than a user-facing application.
2021-11-04 17:16:59 +01:00

5.5 KiB

(api-only)=

Deploying JupyterHub in "API only mode"

JupyterHub is a service for deploying and managing Jupyter servers for users. This functionality is exposed primarily via a REST API. JupyterHub also ships with a basic web UI built on that API, enabling users to click a button to quickly start and stop their servers, and admins to perform some basic user and server management tasks.

The REST API has always provided functionality not available in the UI, and we try to avoid having any functionality only available in the UI and not the API. With JupyterHub 2.0, this should be fully the case - no UI pages should rely on information not available via the REST API. Previously, some admin UI functionality could only be achieved via admin pages, such as paginated requests.

The JupyterHub UI is customizable via extensible HTML templates, but this has some limited scope to what can be customized. Adding some content and messages to existing pages is well supported, but changing the page flow and what pages are available are beyond the scope of what is customizable.

Increasingly, JupyterHub is used purely as an API for managing Jupyter servers for other Jupyter-based applications that might want to present a different user experience. If you want a fully customized user experience, you can now disable the Hub UI and use your own pages together with the JupyterHub REST API to build your own web application to serve your users, relying on the Hub only as an API for managing users and servers.

One example of such an application is BinderHub, which powers https://mybinder.org, and motivates many of these changes.

BinderHub is distinct from a traditional JupyterHub deployment because it uses temporary users created for each launch. Instead of presenting a login page, users are presented with a form to specify what environment they would like to launch:

Binder launch form

When a launch is requested:

  1. an image is built, if necessary
  2. a temporary user is created,
  3. a server is launched for that user, and
  4. when running, users are redirected to an already running server with an auth token in the URL
  5. after the session is over, the user is deleted

This means that a lot of JupyterHub's UI flow doesn't make sense:

  • there is no way for users to login
  • the human user doesn't map onto a JupyterHub User in a meaningful way
  • when a server isn't running, there isn't a 'restart your server' action available because the user has been deleted
  • users do not have any access to any Hub functionality, so presenting pages for those features would be confusing

BinderHub is one of the motivating use cases for JupyterHub supporting being used only via its API. We'll use BinderHub here as an example of various configuration options.

Disabling Hub UI

c.JupyterHub.hub_routespec is a configuration option to specify which URL prefix should be routed to the Hub. The default is / which means that the Hub will receive all requests not already specified to be routed somewhere else.

There are three values that are most logical for hub_routespec:

  • / - this is the default, and used in most deployments. It is also the only option prior to JupyterHub 1.4.
  • /hub/ - this serves only Hub pages, both UI and API
  • /hub/api - this serves only the Hub API, so all Hub UI is disabled, aside from the OAuth confirmation page, if used.

If you choose a hub routespec other than /, the main JupyterHub feature you will lose is the automatic handling of requests for /user/:username when the requested server is not running.

JupyterHub's handling of this request shows this page, telling you that the server is not running, with a button to launch it again:

screenshot of hub page for server not running

If you set hub_routespec to something other than /, it is likely that you also want to register another destination for / to handle requests to not-running servers. If you don't, you will see a default 404 page from the proxy:

screenshot of CHP default 404

For mybinder.org, the default "start my server" page doesn't make sense, because when a server is gone, there is no restart action. Instead, we provide hints about how to get back to a link to start a new server:

screenshot of mybinder.org 404

To achieve this, mybinder.org registers a route for / that goes to a custom endpoint that runs nginx and only serves this static HTML error page. This is set with

c.Proxy.extra_routes = {
    "/": "http://custom-404-entpoint/",
}

You may want to use an alternate behavior, such as redirecting to a landing page, or taking some other action based on the requested page.

If you use c.JupyterHub.hub_routespec = "/hub/", then all the Hub pages will be available, and only this default-page-404 issue will come up.

If you use c.JupyterHub.hub_routespec = "/hub/api/", then only the Hub API will be available, and all UI will be up to you. mybinder.org takes this last option, because none of the Hub UI pages really make sense. Binder users don't have any reason to know or care that JupyterHub happens to be an implementation detail of how their environment is managed. Seeing Hub error pages and messages in that situation is more likely to be confusing than helpful.

:::{versionadded} 1.4

c.JupyterHub.hub_routespec and c.Proxy.extra_routes are new in JupyterHub 1.4. :::