Grading Container Image

When you use Otter Generate to create the configuration zip file for Gradescope, Otter includes the following software and packages for installation. The zip archive, when unzipped, has the following contents:

| - environment.yml
| - otter_config.json
| - requirements.R
| - requirements.txt
| - run_autograder
| -
| -
| files/
  | - ...
| tests/
  | - ...

Note that for pure-Python assignments, requirements.R is not included and all of the R-pertinent portions of are removed. Below are descriptions of each of the items listed above and the Jinja2 templates used to create them (if applicable).

This file, required by Gradescope, performs the installation of necessary software for the autograder to run. The script template looks like this:

#!/usr/bin/env bash

# apt-get clean
# apt-get update
# apt-get install -y python3.7 python3-pip python3.7-dev

apt-get clean
apt-get update
apt-get install -y pandoc
apt-get install -y texlive-xetex texlive-fonts-recommended texlive-generic-recommended

# install wkhtmltopdf
wget --quiet -O /tmp/wkhtmltopdf.deb
apt-get install -y /tmp/wkhtmltopdf.deb

# update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 1

# try to set up R
apt-get clean
apt-key adv --keyserver --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9
add-apt-repository 'deb bionic-cran40/'

add-apt-repository ppa:cran/libgit2
apt-get update
apt-get install -y build-essential libcurl4-gnutls-dev libxml2-dev libssl-dev libgit2-dev

# install conda
wget -nv -O {{ autograder_dir }}/source/ "{{ miniconda_install_url }}"
chmod +x {{ autograder_dir }}/source/
{{ autograder_dir }}/source/ -b
echo "export PATH=/root/miniconda3/bin:\$PATH" >> /root/.bashrc

export PATH=/root/miniconda3/bin:$PATH
export TAR="/bin/tar"

# # install R dependencies
# conda install --yes r-base r-essentials 
# conda install --yes r-devtools -c conda-forge

# # install requirements
# pip3 install -r {{ autograder_dir }}/source/requirements.txt
# pip install -r {{ autograder_dir }}/source/requirements.txt
# Rscript {{ autograder_dir }}/source/requirements.r

# install dependencies with conda
conda env create -f {{ autograder_dir }}/source/environment.yml
conda run -n {{ otter_env_name }} Rscript {{ autograder_dir }}/source/requirements.r

# set conda shell
conda init --all

# install ottr; not sure why it needs to happen twice but whatever
git clone --single-branch -b {{ ottr_branch }} {{ autograder_dir }}/source/ottr
cd {{ autograder_dir }}/source/ottr 
conda run -n {{ otter_env_name }} Rscript -e "devtools::install\\(\\)"
conda run -n {{ otter_env_name }} Rscript -e "devtools::install\\(\\)"

This script does the following:

  1. Install Python 3.7 and pip

  2. Install pandoc and LaTeX

  3. Install wkhtmltopdf

  4. Set Python 3.7 to the default python version

  5. Install apt-get dependencies for R

  6. Install Miniconda

  7. Install R, r-essentials, and r-devtools from conda

  8. Install Python requirements from requirements.txt (this step installs Otter itself)

  9. Install R requires from requirements.R

  10. Install Otter’s R autograding package ottr

Currently this script is not customizable, but you can unzip the provided zip file to edit it manually.


This file specifies the conda environment that Otter creates in

{% if not other_environment %}name: {{ otter_env_name }}
    - defaults
    - conda-forge
    - python=3.7
    - pip
    - nb_conda_kernels
    - r-base 
    - r-essentials 
    - r-devtools
    - libgit2
    - pip:
        - -r file:requirements.txt{% else %}{{ other_environment }}{% endif %}


This file contains the Python dependencies required to execute submissions. It is also the file that your requirements are appended to when you provided your own requirements file for a Python assignment (unless --overwrite-requirements is passed). The template requirements for Python are:

{% if not overwrite_requirements %}datascience
{% endif %}{% if other_requirements %}
{{ other_requirements }}{% endif %}

If you are using R, there will be no additional requirements sent to this template, and rpy2 will be added. Note that this installs the exact version of Otter that you are working from. This is important to ensure that the configurations you set locally are correctly processed and processable by the version on the Gradescope container. If you choose to overwrite the requirements, make sure to do the same.


This file uses R functions like install.packages and devtools::install_github to install R packages. If you are creating an R assignment, it is this file (rather than requirements.txt) that your requirements and overwrite-requirements options are applied to. The template file contains:


This is the file that Gradescope uses to actually run the autograder when a student submits. Otter provides this file as an executable that activates the conda environment and then calls /autograder/source/

#!/usr/bin/env bash

export PATH="/root/miniconda3/bin:$PATH"
source /root/miniconda3/etc/profile.d/
conda activate {{ otter_env_name }}
python {{ autograder_dir }}/source/

This file contains the logic to start the grading process by importing and running

Runs Otter on Gradescope

import os
import subprocess

from import main as run_autograder

if __name__ == "__main__":
    run_autograder('{{ autograder_dir }}')


This file contains any user configurations for grading. It has no template but is populated with the default values and any updates to those values that a user specifies. When debugging grading via SSH on Gradescope, a helpful tip is to set the debug key of this JSON file to true; this will stop the autograding from ignoring errors when running students’ code, and can be helpful in debugging specific submission issues.


This is a directory containing the test files that you provide. All .py (or .R) files in the tests directory path that you provide are copied into this directory and are made available to submissions when the autograder runs.


This directory, not present in all autograder zip files, contains any support files that you provide to be made available to submissions.