nbgrader sharing service, vserver implementation.
This repo, https://github.com/lxylxy123456/ngshare-vserver, is for vserver. The repo ngshare is https://github.com/lxylxy123456/ngshare.
May 9, 2020: migrated vserver from ngshare commit 346d568b (Mar 13) to this repo. The upstream development branch is at commit 9213751b (May 7), and it put in ngshare
branch in this repo.
Note that vserver is not supported since Mar 7, 2020, though at this point (346d568b) it still passes all its tests. You may need to go commit 16aa8850 to see vserver at its EOL.
ngshare is a backend server for nbgrader's exchange service.
nbgrader is a Jupyter notebooks extension for grading running on JupyterHub, but it does not work well in distributed setup of JupyterHub like in Kubernetes, because the file systems exchange uses are not connected between containers.
To solve this problem, we are letting exchange to gather all infromation it needs from a set of REST APIs, which is implemented by ngshare. This server will be a JupyterHub managed service.
We are currently working on the frontend (nbgrader) in an nbgrader fork to make it use this API (ngshare, or "backend").
The major problem we need to solve is that nbgrader exchange mechanism uses a directory in Unix file system (exchange directory), which cannot be shared between containers when JupyterHub runs on Kubenetes.
We brainstormed a few possible solutions before starting the ngshare project:
- hubshare
- hubshare is a directory sharing service for JupyterHub.
- Pros
- Universal solution that can be integrated with nbgrader.
- Similar service desired by nbgrader developer (see jupyter/nbgrader#659)
- Cons
- Lots of work to implement HubShare.
- nbgrader exchange mechanism need to be reworked.
- Too generic, does not have permission control specific to classes & assignment. (see this comment)
- NFS
- Another solution is to let every container access a shared file system through NFS (Network File System).
- Pros
- Very doable. Does not "require" input from the Jupyter community.
- Cons
- Not a universal solution.
- Kubernetes Persistent Volume Claim
- Kubernetes Persistent Volume Claim allows containers to request shared file systems.
- Pros
- More universal than the NFS solution. Does not "require" input from the Jupyter community.
- Cons
- Difficult to work around limitations regarding multiple writers per volume. Need to find a way to have correct permissions for students and instructors.
The best solution we think is the first one, but the generic problem still need to be solved. So we decided to find a fourth solution, which is creating a service similar to hubshare but more specialized for nbgrader.
- ngshare
- ngshare implements a set of REST APIs designed for nbgrader exchange mechanism.
- Pros
- Universal solution that can be integrated with nbgrader.
- Fully controlled APIs by this project.
- Cons
- Work needs to be done to implement ngshare.
- nbgrader exchange mechanism needs to be reworked.
The development of ngshare (backend) requires collaborating with frontend development and requires solving technical issues, so our plan breaks the development into different stages.
- Develop vserver (see #Structure) with Unix file system APIs. This allows frontend to forward all file system calls (e.g. read file, write file) to another server. It allows frontend to test the idea when backend is implementing next stage.
- Develop vserver with nbgrader APIs (e.g. create course, release assignment). After this the frontend can begin large changes to the exchange mechanism by replacing file system calls with nbgrader API calls. At this point no authentication is made.
- Add authentication to vserver nbgrader APIs. To make things simple the frontend just needs to send the username, and the backend trusts what frontend does. During the first three stages, the backend can concurrently investigate how to set up a JupyterHub service.
- Port vserver's nbgrader APIs to ngshare (final API server). There should be minimal effort in both backend and frontend as long as JupyterHub service can be set up correctly. The front end need to change the address of the server and send an API token instead of username; the backend need to copy the logic of vserver.
- Maintain ngshare, fix any bugs and implement any features as frontend requests.
Currently we are at stage 5.
You can use ngshare if you
- Need to run nbgrader on a distributed set up (probably using lxylxy123456/nbgrader)
- Have something similar to nbgrader that also needs an API to manage courses, homework submissions and feedbacks, etc.
- Want to learn Flask, SQLAlchemy, or Tornado Web Server.
This project has 2 parts
ngshare
is the final API server that will be used in nbgrader in production. Written as Tornado Web Server and using SQLAlchemy.vserver
is a simple and vulnerable API server, written in Flask, that allows testing the project structurte and development of frontend without waiting for backend.- Mar 7, 2020: Since
ngshare
is already mature, we decided to no longer supportvserver
anymore.vngshare
does almost the exact same thing asngshare
. So the current version ofvserver
should conform to the API documentation at Git version890c4b21
.
- Mar 7, 2020: Since
The database structure is documented in ngshare/database.
The API specifications for ngshare
are available in
api-specifications.md
.
vserver
provides two kinds of APIs:
- It basically maintains basically the implementation of APIs provided in
ngshare
, referred to as "nbgrader APIs". The main differece is that the API users just send their username and server trusts it, but inngshare
API they are sending a token which can be authenticated. - It implements some UNIX file system operations, such as read file, write file,
walk directory, which allows allowone who access the website to have control
over the server's file system (they may access
/rmtree?pathname=/
, so be careful) - Currently all APIs are no longer supported.
- Skip 1 - 10 if using vngshare
git clone https://github.com/lxylxy123456/ngshare
git clone https://github.com/lxylxy123456/nbgrader
- Skip 4 - 7 if using docker
git clone https://github.com/rkevin-arch/zero-to-jupyterhub-k8s
cd zero-to-jupyterhub-k8s
chartpress
(pip3 install
if you do not have it)cd ..
- Skip 9 if using Kubenetes
- install
docker-compose
using package manager (apt
,yum
,dnf
,pacman
, etc.) cd ngshare/testing
cd docker
docker-compose build && docker-compose up
- Open
http://localhost:8000
- If you want to stop the server, Press Ctrl+C once, then wait until exit
cd minikube
- See
./test.sh
for help ./test.sh init
./test.sh install
- Access the address printed using a browser
- e.g.
http://123.456.78.910:1112
- If Kubenetes is running on a remote server, you may want SSH local forward
like
-L 127.0.0.1:66666:123.456.78.910:1112
- e.g.
- vngshare stands for Vserver-like Notebook Grader Share. It is similar to vserver and allows easy testing.
pip3 install tornado jupyterhub sqlalchemy
cd ngshare
python3 vngshare.py [bind_IP_address [port_number]]
- Note that
/tmp/ngshare.db
will be the database created - Though there is no file system APIs, so your system should be safe, but unauthorized people can corrupt your data.
- To test, when
vngshare.py
is running with default IP and port,pytest test_ngshare.py
- Note that vserver is no longer supported since Mar 7, 2020. But it should serve as a good example for learning Flask.
pip3 install flask sqlalchemy
cd vserver
- Make sure that
database
is a symbolic link to../ngshare/database/
python3 vserver.py [bind_IP_address [port_number]]
- Note that
/tmp/vserver.db
will be the database created - Keep in mind that ideally only people you trust can have access to this API
- To test, when
vserver.py
is running with default IP and port,pytest test_nbgrader.py