This grading service accepts anonymous submissions for grading via HTTP. The submissions are graded either synchronously in the web application or asynchronously in containers (usually in Kubernetes, though it is possible to run Docker containers in the web server for a small number of submissions). The results are delivered to the calling system and the grader does not keep any record other than service logs. The grader is designed to serve exercises for the A+ learning system. If the number of submissions is large, we recommend setting up a Kubernetes cluster for the grader.
The grader is implemented on Django 3.2 (grader/settings.py
).
The application requires Python 3.7 or newer.
The grader can be run stand alone without the full stack to test graders in
the local system environment. The grader is designed to be extended for
different courses and exercise types. Course and exercise configuration is in
courses
directory where further documentation and examples are available.
You may run the app with Docker without installing the whole software stack locally. It is easy to get started with the aplus-manual course: apluslms/aplus-manual. The Docker image is intended for local development and testing, not production: apluslms/run-mooc-grader.
Ubuntu 20.04
General requirements
sudo apt-get install git libjpeg-dev
sudo apt-get install libxml2-dev libxslt-dev zlib1g-dev
Install software
git clone https://github.com/apluslms/mooc-grader.git
mkdir mooc-grader/uploads
sudo apt-get install python3 python3-dev python3-pip python3-venv
Then, create virtual environment with grader requirements.
python3 -m venv venv
source venv/bin/activate
pip install wheel
pip install -r mooc-grader/requirements.txt
Run the Django app locally:
cd mooc-grader
python manage.py runserver
The exercise configuration and grading of individual exercises can be tested from the command line.
python manage.py exercises
python manage.py grade
Ubuntu 20.04
On a server, one can install mooc-grader for a specific grader user account.
sudo adduser --system --group \
--shell /bin/bash --home /srv/grader \
--gecos "A-plus mooc-gracer service" \
grader
su - grader
Then follow the "Installing for development" and continue from here.
echo "d /run/grader 0750 grader www-data - -" | \
sudo tee /etc/tmpfiles.d/grader.conf > /dev/null
sudo systemd-tmpfiles --create
Install uwsgi to run WSGI processes. The mooc-grader directory and user must be set in the configuration files.
source ~/venv/bin/activate
pip install uwsgi
cp ~/mooc-grader/doc/etc-uwsgi-grader.ini ~/grader-uwsgi.ini
sudo cp ~grader/mooc-grader/doc/etc-systemd-system-uwsgi.service /etc/systemd/system/grader-uwsgi.service
# EDIT ~/grader-uwsgi.ini
# EDIT /etc/systemd/system/grader-uwsgi.service, set the correct uwsgi path to ExecStart
Operate the workers:
# as root
systemctl status grader-uwsgi
systemctl start grader-uwsgi
systemctl enable grader-uwsgi # start on boot
# Graceful application reload
touch ~grader/grader-uwsgi.ini
apt-get install nginx
sed -e "s/__HOSTNAME__/$(hostname)/g" \
~grader/mooc-grader/doc/etc-nginx-sites-available-grader > \
/etc/nginx/sites-available/$(hostname).conf
ln -s ../sites-available/$(hostname).conf /etc/nginx/sites-enabled/$(hostname).conf
# Edit /etc/nginx/sites-available/$(hostname).conf if necessary
# Check nginx config validity
nginx -t
systemctl reload nginx
apt-get install apache2 libapache2-mod-uwsgi
# Configure based on doc/etc-apache2-sites-available-grader
a2enmod headers
When deploying, overwrite necessary configurations in mooc-grader/grader/local_settings.py
.
Alternatively, the system can be disabled by settings DISABLE_JWT_SIGNING
and
DISABLE_LOGIN_CHECKS
in the APLUS_AUTH
dict in the settings to True.
-
Create RSA keys for JWT authentication
# generate private key openssl genrsa -out private.pem 2048 # extract public key openssl rsa -in private.pem -out public.pem -pubout
-
Fill the
APLUS_AUTH
settings (inlocal_settings.py
). Check the comments insettings.py
. -
Add the RSA public key to A+ settings.