Skip to content

Commit

Permalink
Handle multiple courses with JupyterHub when using Notebook
Browse files Browse the repository at this point in the history
  • Loading branch information
brichet committed Sep 1, 2023
1 parent d0ae737 commit 043cabe
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 50 deletions.
8 changes: 4 additions & 4 deletions demos/demo_multiple_classes/jupyterhub_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@
'user': 'grader-course101',
'cwd': '/home/grader-course101',
'environment': {
# specify formgrader as default landing page
'JUPYTERHUB_DEFAULT_URL': '/formgrader'
# specify lab as default landing page
'JUPYTERHUB_DEFAULT_URL': '/lab'
},
'api_token': '{{course101_token}}',
},
Expand All @@ -116,8 +116,8 @@
'user': 'grader-course123',
'cwd': '/home/grader-course123',
'environment': {
# specify formgrader as default landing page
'JUPYTERHUB_DEFAULT_URL': '/formgrader'
# specify lab as default landing page
'JUPYTERHUB_DEFAULT_URL': '/lab'
},
'api_token': '{{course123_token}}',
},
Expand Down
4 changes: 2 additions & 2 deletions demos/demo_one_class_multiple_graders/jupyterhub_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@
],
'user': 'grader-course101',
'environment': {
# specify formgrader as default landing page
'JUPYTERHUB_DEFAULT_URL': '/formgrader'
# specify lab as default landing page
'JUPYTERHUB_DEFAULT_URL': '/lab'
},
'cwd': '/home/grader-course101',
}
Expand Down
26 changes: 0 additions & 26 deletions demos/formgrader_workspace.json

This file was deleted.

4 changes: 0 additions & 4 deletions demos/utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ setup_nbgrader () {
${runas} mkdir -p "${HOME}/.jupyter"
${runas} cp "${config}" "${HOME}/.jupyter/nbgrader_config.py"
${runas} chown "${USER}:${USER}" "${HOME}/.jupyter/nbgrader_config.py"

cp "/root/formgrader_workspace.json" "${HOME}/formgrader_workspace.json"
chown "${USER}:${USER}" "${HOME}/formgrader_workspace.json"
${runas} jupyter lab workspaces import "${HOME}/formgrader_workspace.json"
}

setup_jupyterhub () {
Expand Down
8 changes: 4 additions & 4 deletions nbgrader/server_extensions/course_list/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def check_for_local_formgrader(self, config):
if status:
raise gen.Return([{
'course_id': coursedir.course_id,
'url': base_url + '/formgrader',
'url': base_url + '/lab',
'kind': 'local'
}])

Expand All @@ -102,7 +102,7 @@ def check_for_noauth_jupyterhub_formgraders(self, config):
if not coursedir.course_id:
raise gen.Return([])

url = self.get_base_url() + "/services/" + coursedir.course_id + "/formgrader"
url = self.get_base_url() + "/services/" + coursedir.course_id
auth = get_jupyterhub_authorization()
http_client = AsyncHTTPClient()
try:
Expand All @@ -113,7 +113,7 @@ def check_for_noauth_jupyterhub_formgraders(self, config):

courses = [{
'course_id': coursedir.course_id,
'url': url,
'url': url + "/lab",
'kind': 'jupyterhub'
}]
raise gen.Return(courses)
Expand Down Expand Up @@ -156,7 +156,7 @@ def check_for_jupyterhub_formgraders(self, config):
service = services[course]
courses.append({
'course_id': course,
'url': self.get_base_url() + service['prefix'].rstrip('/') + "/formgrader",
'url': self.get_base_url() + service['prefix'].rstrip('/') + "/lab",
'kind': 'jupyterhub'
})

Expand Down
24 changes: 17 additions & 7 deletions src/course_list/courselist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export async function requestAPI<T>(
return data;
}

function createElementFromCourse(data: any, app: JupyterFrontEnd) {
function createElementFromCourse(data: any, app: JupyterFrontEnd, isNotebook:boolean) {
var element = document.createElement('div') as HTMLDivElement;
element.classList.add('list_item','row');

Expand All @@ -54,16 +54,18 @@ function createElementFromCourse(data: any, app: JupyterFrontEnd) {
var anchor = document.createElement('a') as HTMLAnchorElement;
anchor.href = '#';
anchor.innerText = data['course_id'];

if (data['kind'] == 'local') {
anchor.href = '#';
anchor.onclick = function() {
app.commands.execute(commandIDs.openFormgrader, data);
}
}
else {
} else {
const url = data['url'] as string;
anchor.href = URLExt.join(url.replace(/formgrader$/, 'lab'), 'workspaces', 'formgrader');
if (isNotebook) {
anchor.href = URLExt.join(url.replace(/lab\/?$/, 'tree'));
} else {
anchor.href = url
}
anchor.target = 'blank';
}

Expand All @@ -85,9 +87,15 @@ export class CourseList {
listerror: HTMLDivElement;
listerrortext: HTMLDivElement;
app: JupyterFrontEnd;
private _isNotebook: boolean;

constructor(public course_list_element: HTMLDivElement, app: JupyterFrontEnd) {
constructor(
public course_list_element: HTMLDivElement,
app: JupyterFrontEnd,
isNotebook: boolean
) {
this.app = app;
this._isNotebook = isNotebook;
this.listplaceholder = document.createElement('div') as HTMLDivElement;
this.listplaceholder.id = 'formgrader_list_placeholder';
this.listplaceholder.classList.add('list_placeholder');
Expand Down Expand Up @@ -170,7 +178,9 @@ export class CourseList {
this.listplaceholder.hidden = true;
}
for (var i=0; i<len; i++) {
this.course_list_element.appendChild(createElementFromCourse(data[i], this.app));
this.course_list_element.appendChild(
createElementFromCourse(data[i], this.app, this._isNotebook)
);
}

}
Expand Down
4 changes: 2 additions & 2 deletions src/course_list/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class CourseListWidget extends Widget {
courselist: CourseList;
app: JupyterFrontEnd;

constructor(app: JupyterFrontEnd) {
constructor(app: JupyterFrontEnd, isNotebook: boolean) {
super();
this.app = app;
var maindiv = document.createElement('div') as HTMLDivElement;
Expand Down Expand Up @@ -55,7 +55,7 @@ export class CourseListWidget extends Widget {
formgraderlist.classList.add('list_container');

// further initialization of formgraderlist is in here
this.courselist = new CourseList(formgraderlist, this.app);
this.courselist = new CourseList(formgraderlist, this.app, isNotebook);

panelbody.appendChild(formgraderlist);
panel.appendChild(panelbody);
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ const courseListExtension: JupyterFrontEndPlugin<void> = {
label: 'Course List',
execute: () => {
if (!widget || widget.isDisposed) {
const content = new CourseListWidget(app);
const content = new CourseListWidget(app, notebookTree !== null);
widget = new MainAreaWidget({content});
widget.id = 'nbgrader-course-list';
widget.addClass('nbgrader-mainarea-widget');
Expand Down

0 comments on commit 043cabe

Please sign in to comment.