目录

通过lti1.3将jupyterhub添加到moodle中作为外部工具

这些年一直想用Jupyterhub作为学习平台来尝试一些教学活动,但Jupyterhub用来进行学习管理方面的功能非常欠缺,好在有一个叫LTI(Learning Tools Interoperability,学习工具互操作性)的标准,可以方便的在各个教育技术系统之间无缝集成,所以尝试了一下通过LTI将Jupyterhub作为外部工具添加到Moodle中。

基本概念

LTI是一种标准,LTI1.3是目前这一标准的最新版本之一。

学习工具(Tools)

LTI标准中外部应用程序或服务的统称,如在线测验工具、互动内容平台等,这里Jupyterhub就是学习工具。

平台

提供课程管理、内容管理或学习管理的系统,如LMS(Learning Management System,学习管理系统),这里Moodle就是平台。

安装Moodle

安装

Moodle我使用的是 bitnami提供的Moodle容器(docker) ,直接把 docker-compose.yml 下到本地,安装好docker环境之后,启动服务即可。

# Copyright Broadcom, Inc. All Rights Reserved.
# SPDX-License-Identifier: APACHE-2.0

version: '2'
services:
  mariadb:
    image: docker.io/bitnami/mariadb:11.3
    environment:
      # ALLOW_EMPTY_PASSWORD is recommended only for development.
      - ALLOW_EMPTY_PASSWORD=yes
      - MARIADB_USER=bn_moodle
      - MARIADB_DATABASE=bitnami_moodle
      - MARIADB_CHARACTER_SET=utf8mb4
      - MARIADB_COLLATE=utf8mb4_unicode_ci
    volumes:
      - 'mariadb_data:/bitnami/mariadb'
  moodle:
    image: docker.io/bitnami/moodle:4.4
    ports:
      - '80:8080'
      - '443:8443'
    environment:
      - MOODLE_DATABASE_HOST=mariadb
      - MOODLE_DATABASE_PORT_NUMBER=3306
      - MOODLE_DATABASE_USER=bn_moodle
      - MOODLE_DATABASE_NAME=bitnami_moodle
      # ALLOW_EMPTY_PASSWORD is recommended only for development.
      - ALLOW_EMPTY_PASSWORD=yes
    volumes:
      - 'moodle_data:/bitnami/moodle'
      - 'moodledata_data:/bitnami/moodledata'
    depends_on:
      - mariadb
volumes:
  mariadb_data:
    driver: local
  moodle_data:
    driver: local
  moodledata_data:
    driver: local

在docker-compose.yml目录下启动服务

  docker compose up -d

配置

Moodle中的配置主要是创建一个外部工具,通过这个外部工具调用jupyterhub,可以把用户信息等数据一并传递过去供jupyterhub使用。

创建外部工具

选择 站点管理->插件->活动模块->外部工具->管理 ,点击 "手动配置一个工具":

/images/2024-06-19_11-39-19_screenshot.png

填写jupyterhub服务相关信息(待Jupyterhub环境配置好后)

客户端ID在创建的时候自动生成,无需填写。注意下面红框中的内容需要选择相应的选项开启才能共享用户信息。注意默认启动容器要选择新窗口,因为Jupyterhub的安全设置似乎不允许嵌入方式。

/images/2024-06-19_11-42-53_screenshot.png

查看工具信息

回到 站点管理->插件->活动模块->外部工具->管理 ,会有一个工具列表看到刚刚创建的外部工具,点击其"工具配置细节"

/images/2024-06-19_17-57-37_screenshot.png

Jupyterhub

安装

和Moodle整合需要使用jupyterhub的ltiauthenticator认证器,安装的时候一并安装

  mkdir jupyterhub
  cd jupyterhub
  # 创建python虚拟环境
  python -m venv .venv
  source .venv/bin/activate
  pip install jupyterhub jupyterlab jupyterhub-ltiauthenticator

配置

  cd jupyterhub
  # 编辑jupyterhub配置文件
  vim jupyterhub_config.py

相关配置内容如下:

  import os
  import pwd
  import subprocess

  c = get_config()  # noqa

  # LTI13AUTHENTICATOR configuration for Moodle
  c.JupyterHub.authenticator_class = "ltiauthenticator.lti13.auth.LTI13Authenticator"
  c.LTI13Authenticator.issuer = "http://10.80.73.225:13080"
  c.LTI13Authenticator.client_id = "ty3IkxZtqgrJotg" #Moodle当中的外部工具ID
  c.LTI13Authenticator.authorize_url = "http://10.80.73.225:13080/mod/lti/auth.php" #Moodle的外部工具的身份验证请求URL
  c.LTI13Authenticator.jwks_endpoint = "http://10.80.73.225:13080/mod/lti/certs.php" #Moodle的外部工具的公钥集URL
  c.LTI13Authenticator.username_key = "name" #用户的name作为Jupyterhub的用户名,还可以选email或id

  # Users
  c.Authenticator.admin_users = {"admin1", "admin2"} #Moodle中的管理员的name
  c.Authenticator.allow_all = True #允许所有登录


  # 如果使用systemd类似的需要本地用户账号的spawner,需要先检查jupyterhub系统中是否存在该用户,如果不存在则创建一个新用户以便spawner能正常启动
  def pre_spawn_hook(spawner):
      username = spawner.user.name
      try:
          pwd.getpwnam(username)
      except KeyError:
          subprocess.check_call(["useradd", "-ms", "/bin/bash", username])
          print(f"User {username} has been added.")
      else:
          print(f"User {username} is already exist.")

  c.JupyterHub.spawner_class = "systemd"
  c.Spawner.pre_spawn_hook = pre_spawn_hook
  # 一些安全设置,隔离temp目录和硬件设备
  c.SystemdSpawner.isolate_tmp = True
  c.SystemdSpawner.isolate_devices = True

Moodle的课程中添加Jupyterhub外部工具

如果课程中需要添加Jupyterhub作为外部工具,需要首先设置在课程的活动选择中启用这个外部工具:

/images/2024-06-19_17-59-44_screenshot.png

之后在添加活动资源的时候就可以看到这个外部工具,添加到课程中即可。

/images/2024-06-19_18-00-54_screenshot.png

最终效果如下,在课程中会看到jupyterhub的连接,点击之后会传递当前用户的用户名(个人资料中的姓+名)作为jupyterhub中的用户名。

/images/2024-06-19_18-02-46_screenshot.png