Exercise py-07 — an async LLM client that respects both limits

Every RAG or agent service has exactly this component: a client that calls a model API under the two limits the event loop page kept apart — requests per second (a token bucket) and connections in flight (a semaphore) — retries a transient failure once, and gives up cleanly when its caller cancels. The GIL page is why the waits overlap at all. You build it against a mock transport; flagship F1 (the RAG service) swaps in a real one. This one runs on your Mac, not in the browser — it needs a real asyncio loop with tasks, locks and cancellation, which Pyodide's single-threaded loop does not exercise faithfully.

~90 minruns locally · uv + pytest 7 checkspy-07-async-token-bucket

What you're building

clock and sleep are plain parameters (defaults time.monotonic / asyncio.sleep) so the tests can drive everything on a fake clock (tests/conftest.py): the whole suite runs in milliseconds, and a real sleep anywhere is a bug the last test catches. Only the injected sleep advances that clock: a bucket that waits on asyncio.sleep directly, or busy-loops on asyncio.sleep(0), fails the three timing tests (the busy loop after 5 s of real time, with a message saying so, instead of hanging).

The tests are ordinary pytest and ship in the public folder with the starter — read them first; the names below are the check list. Solutions are not published.

Get the repo (once)

Needs git. uv installs the right Python itself, so nothing else is required.

# once, anywhere on your machine
git clone https://github.com/theDocWho/ai-ml-roadmap.git
cd ai-ml-roadmap

No git? Download the ZIP, unzip it, and cd into the unzipped folder instead.

Run it

From the repo root:

# one-time: uv (https://docs.astral.sh/uv/) manages the venv and pins Python ≥ 3.12
cd exercises/py-07-async-token-bucket && uv sync && uv run pytest -q

# the same bar the reference solution clears
uv run ruff check . && uv run mypy src

Done when uv run pytest -q prints 7 passed. Rerun after every edit; pytest's -q output is the only readout this exercise has. No pytest-asyncio: every test is a plain def that calls asyncio.run.

The checks

Files

This is self-attestation — the site cannot see your terminal, so the box and the button are you telling The Path the suite went green on your machine.

If you get stuck