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 189 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
The catalogue
today's picks, the tags, the whole table
The catalogue, light The catalogue, dark
Progress
the ladder, what is due, where each topic sits
Progress, light Progress, 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: 189 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.13+ 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 turns Vim keys on if you use them everywhere else. That one lives in the browser rather than in your progress, so a backup does not carry it.

What running it does to your machine

drillion runs Python on your computer: the code you write, and the code that ships inside the 189 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 189 tasks adapt a problem from Exercism's Python track (also MIT) and one 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.7.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.7.0
File Size Uploaded
drillion-0.7.0.tar.gz 5.5 MB Details

Built distribution (wheel)

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

Total release size: 10.9 MB

Release files / drillion-0.7.0.tar.gz

Download URL drillion-0.7.0.tar.gz
Size 5.5 MB
Tags Source
SHA-256 checksum
How to use checksums
25341a411b03745db389df07e9dbb7f42b612ababa620593e3fefa558be68114
BLAKE2b-256 checksum
How to use checksums
4c187a145d93569feb3842535be291c55f65e9e411b1e2d9fe5f6fd08d39635e
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 8, 2026.

Transparency log

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

Download URL drillion-0.7.0-py3-none-any.whl
Size 5.4 MB
Tags Python 3
SHA-256 checksum
How to use checksums
0d8f0cb33e3b7647324aa6295d600760bf3da84026757074cd540067b5f2112a
BLAKE2b-256 checksum
How to use checksums
bfff9e41f342d9a6e86027320ce6ec8551b14860b9db2189b89d81d68b2f9484
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 8, 2026.

Transparency log

Release history Release notifications | RSS feed

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

This release

0.7.0 This release

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