question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Create a JupyterHub "exchange" service to replace the exchange directory

See original GitHub issue

I would eventually like to replace the nbgrader exchange directory with a more robust solution, namely, a JupyterHub “exchange” service that manages released assignments, submissions, and feedback. This has the drawback that people won’t be able to use nbgrader’s file management capabilities unless they are using JupyterHub. In practice, I don’t think anyone is using nbgrader’s file management capabilities without JupyterHub anyway, though (but if I am wrong about this, someone should correct me!). Here’s how I will imagine this working.

@lgpage @minrk @ellisonbg @willingc @dsblank I would appreciate any feedback you have on this proposal!

Permissions

All authentication will be handled by JupyterHub, which will tell the service who the current user is and what group(s) they are a part of. The exchange service will handle any number of courses on the same machine, and for each course, will require that there are two groups specified: one for instructors (who are allowed to release, fetch, submit, and collect assignments and return feedback) and one for students (who are allowed to fetch and submit assignments and download feedback). This would be configured something like this:

c.ExchangeApp.groups = {
    'course1': dict(instructors='instructors_course1', students='students_course1'),
    'course2': dict(instructors='instructors_course2', students='students_course2'),
    ...
}

API

The exchange service will define a REST api that the nbgrader commands (release, fetch, submit, collect, etc.) can access.

/api/assignments

  • GET /api/assignments/<course_id> – list all assignments for a course (students+instructors)

/api/assignment

  • GET /api/assignment/<course_id>/<assignment_id> – download a copy of an assignment (students+instructors)
  • POST /api/assignment/<course_id>/<assignment_id> – release an assignment (instructors only)

/api/submissions

  • GET /api/submissions/<course_id>/<assignment_id> – list all submissions for an assignment from all students (instructors only)
  • GET /api/submissions/<course_id>/<assignment_id>/<student_id> – list all submissions for an assignment from a particular student (instructors+students, though students are restricted to only viewing their own submissions)

/api/submission

  • POST /api/submission/<course_id>/<assignment_id>/<student_id> – submit a copy of an assignment (students+instructors)
  • GET /api/submission/<course_id>/<assignment_id>/<student_id> – download a student’s submitted assignment (instructors only)

/api/feedback

  • POST /api/feedback/<course_id>/<assignment_id>/<student_id> – upload feedback on a student’s assignment (instructors only)
  • GET /api/feedback/<course_id>/<assignment_id>/<student_id> – download feedback on a student’s assignment (instructors+students, though students are restricted to only viewing their own feedback)

Exchange implementation

Under the hood, the exchange service will continue to store files directly on the filesystem, but they will all have the same permissions (read and write only for the user running the exchange service). I think this is a better option that doing it with a database because we don’t really need any fancy relational features here and this also makes it easier for instructors to inspect files in the exchange manually. If someone feels strongly that a database should be used then I might be able to be convinced otherwise, though.

Regardless, I do want to implement some form of checksumming, though, because I have noticed at least in the current implementation that sometimes if the system is under heavy load that the submissions are occasionally incomplete or corrupted (e.g. missing timestamp.txt or something).

Existing nbgrader apps

The existing nbgrader apps will be reworked to make requests to the exchange API rather than copying to and from the exchange directory.

One thing I am not quite sure of is how the command line apps get properly authenticated, because the authentication is normally happening in the browser, not the command line. I see two possible solutions:

  • One solution to this is to say that these commands can only be used through the server extension, and then have that extension pass the authentication information to the command line apps. This is probably the easiest but then it means you can’t just run the commands from the command line anymore.
  • The other solution is to require some how that users re-authenticate from the command line. I am not really sure how to this in a general way that handles all the forms of authentication that JupyterHub uses. Maybe @minrk can weigh in on the feasibility of this, but from what I know about how this works it doesn’t seem like a particularly feasible option to me?

Issue Analytics

  • State:open
  • Created 7 years ago
  • Reactions:3
  • Comments:26 (25 by maintainers)

github_iconTop GitHub Comments

1reaction
ellisonbgcommented, Feb 7, 2017

A page to get a token would be helpful!

On Mon, Feb 6, 2017 at 2:33 AM, Min RK notifications@github.com wrote:

One thing I am not quite sure of is how the command line apps get properly authenticated

I’d use authentication tokens for this. HubAuth did recently get support for API tokens in the Authorization header, not just cookies. You can store these in a file once generated. I think we do need to have a page for requesting a new token in the Hub UI to complete the loop, though. It would look like:

  1. request an API token (this is fiddly right now, but I’ll add a page for it)
  2. save that somewhere like ~/.nbgrader/token
  3. CLI apps look for this file, use it in Authorization header. If not present, point to Hub page where they can get one.

Spawners could request and install this token at launch, to make it easy to do it from the single-user-server terminal.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/jupyter/nbgrader/issues/659#issuecomment-277643882, or mute the thread https://github.com/notifications/unsubscribe-auth/AABr0EpcVmc_DX7ScgH8IBHxN21UNAXoks5rZvblgaJpZM4LkDD9 .

– Brian E. Granger Associate Professor of Physics and Data Science Cal Poly State University, San Luis Obispo @ellisonbg on Twitter and GitHub bgranger@calpoly.edu and ellisonbg@gmail.com

0reactions
perllaghucommented, Dec 2, 2022

I believe we can close this.

In response to:

Currently, the exchange service does not provide a mean to share nbgrader’s grade database among several instructors, right?

We have the following solution:

Each course gets it’s own database in a central database server, and a directory on a central FileStore server.

When an instructor starts their notebook server in our system, the database URL is calculated & set for that course, and the directory in the central FileStore is mounted. We also set c.CourseDirectory.root to a path specific for that course.

Thus all instructors have access to the same database, and the same course files: source, release, submitted, autograded, feedback.

… Oh, and we found it useful to set c.CourseDirectory.directory_structure = '{nbgrader_step}/{assignment_id}/{student_id}' - but that’s just us…

[How 10 markers manage the 200 submissions is not in the solution: they all see the same dataset]

Read more comments on GitHub >

github_iconTop Results From Across the Web

Exchanging assignment files — nbgrader 0.8.1 documentation
This page describes the built-in implementation of an exchange directory coupled with instructor and student interfaces - both integrated in the Jupyter ......
Read more >
Nbgrader with Littlest JupyterHub releases assignment to ...
Create the /srv/nbgrader/exchange directory and add the permissions like this: chmod ugo+rw /srv/nbgrader/exchange · Open the nbgrader_config.py ...
Read more >
How to Install the Jupyter Notebook Server on Mac - Medium
Jupyter Notebook is a program that's used to create, modify, ... The Change Directory (cd) command is used to change the current working...
Read more >
Jupyter Notebook - Change HTTP Headers
You can generate a config file in your home directory by running: jupyter notebook --generate-config. which should leave you with a file ...
Read more >
Run Jupyter notebooks in your workspace - Azure
Save and checkpoint a notebook. Azure Machine Learning creates a checkpoint file when you create an ipynb file. In the notebook toolbar, select ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found