Skip to content
Easy, safe evaluation of arbitrary Python code
Python Shell Dockerfile
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github Rename .github/FUNDING.yml to .github/.github/FUNDING.yml Jun 9, 2019
docker CI: fix NsJail clone in base Docker image Sep 4, 2019
scripts
snekbox Fix multiline function definition Sep 23, 2019
tests
.coveragerc Fix venv being included in coverage when testing in a container Jun 22, 2019
.dockerignore
.flake8 Add flake8-annotations & relint Sep 23, 2019
.gitignore
.pre-commit-config.yaml Pin dependencies for flake8 pre-commit hook Aug 5, 2019
CONTRIBUTING.md
LICENSE Initial commit May 21, 2018
Pipfile Add flake8-annotations & relint Sep 23, 2019
Pipfile.lock Add flake8-annotations & relint Sep 23, 2019
README.md Use pipenv sync instead of pipenv --sync Oct 5, 2019
azure-pipelines.yml
docker-compose.yml

README.md

Build Status

snekbox

Python sandbox runners for executing code in isolation aka snekbox.

A client sends Python code to a snekbox, the snekbox executes the code, and finally the results of the execution are returned to the client.

          +-------------+           +-----------+
 input -> |             |---------->|           | >----------+
          |  HTTP POST  |           |  SNEKBOX  |  execution |
result <- |             |<----------|           | <----------+
          +-------------+           +-----------+
             ^                         ^
             |                         |- Executes python code
             |                         |- Returns result
             |                         +-----------------------
             |
             |- HTTP POST Endpoint receives request and returns result
             +---------------------------------------------------------

The code is executed in a Python process that is launched through NsJail, which is responsible for sandboxing the Python process. NsJail is configured as follows:

  • Root directory is mounted as read-only
  • Time limit of 2 seconds
  • Maximum of 1 PID
  • Maximum memory of 52428800 bytes
  • Loopback interface is down
  • procfs is disabled

The Python process is configured as follows:

  • Version 3.7.4
  • Isolated mode
    • Neither the script's directory nor the user's site packages are in sys.path
    • All PYTHON* environment variables are ignored

HTTP REST API

Communication with snekbox is done over a HTTP REST API. The framework for the HTTP REST API is Falcon and the WSGI being used is Gunicorn. By default, the server is hosted on 0.0.0.0:8060 with two workers.

See snekapi.py and resources for API documentation.

Development Environment

Initial Setup

A Python 3.7 interpreter and the pipenv package are required. Once those requirements are satisfied, install the project's dependencies:

pipenv sync

Follow that up with setting up the pre-commit hook:

pipenv run precommit

Now Flake8 will run and lint staged changes whenever an attempt to commit the changes is made. Flake8 can still be invoked manually:

pipenv run lint

Running snekbox

The Docker images can be built with:

pipenv run buildbase
pipenv run buildvenv
pipenv run build

Use Docker Compose to start snekbox:

docker-compose up

Running Tests

Tests are run through coverage.py using unittest. Before tests can run, the dev venv Docker image has to be built:

pipenv run builddev

Alternatively, the following command will build the image and then run the tests:

pipenv run testb

If the image doesn't need to be built, the tests can be run with:

pipenv run test

Coverage

To see a coverage report, run

pipenv run report

Alternatively, a report can be generated as HTML:

pipenv run coverage html

The HTML will output to ./htmlcov/ by default

The devsh Helper Script

This script starts an ash shell inside the venv Docker container and attaches to it. Unlike the production image, the venv image that is built by this script contains dev dependencies too. The project directory is mounted inside the container so any filesystem changes made inside the container affect the actual local project.

Usage

pipenv run devsh [--build [--clean]] [ash_args ...]
  • --build Build the venv Docker image
  • --clean Clean up dangling Docker images (only works if --build precedes it)
  • ash_args Arguments to pass to /bin/ash (for example -c "echo hello"). An interactive shell is launched if no arguments are given

Invoking NsJail

A shell alias named nsjpy is included and is basically nsjail python -c <args> but NsJail is configured as it would be if snekbox invoked it (such as the time and memory limits). It provides an easy way to run Python code inside NsJail without the need to run snekbox with its webserver and send HTTP requests. Example usage:

nsjpy "print('hello world!')"

The alias can be found in ./scripts/.profile, which is automatically added when the shell is launched in the container.

You can’t perform that action at this time.