Skip to main content

drillion

PyPI Python CI OpenSSF Best Practices License

TL;DR: self-hosted Python practice with a UI that stays out of your way. No streaks, no leaderboard nonsense, no badges and no engagement bait. Made by a neurodivergent engineer. It is simple, and it runs your code in a sandbox.

Longer: drillion is a local web app with 267 short Python tasks, each tagged with the concept it drills so you can go straight at whatever you're worst at. No login, no account, no server except the one on your laptop. Tasks are folders of Markdown and Python. Your progress is a single SQLite file you can copy, back up and carry.

Light Dark
The editor
the editor completing a list method
The editor, light The editor, dark
A task
spec on the left, your code and the test output on the right
A task, light A task, dark
A failed run
the case that failed, your output beside what was expected
A failed run, light A failed run, dark
A pass
your answer against the reference, and when it comes back
A pass, light A pass, dark
The catalogue
today's picks, the tags, the whole table
The catalogue, light The catalogue, dark
Lineage
what gates a task, and what it gates in turn
Lineage, light Lineage, dark
Progress
the ladder, what is due, where each topic sits
Progress, light Progress, dark
Settings
the editor set up the way you have it everywhere else
Settings, light Settings, dark

Every solve() says what it takes, so the editor knows what your value can do. Completions, signatures and type errors come from a language server running next to the grader, on your machine, and nothing is sent anywhere.

But why?

I have tried some learning platforms. Some stuck better than others, and there were plenty of things I did not like about all of them, the gamification and the ratings above all. I simply do not care about them. I came for one thing: to keep my Python sharp and learn new things, not to chat about it with peers.

I took heavy inspiration from Exercism, HackerRank and, surprisingly, Anki, and built it from scratch.

Core ideas I'm keeping in mind during the development:

  • A clean UI that does not gate the task. Nothing stands between opening drillion and writing code.
  • Categorisation. Every task is tagged with the concept it drills, and a tag spans many tasks, so you can go straight at the thing you are worst at instead of grinding a track in order.
  • Anki-like progression. A task comes back before you forget it, with a daily cap so a backlog cannot bury you.
  • An editor that behaves like an IDE without the complexity of one. Every solve() is typed, so completions, signatures and inline type errors are real as they come from a language server running next to the grader, on your machine.
  • Hints unlock and they are not free. Three per task, escalating from a nudge to the same idea worked through on different data. After half an hour with no submission, drillion suggests taking one as you cannot brute-force something you are unaware of.
  • Grading is the real. Your code is spliced into the task's own pytest file and run.
  • YOUR progress. One SQLite file on your disk, stamped with a schema version, and a build refuses to rewrite a file a newer one wrote rather than quietly mangling it. Settings turns it into a backup you can carry, and can erase the lot if you want to start over.
  • It is free, and it stays free. No tier, no voucher, no account, no telemetry, open-source.

One consequence worth stating plainly: 267 tasks ship as executable Python, and task.py runs on import. Shipping tasks as code is what makes the sandbox necessary, so graded code is confined by the kernel and you do not have to take my word for it. What running it does to your machine, below, is the detail.

Install

You do not need Python, and you do not need to know what a virtual environment is. Pick your system below, run two commands, and drillion opens in your browser at http://127.0.0.1:8765. It runs on your machine, so nothing is uploaded and there is no account.

Linux, macOS, or Windows with WSL

Open a terminal. Install uv, which is the one tool drillion needs:

curl -LsSf https://astral.sh/uv/install.sh | sh

Close the terminal and open a new one, so it picks up the new command. Then:

uvx drillion

The first run takes a minute while it fetches Python and drillion. After that it starts in seconds.

Windows

Open PowerShell from the Start menu. Install uv:

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Close PowerShell and open it again, then:

uvx drillion

One difference worth knowing: the code you submit is sandboxed less tightly on Windows than on Linux and macOS. Windows blocks what it can write, but not what it can read. SECURITY.md says exactly which half is which.

Using it day to day

  • Stop it: press Ctrl+C in the terminal window.
  • Start it again: uvx drillion, in any terminal.
  • Update: nothing to do. uvx fetches the current version each time.
  • Your work is kept between runs, and an update never overwrites it.

Want a permanent drillion command instead of typing uvx every time? Either of these installs one:

uv tool install drillion    # uv tool upgrade drillion to update
pip install drillion        # the same, if you already have Python 3.14+ and no uv

Docker

Same on every system, if you already run Docker:

docker run -p 127.0.0.1:8765:8765 -v drillion:/data ghcr.io/vazome/drillion

Open http://127.0.0.1:8765 yourself, since the container never opens a browser. The image carries the tasks and the page; the named volume keeps your work across upgrades. compose.yaml is the same thing plus restart: unless-stopped, so drillion comes back after a reboot; save that one file anywhere and docker compose up -d.

Commands

drillion              # serve the web UI (default)
drillion selfcheck    # solve every task with its own reference, proving the set still works
drillion doctor       # say why a task folder would be skipped

Your progress

Everything drillion owns lives under one root: tasks/, which is where your code is saved, and progress.sqlite3, which holds your cards, notes and archived solutions. From a clone that root is the checkout. Installed, it is a per-user data directory that the first run seeds from the tasks inside the wheel. In Docker it is the volume at /data. An upgrade never writes over a root that already has tasks in it, so nothing you have written is at risk. See docs/configuration.md for the environment variables and the Docker bind-mount recipe.

Existing progress.json files are imported automatically on first access and kept untouched. After import, SQLite is the source of truth, and the retained JSON is only a snapshot from before the upgrade.

Settings → Back up writes everything you would miss to one file: your cards, notes, log and archive, plus the code you have written in every task. Restore it on another machine or after a reinstall and you pick up where you left off. A restore replaces what is there now, and saves what it replaced to backup-before-restore.zip in the same root first.

Settings → Danger zone is the way back to a first run: it deletes the stored progress and puts every task back to its stub. You confirm it by typing erase progress, and it writes backup-before-reset.zip in the same root before it does anything, which is the only way to undo it.

Settings → Editor sets the editor up the way you have it everywhere else: font and size, ligatures, Vim or Emacs keys, tab size, word wrap, relative line numbers, and whether the practice timer is on screen. Those live in the browser rather than in your progress, so a backup does not carry them.

What running it does to your machine

drillion runs Python on your computer: the code you write, and the code that ships inside the 267 tasks. So it is worth saying plainly what that costs you.

  • Your submissions are confined by the kernel. Landlock on Linux, an sandbox-exec profile on macOS, a restricted token at low integrity on Windows. On Linux and macOS graded code reads only the interpreter, the system libraries and the tasks, writes only to a scratch directory deleted after the run, and cannot open a network connection. Windows confines the writes but not the reads or the network. drillion doctor prints the tier you actually got, read back from a process that tried it.

  • Nothing leaves your machine. No account, no telemetry, no fonts or scripts fetched from anyone. The server binds 127.0.0.1, and refuses a request from a page it did not serve, so a website you happen to have open cannot drive your local drillion.

  • What you downloaded can be checked. Every release carries provenance naming the workflow run that built it, attached to the release itself:

    gh attestation verify drillion-0.5.1-py3-none-any.whl --repo vazome/drillion
    gh attestation verify oci://ghcr.io/vazome/drillion:0.5.1 --repo vazome/drillion
    

SECURITY.md is the whole picture, including which half of it Windows does not cover, and how to report something.

Docs

Contributing

The most useful contribution is a new task. Open an issue with the New task template first, then read CONTRIBUTING.md for the dev loop and the contract a task is graded against, and AGENTS.md for how the project decides things. Bugs and ideas go in Issues; a vulnerability goes through SECURITY.md, which also spells out what running drillion does to your machine.

License

MIT. See LICENSE. 89 of the 267 tasks adapt a problem from Exercism's Python track (also MIT), 13 adapt reference code from Fluent Python's examples and six from TheAlgorithms/Python (both MIT), and one restates a problem from MBPP (CC-BY-4.0); each names its origin in a source: field and an attribution footer, and NOTICE reproduces the notices that travel with them.

Metadata

Release files for drillion 0.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for drillion 0.8.0
File Size Uploaded
drillion-0.8.0.tar.gz 6.1 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for drillion 0.8.0
File Interpreter ABI Platform
drillion-0.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 11.9 MB

Release files / drillion-0.8.0.tar.gz

Download URL drillion-0.8.0.tar.gz
Size 6.1 MB
Tags Source
SHA-256 checksum
How to use checksums
7c3af782001efa76d8fc2c0dc7b47f35ec7ca61d266cd471ae536b2690c1926f
BLAKE2b-256 checksum
How to use checksums
dea49824cd98913bfa60b7724521a9a07cc6f73065ff1fcc7d716061bb3a2378
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / drillion-0.8.0-py3-none-any.whl

Download URL drillion-0.8.0-py3-none-any.whl
Size 5.8 MB
Tags Python 3
SHA-256 checksum
How to use checksums
e7f96b8f8fe464169d2e53595f9b2464a8275805e42cb2fa10ee02506c71653f
BLAKE2b-256 checksum
How to use checksums
9ad47a7197c4fd823d09cb3c88884a1dbdc4595a67f0fa4bb520804a6847992b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release history Release notifications | RSS feed

0.8.2

2 release files

0.8.1

2 release files

This release

0.8.0 This release

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.6

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page