Hello,
I’m trying to deploy z2jh with nbgrader. here is the information about courses
courses_data = [
{
"name":"course101",
"instructors": ["instructor1"],
"grader": "grader-course101",
"docker_image_instructors": "path/to/image",
"students": ["student1"],
"docker_image_students": "path/to/image"
},
{
"name": "course123",
"instructors": ["instructor2"],
"grader": "grader-course123",
"students": ["student1"],
"docker_image_instructors": "path/to/image",
"docker_image_students": "path/to/image"
}
]
For each course I have a docker image for instrcutors and students where proper nbgrader extensions are enabled/disabled, e.g.
Dockerfile for course101 instructors>
FROM jupyter/base-notebook
# Install nbgrader and any other dependencies you might want, e.g. numpy, scipy, etc.
RUN pip3 install nbgrader numpy scipy matplotlib
# enable formgrader, create_assignment, and validate
RUN jupyter labextension enable --level=sys_prefix nbgrader:validate-assignment
RUN jupyter server extension enable --sys-prefix nbgrader.server_extensions.validate_assignment
...
USER root
# creating global /etc/jupyter/nbgrader_config.py
RUN mkdir -p /etc/jupyter && \
echo "from nbgrader.auth import JupyterHubAuthPlugin" > /etc/jupyter/nbgrader_config.py && \
echo "c = get_config()" >> /etc/jupyter/nbgrader_config.py && \
echo "c.Exchange.path_includes_course = True" >> /etc/jupyter/nbgrader_config.py && \
echo "c.Authenticator.plugin_class = JupyterHubAuthPlugin " >> /etc/jupyter/nbgrader_config.py
# create local /home/jovyan/.jupyter/nbgrader_config.py
RUN mkdir -p /home/jovyan/.jupyter && \
echo "c = get_config()" > /home/jovyan/.jupyter/nbgrader_config.py && \
echo "c.CourseDirectory.root = '/home/jovyan/course101'" >> /home/jovyan/.jupyter/nbgrader_config.py && \
echo "c.CourseDirectory.course_id = 'course101'" >> /home/jovyan/.jupyter/nbgrader_config.py
# setting up shared directory for nbgrader
RUN mkdir -p /usr/local/share/nbgrader/exchange
RUN chmod ugo+rwx /usr/local/share/nbgrader/exchange
And here is my basic config.yaml for installing z2jh:
hub:
cookieSecret: xxxx
config:
Authenticator:
allowed_users:
- instructor1
- instructor2
- student1
- grader-course101
- grader-course123
admin_users:
- grader-course101
- grader-course123
JupyterHub:
admin_access: false
loadRoles:
formgrade-course101:
description: formgrade-course101
scopes: ['access:services!service=course101']
groups: ["formgrade-course101"]
services: ["formgrade-course101"]
formgrade-course123:
description: formgrade-course123
scopes: ['access:services!service=course123']
groups: ["formgrade-course123"]
services: ["formgrade-course123"]
load_groups:
instructors:
- instructor1
- instructor2
formgrade-course101:
- instructor1
- grader-course101
formgrade-course123:
- instructor2
- grader-course123
nbgrader-course101:
- instructor1
- student1
nbgrader-course123:
- instructor2
- student1
services:
course101:
url: http://127.0.0.1:9999
command:
- jupyterhub-singleuser
- '--group=formgrade-course101'
- '--debug'
user: grader-course101
# cwd: ????
# environment:
# JUPYTERHUB_DEFAULT_URL: /lab
api_token: xxxx
course123:
url: http://127.0.0.1:9998
command:
- jupyterhub-singleuser
- '--group=formgrade-course123'
- '--debug'
user: grader-course123
# cwd: ????
# environment:
# JUPYTERHUB_DEFAULT_URL: /lab
api_token: xxxx
proxy:
secretToken: xxxx
singleuser:
image:
name: jupyter/datascience-notebook
tag: latest
cmd: jupyterhub-singleuser
storage:
capacity: 1Gi
extraVolumes:
- name: nbgrader-exchange
persistentVolumeClaim:
claimName: nbgrader-exchange-pvc
extraVolumeMounts:
- name: nbgrader-exchange
mountPath: /usr/local/share/nbgrader/exchange
For the moment I wrote allowed_users
, services
, etc manually in the config file but I know that it is possible to write them as code in extraConfig
:
hub:
extraConfig: |
# read the list of allowed users
c.JupyterHub.allowed_users = ...
But I got very confused about this. My questions are:
1 - Once a user logs in, I would like to identify the users (student, or instructor) and give them the possibility to choose which course to spawn (if they are registered in multiple courses) as profileList and then spawn the proper image that they choose. how can I do that? I think in the case where the spawning doesn’t depend on the user it can be
singleuser:
# Defines the default image
image:
name: jupyter/minimal-notebook
tag: 2343e33dec46
profileList:
- display_name: "Minimal environment"
description: "To avoid too much bells and whistles: Python."
default: true
- display_name: "Datascience environment"
description: "If you want the additional bells and whistles: Python, R, and Julia."
kubespawner_override:
image: jupyter/datascience-notebook:2343e33dec46
how can I do a custom user profile list and spawning in the extraConfig?
2 - As far as I know the home directory is already mounted. what other directories should be mounted? should I create PVC for each user and mount it in the config.yaml?
3 - what is the role of singleuser image & cmd, profilelist.kubespawner_override, and services cmd? which one does the spawning?
I’m trying to generalize the implementation in here:https://github.com/jupyter/nbgrader/tree/main/demos
I appreciate your help.