Skip to content

1. Installation

mpetojevic edited this page Sep 27, 2023 · 2 revisions

Installation requirements

Before installing the Grader Service on your machine, make sure to meet the following requirements:

# Python is needed for all packages

Python>=3.10

# For Grader labextension you will need:
JupyterHub
JupyterLab
pip
Node.js>=12
npm

Installing Grader Service

This repository contains the packages for the jupyter extensions and the grader service as well as grader-convert.

The grader service has only been tested on Unix/macOS operating systems.

This repository contains all the necessary packages for a full installation of the grader service.

  • grader-convert: A tool for converting notebooks to different formats (e.g. removing solution code, executing, etc.). It can be used as a command line tool but will mainly be called by the service. The conversion logic is based on nbgrader.
pip install grader-convert
  • grader-labextension: The JupyterLab plugin for interacting with the service. Provides the UI for instructors and students and manages the local git repositories for the assignments etc.
pip install grader-labextension
  • grader-service: Manages students and instructors, files, grading and multiple lectures. It can be run as a standalone containerized service and can utilize a kubernetes cluster for grading assignments.
pip install grader-service

Installing from Source

In order to locally install Grader Service make sure to clone this project on your machine or download zip file

Local installation

Once you have your local copy of Grader Service repository navigate to graderservice directory and run:

pip install -r ./grader_convert/requirements.txt
pip install --no-use-pep517 ./grader_convert

pip install -r ./grader_labextension/requirements.txt
pip install ./grader_labextension

pip install -r ./grader_service/requirements.txt
pip install --no-use-pep517 ./grader_service

To install grader-labextension in development mode and contribute to it, follow instructions in section :ref:`Grader Labextension Development Install <grader-labextension-dev-install>`.

Installation Scripts

Alternatively you can use installation scripts which you can find in examples/dev_environment directory. This directory provides you with local development environment and and servers as a guide for more complex setups. The bash scripts have to be run in the dev_environment directory.

It contains four bash files:

  • install.sh: Sets up a virtual environment in the directory and install the necessary dependencies. Also creates the directories for the grader service.
  • run_hub.sh: Start a JupyterHub instance with the config provided in jupyter_hub_config.py.
  • run_service.sh: Start a grader service instance with the config provided in grader_service_config.py.
  • clean.sh: Cleans up the directories created in install.sh and other auxiliary files. Does not delete the virtual environment.

In order to install Grader Service navigate to folder examples/dev_environment. Make sure to run installation script by running command line bash ./install.sh. Installation script creates a virtual enviroment and installs all needed packages in it.

To start JuypterHub, run bash ./run_hub.sh in the command line. JupyterHub instance will be running at http://localhost:8080.

To connect JupyterHub to Grader Service open a separate terminal and run following command line: bash ./run_service.sh. Once shell script was run, Grader Service automatically connects to Jupyterhub. Grader Service runs at http://127.0.0.1:4010.

Starting Grader Service

Starting JupyterHub

You first need a file named jupyter_hub_cofig.py. For a practical example you can take a look at examples/dev-environment. To run the grader service you first have to register the service in JupyterHub as an unmanaged service in the config:

c.JupyterHub.services.append(
    {
        'name': 'grader',
        'url': 'http://127.0.0.1:4010',
        'api_token': '<token>'
    }
)

The api token can be generated in the jupyterhub control panel. You can verify the config by running jupyterhub -f <config_file.py> and you should see the following error message:

Cannot connect to external service grader at http://127.0.0.1:4010. Is it running?

Since the JupyterHub is the only source of authentication for the service, it has to rely on the JupyterHub to provide all the necessary information for user groups.

Users have to be added to specific groups which maps the users to lectures and roles. They have to be separated by colons.

The config could look like this:

## generic
c.JupyterHub.admin_access = True
c.Spawner.default_url = '/lab'
c.Spawner.cmd=["jupyter-labhub"]


## authenticator
c.JupyterHub.authenticator_class = 'jupyterhub.auth.DummyAuthenticator'
c.Authenticator.allowed_users = {'user1', 'user2', 'user3', 'user4'}
c.Authenticator.admin_users = {'user1', 'user2', 'user3', 'user4'}

## spawner
c.JupyterHub.spawner_class = 'jupyterhub.spawner.SimpleLocalProcessSpawner'
c.SimpleLocalProcessSpawner.home_dir_template = '/path/to/lab_dir/{username}'


c.JupyterHub.load_groups = {
    "lect1:instructor": {'users': ["user1"]},
    "lect1:tutor": {'users': ["user2"]},
    "lect1:student": {'users': ["user3", "user4"]},
}

Here, user1 is an instructor of the lecture with the code lect1 and so on.

Starting the service

In order to start the grader service we have to provide a configuration file for it as well:

import os

c.GraderService.service_host = "127.0.0.1"
# existing directory to use as the base directory for the grader service
service_dir = os.path.expanduser("<grader_service_dir>")
c.GraderService.grader_service_dir = service_dir

c.JupyterHubGroupAuthenticator.hub_api_url = "http://127.0.0.1:8081/hub/api"

c.LocalAutogradeExecutor.base_input_path = os.path.expanduser(os.path.join(service_dir, "convert_in"))
c.LocalAutogradeExecutor.base_output_path = os.path.expanduser(os.path.join(service_dir, "convert_out"))

The <token> has to be the same value as the JupyterHub service token specified earlier. The grader_service_dir directory has to be an existing directory with appropriate permissions to let the grader service read and write from it.

Alternatively, you can run grader-service --generate-config -f /path/to/grader_service_config.py to generate the skeleton for the config file that show all possible configuration options.

Furthermore the database must be initialized before we can start the service. To do this navigate to the grader_service_dir that was specified and execute the following command:

grader-service-migrate

Then the grader service can be started by specifying the config file as such:

grader-service -f <grader_service_config.py>

When restarting the JupyterHub you should now see the following log message:

Adding external service grader at http://127.0.0.1:4010

Do not forget to set the log level to INFO in the JupyterHub config if you want to see this message.

The last thing we have to configure is the server-side of the JupyterLab plugin which also needs information where to access the endpoints of the service. This can be done in the jupyter_notebook_config.py file. When using the defaults from above we do not need to explicitly configure this but it would look like this:

import os
c.GitService.git_access_token = os.environ.get("JUPYTERHUB_API_TOKEN")
c.GitService.git_remote_url = "http://127.0.0.1:4010/services/grader/git"

c.RequestService.url = "http://127.0.0.1:4010"

Alias for starting Grader Service

Create a configs directory where you are going to store your jupyter_hub_config.py and grader_service_config.py files. In the example below, the configs directory is located in the work directory, where the graderservice directory is also stored.

Creating an alias for starting JupyterHub:

alias jupyterhubstart='cd ~/work/configs && jupyterhub -f jupyter_hub_config.py'

Creating an alias for starting Grader Service:

alias graderservice='cd ~/work/configs && grader-service -f grader_service_config.py'

Now run the command jupyterhubstart in one terminal and graderservice in another. If your configuration of JupyterHub is the same as in the example above, the JupyterHub instance will be running at localhost:8000. However, you can specify another port in jupyter_hub_config.py by setting c.JupyterHub.port = .... The Grader Service should be automatically connected to JupyterHub.