LMS Integration#

Open edX#

  1. You need access to Open edX Studio to set up Open edX with LTI 1.1. You might have to contact your Open edX administrator to get access.

  2. Enable LTI Components for your course.

  3. Pick a name for Open edX to call your JupyterHub server. Then, along with the client key and client secret you generated, create a LTI Passport String in the following format: your-hub-name:client-key:client-secret. The your-hub-name value can be anything, but you’ll be using it throughout Open edX to refer to your JupyterHub instance, so make it something meaningful and unique.

  4. Then add the Passport String to Open edX. Remember to save your changes when done!

  5. In a Unit where you want there to be a link to the hub, add an LTI Component.

    You should enter the following information into the appropriate component settings:

    • LTI ID: The value you entered for your-hub-name above.

    • LTI URL: Should be set to your-hub-url/hub/lti/launch. So if your hub is accessible at http://datahub.berkeley.edu, LTI URL should be http://datahub.berkeley.edu/hub/lti/launch

    • LTI Launch Target: Should be set to New Window.

    • Custom parameters: The only currently supported custom parameter are next and custom_next, which can contain the relative URL that the user should be redirected to after authentication. For example, if you are using nbgitpuller and want the user to see this file after logging in, you could set the field Custom parameters to the following string:

    [
      "next=/hub/user-redirect/git-pull?repo=https://github.com/binder-examples/requirements&subPath=index.ipynb",
    ];
    

    Note: If you have a base_url set in your JupyterHub configuration, that should be prefixed to your next parameter. (Further explanation)

  6. Done! You can click the Link to see what the user workflow would look like. You can repeat step 6 in all the units that should have a link to the Hub for the user.

Canvas#

The setup for Canvas is very similar to the process for Open edX.

Install JupyterHub as an External Tool#

Add a new external app configuration in Canvas. You can name it anything, but you’ll be using it throughout the Canvas course to refer to your JupyterHub instance, so make it something meaningful and unique. Note that the right to create applications might be limited by your institution. The basic information required to create an application in Canvas’ Manual entry mode is:

  • Name: the external tool name, such as JupyterHub

  • Consumer Key: the created consumer key

  • Secret Key: the shared secret

  • Launch URL: https://www.example.com/hub/lti/launch

  • Domain: optional

  • Privacy: anonymous, email only, name only, or public

  • Custom Fields: optional

Canvas also provides the option to add the external tool by selecting either the Paste XML or By URL items from the Course --> Settings --> Apps --> +App section. In these cases, use the /lti11/config endpoint from your JupyterHub instance to copy/paste the configuration XML or add the URL when defining your external tool configuration with the Paste XML or By URL options, respectively.

The application can be created at the account level or the course level. If the application is created at the account level, it means that the application is available to all courses under the same account.

Privacy Setting:

  • If you run the course in public mode, ltiauthenticator will parse the student’s canvas ID as the JupyterHub username.

  • If you run the course in anonymous mode, ltiauthenticator will fall back to the LTI user ID, an anonymized version.

    • Currently, the only method for de-anonymizing the LTI user ID in Canvas is with the “masquerade” permission, which grants the user full access to act as any user account.

    • Unless you are able to obtain masquerade permissions, it is recommended to run the course in public mode.

Create a new assignment.#

  1. Navigate to Assignments -> Add Assignment

  2. For Submission Type, select External Tool

  3. Click on the Find button and search for the external tool by name that you added in the step above. Selecting the external tool will prepopulate the URL field with the correct launch URL.

Important

Using the Find button to search for your external tool is necessary to ensure the LTI consumer key and shared secret are referenced correctly. Else, your launch request will be recognized as unauthorized and responded to with 401 Unauthorized.

  1. (Recommended) Check the Launch in a new tab checkbox.

  2. Append any custom parameters you wish (see next step)

    Note: If you are creating assignments via the Canvas API, you need to use these undocumented external tool fields when creating the assignment.

  3. Custom Parameters: With Canvas users have the option to set custom fields with the Launch Request URL. Unlike Open edX, there is no method to include these custom parameters in the LTI launch request’s form data. However, you can append custom parameters to the launch URL as query strings using proper character encoding to preserve the query strings as they are passed through JupyterHub. You can perform this encoding manually, programmatically, or via an online tool.

    Before:

    https://example.com/hub/lti/launch?custom_next=/hub/user-redirect/git-pull?repo=https://github.com/binder-examples/requirements&subPath=index.ipynb
    

    After:

    https://example.com/hub/lti/launch?custom_next=/hub/user-redirect/git-pull%3Frepo%3Dhttps%3A%2F%2Fgithub.com%2Fbinder-examples%2Frequirements%26subPath%3Dindex.ipynb
    

    Note that the entire query string should not need to be escaped, just the portion that will be invoked after JupyterHub processes the user-redirect command.

  4. Done! You can click the link to see what the user workflow would look like. You can repeat step 7 in all the units that should have a link to the Hub for the user.

Moodle#

General Requirements#

The Moodle setup is very similar to both the Open edX and Canvas setups described above. In addition to completing the steps from the Getting Started sections ensure that:

  1. You have access to a user with the Moodle Administrator role, or have another Moodle Role that gives you Permissions to manage Activity Modules.

  2. You need to have enabled the External Tool Activity Module in your Moodle environment.

  3. If your Moodle environment is using https, you should also use https for your JupyterHub.

Configuration Steps#

  1. Navigate to the course where you would like to add JupyterHub as an external tool

  2. Turn on editing and add an instance of the External Tool Activity Module (https://docs.moodle.org/37/en/External_tool_settings)

    1. Activity Name: This will be the name that appears in the course for students to click on to initiate the connection to your hub.

    2. Click ‘Show more…’ to add additional configuration settings:

    • Tool name: the external tool name, such as JupyterHub.

    • Tool URL: Should be set to your-hub-url/hub/lti/launch. So if your hub is accessible at https://datahub.berkeley.edu, Tool URL should be https://datahub.berkeley.edu/hub/lti/launch.

    • Consumer Key: client key

    • Shared secret: client secret

    • Custom parameters: this is an optional field that you could use to fetch additional values from the launch request.

    • Default launch container: This setting will define how the hub is presented to the end user, whether it’s embedded within a Moodle, with or without blocks, replaces the current window, or is displayed in a new window.

  3. Click Save and return to course or Save and display, you will either be returned to the course page or create an LTI 1.1 launch request to log into the JupyterHub instance.

Common Gotchas#

  1. If you have a base_url set in your JupyterHub configuration, this needs to be reflected in your launch URL and custom parameters. For example, if your jupyterhub_config.py file contains:

c.JupyterHub.base_url = '/jupyter'

then your Launch URL would be:

https://www.example.com/jupyter/hub/lti/launch

A custom next parameter might look like:

[
  "next=/jupyter/hub/user-redirect/git-pull?repo=https://github.com/binder-examples/requirements&subPath=index.ipynb",
];