Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assignment List extension does not support multiple classes #544

Closed
dsblank opened this issue Sep 8, 2016 · 21 comments
Closed

Assignment List extension does not support multiple classes #544

dsblank opened this issue Sep 8, 2016 · 21 comments

Comments

@dsblank
Copy link
Member

dsblank commented Sep 8, 2016

I have a lot of students this year in multiple courses attempting to use nbgrader on jupyterhub (between Physics, Biology, and Computer Science). It appears that every time a student wants to see the Assignments tab for a particular course, they have to edit their nbgrader_config.py file:

c = get_config()
c.NbGrader.course_id = "cs245"
c.TransferApp.exchange_directory = "/opt/nbgrader/exchange/"

This is really a pain, and I'd rather not have students even know about such things, let alone have to edit the file.

Suggestion: make the system know what students are in a course, and show the students all courses that they are enrolled in.

Complication: because there is only one course now (course_id) how will the system know what ID to use for fetch/submission. The UI should know.

@jhamrick
Copy link
Member

jhamrick commented Sep 8, 2016

Yes, it is definitely a problem that the assignment list plugin doesn't currently support multiple courses. Thank you for opening an issue for this -- it's something on the TODO list in my head but something I forgot to actually write down 😄

One thought I had for how to deal with this was to have multiple nbgrader "profiles" in a similar way to how IPython has different profiles (see #361). The interface could then allow people to switch between different profiles if they wanted to view/fetch/submit assignments for different classes.

@jhamrick jhamrick added this to the 0.4.0 milestone Sep 8, 2016
@jhamrick jhamrick changed the title Students in multiple courses have to keep editing their nbgrader_config.py Assignment List extension does not support multiple classes Sep 8, 2016
@dsblank
Copy link
Member Author

dsblank commented Sep 9, 2016

Consider having a list of course_ids for each student, rather just a single course_id. Also, if there could be a single, system-level enrollment config that would map student_ids to course_ids, that would eliminate the need for each student to have a nbgrader_config.py file.

@randy3k
Copy link
Contributor

randy3k commented Sep 9, 2016

👍 for the systemwide database. In fact, I don't think students actually need the file nbgrader_config.py. In default, we could just fetch all available assignments of a particular course on the exchange directory if the corresponding class roster is empty.

Just one thought, is it possible (or allowable) to expand the jupyterhub database jupyterhub.sqlite?

@ellisonbg
Copy link
Contributor

I am having trouble finding the documentation on how to configure the assignment list page to include different courses. Can you point me to the code/docs for that?

@ellisonbg
Copy link
Contributor

ellisonbg commented Jan 18, 2017 via email

@zonca
Copy link
Contributor

zonca commented Mar 25, 2017

@jhamrick UCSD is deploying JupyterHub with nbgrader, we really need to do access control for multiple courses in the assignments list extension, we might be able to contribute some code, could you give us some hints on how to implement that?

@jhamrick
Copy link
Member

Hey @zonca that's great to hear!

Here's how I'd recommend doing it, though if other people have different suggestions we can certainly discuss this further. I think the idea of having a global "enrollment" system is worthwhile, though the drawback is that it means individual instructors can't selectively edit the enrollment of their courses -- either you provide group-level access to all instructors, meaning any instructor can modify the enrollment for any course, or you provide access only to an admin who manages all enrollment information for all courses. So, with that caveat, here's how I envision this would work:

  1. Create a database in the exchange directory, e.g. /srv/nbgrader/exchange/enrollment.db. This should be readable by everyone but only writeable by one person or one group, as described above.
  2. Create a new config option for the Exchange class (in nbgrader/exchange/exchange.py) which is the name of the database.
  3. Add a function to the Exchange class that takes the user id of a student and a course id and checks the database to see if the student is enrolled in the class.
  4. Add another function to the Exchange class that takes the user id of a student and returns the list of classes they are enrolled in.
  5. Modify the ExchangeFetch class to verify that the student is enrolled in the class before fetching.
  6. Modify the ExchangeSubmit class to verify that the student is enrolled in the class before submitting.
  7. Modify the ExchangeList class to only consider course ids that the student is enrolled in.

To manage the enrollment database, we probably want to create a new database-management API (analogous to the models and gradebook defined in nbgrader/api.py) and then new subcommands to import and edit the enrollments (analogous to the commands defined in nbgrader/apps/dbapp.py). The subcommands could maybe be a separate PR, though.

@nabriis
Copy link

nabriis commented Mar 30, 2017

Great to hear this is being worked on!

@jhamrick
Copy link
Member

@zonca did you ever make any progress on this?

@zonca
Copy link
Contributor

zonca commented May 30, 2017

sorry @jhamrick, no progress, still in my todo list...

@jhamrick
Copy link
Member

No problem! I might have some time to work on this soon, and just wanted to make sure I wasn't going to reinvent anything you'd already done :)

@jhamrick
Copy link
Member

I realized there is an issue with my above comment for how to implement this, which is that the enrollment database would be readable by everybody---meaning that anyone with access to that database would be able to see the list of everybody who is enrolled in every class in the database. This is a pretty severe security issue so I don't think that particular implementation is feasible.

An alternate way to do this would be to implement the enrollment checking using JupyterHub groups. Then, ExchangeFetch, ExchangeSubmit, and ExchangeList would query JupyterHub for the groups that the student is in, and only allow functionality if the student is in the relevant group. This functionality is likely to be implemented regardless once JupyterHub file sharing is implemented and we update nbgrader to work with that.

I am going to push this issue to 0.6.0 for now; if anybody has suggestions for alternate implementations let me know.

@jhamrick jhamrick modified the milestones: 0.6.0, 0.5.0 Jun 27, 2017
@zonca
Copy link
Contributor

zonca commented Jul 13, 2017

I'll have some time in August.

so we should create a Jupyterhub group for each class and add students to those groups, then use the groups REST API (the User model returned by querying a user contains also the groups) to query Jupyterhub for students membership in those groups. Right?

@jhamrick
Copy link
Member

@zonca Awesome!

Yes, that's the idea. This shouldn't be difficult to do for the Assignment List extension, but it will be tricky to do for the command line utilities in general since they won't have the auth token for JupyterHub. I think @minrk had some ideas for how to implement this properly, along the lines of getting JupyterHub to set the auth token as an environment variable so that user apps can utilize it?

@zonca
Copy link
Contributor

zonca commented Sep 17, 2017

I implemented this in the Assignment List extension in #893, however I don't know how to do this for command line utilities like nbgrader list.

@minrk We need for example to have the nbgrader list command ran by a student in their single user notebook environment to access the Jupyterhub APIs to get the Jupyterhub groups of the authenticated user. Is there a way to do this?

@minrk
Copy link
Member

minrk commented Sep 18, 2017

@zonca you can GET <hub-host>/hub/api/users/:username to get the user model, which will include their group membership. If you use the JUPYTERHUB_API_TOKEN env variable, you will be able to access this field for the current user.

@zonca
Copy link
Contributor

zonca commented Sep 18, 2017 via email

@minrk
Copy link
Member

minrk commented Sep 18, 2017

Ah, it's hidden from kernel processes on JupyterHub 0.7, but available on 0.8.

@zonca
Copy link
Contributor

zonca commented Sep 18, 2017 via email

@jhamrick
Copy link
Member

Closed by #1040

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants