Using nbgrader with JuptyerHub

See also

Manually grading and formgrade
Documentation for nbgrader formgrade.
nbgrader formgrade
Command line options for nbgrader formgrade
Configuration options
Details on nbgrader_config.py
The philosophy and the approach
More details on how the nbgrader hierarchy is structured.
JupyterHub Documentation
Detailed documentation describing how JupyterHub works, which is very much required reading if you want to integrate the formgrader with JupyterHub.

In addition to using the nbgrader release, nbgrader fetch, nbgrader submit, and nbgrader collect commands with a shared server setup like JupyterHub, the formgrader can be configured to integrate with JupyterHub so that all grading can occur on the same server.

To set up the formgrader to work with JupyterHub, you will need to specify a few custom config options (see Configuration options for details on all possible config options, and where configuration files live). In this documentation, we’ll go through an example setup of JupyterHub with nbgrader, though note that each deployment of JupyterHub is slightly different, which might also require a slightly different nbgrader configuration. If you run into problems getting nbgrader to work with JupyterHub, please do email the Jupyter mailing list!

Configuring JupyterHub

To begin, we’ll run a vanilla JuptyerHub with the following jupyterhub_config.py:

c = get_config()

# Add users here that are allowed admin access to JupyterHub.
c.Authenticator.admin_users = ["instructor1"]

# Add users here that are allowed to login to JupyterHub.
c.Authenticator.whitelist = [
    "instructor1", "instructor2", "student1", "student2", "student3"
]

Then, you would run JupyterHub as follows. Note that in a real deployment, you should generate your own auth token and keep it secret! For details on how to do this, please refer to the JupyterHub documentation.

export CONFIGPROXY_AUTH_TOKEN='foo'
jupyterhub

Running this command should launch JupyterHub, which will then be accessible from localhost:8000.

Configuring nbgrader formgrade

To make the formgrader integrate with JupyterHub, we must tell it to authenticate users with JuptyerHub. The following is an example nbgrader_config.py that does this:

c = get_config()

## Generic nbgrader options (technically, the exchange directory is not used
## by the formgrader, but it is left in here for consistency with the rest of
## the user guide):

c.NbGrader.course_id = "example_course"
c.TransferApp.exchange_directory = "/tmp/exchange"

## Options that are specific to the formgrader and integrating it with JuptyerHub:

c.FormgradeApp.ip = "127.0.0.1"
c.FormgradeApp.port = 9000
c.FormgradeApp.authenticator_class = "nbgrader.auth.hubauth.HubAuth"

# This is the actual URL or public IP address where JupyterHub is running (by
# default, the HubAuth will just use the same address as what the formgrader is
# running on -- so in this case, 127.0.0.1). If you have JupyterHub behind a
# domain name, you probably want to set that here.
c.HubAuth.hub_address = "127.0.0.1"

# Change this to be the path to the user guide folder in your clone of
# nbgrader, or just wherever you have your class files. This is relative
# to the root of the notebook server launched by JupyterHub, which is
# probably your home directory. This is used for accessing the *live*
# version of notebooks via JupyterHub. If you don't want to access the
# live notebooks and are fine with just the static interface provided by
# the formgrader, then you can ignore this option.
c.HubAuth.notebook_url_prefix = "path/to/class_files"

# Change this to be the list of unix usernames that are allowed to access
# the formgrader.
c.HubAuth.graders = ["instructor1", "instructor2"]

# This specifies that the formgrader should automatically generate an api
# token to authenticate itself with JupyterHub.
c.HubAuth.generate_hubapi_token = True

# Change this to be the jupyterhub.sqlite located in the directory where
# you actually run JupyterHub.
c.HubAuth.hub_db = "path/to/jupyterhub.sqlite"

In this example, the formgrader listens on localhost at port 9000, and uses the special HubAuth authenticator class. This class tells the formgrader to ask JupyterHub to route requests from localhost:8000/hub/nbgrader/example_course to the formgrader at localhost:9000, and configures the formgrader to only allow access from usernames specifed in the list of graders. In addition, it tells JupyterHub where the root of the class files directory (where the formgrader should be run from) is in relation to where the notebook server will run.

Then, to run the formgrader, we must set the auth token to be the same as the one that we ran JupyterHub with (and note, as before, that you should generate this auth token and keep it secret):

export CONFIGPROXY_AUTH_TOKEN='foo'
nbgrader formgrade

Running this command will launch the formgrader, which you should be able to access from localhost:8000/hub/nbgrader/example_course. If you properly configured the notebook_url_prefix, you should additionally be able to open live notebooks from the formgrader using your notebook server that was spawned by JupyterHub.