Nobody has started this yet — be first.
Business impact
A planned maintenance window (upstream migration, a scheduled Redis failover, a config change that needs a moment of "do not send anything through yet") currently has no clean way to pause traffic at the gateway without actually tearing down routes one by one or stopping the process. A single, fast, reversible kill switch is the kind of thing that is much better to have before the first time it is needed under pressure than to improvise in the moment.
Problem
POST /admin/maintenance (body {"enabled": true/false}) and GET /admin/maintenance both work today -- they really do flip app.state.maintenance_mode and reflect it back. But nothing in the actual proxy request pipeline (app/routers/proxy.py::proxy_endpoint) ever reads that flag.
Current behavior
Turning maintenance mode "on" via the admin endpoint changes app.state.maintenance_mode to True, but a proxied request sent immediately afterward still goes through routing, auth, rate limiting, and the upstream call exactly as if maintenance mode were off.
Expected behavior
While app.state.maintenance_mode is True, every proxied request (everything the catch-all proxy_endpoint handles) is rejected with 503 immediately -- before route matching, auth, rate limiting, or any upstream call. /healthz, , , and every endpoint are unaffected.
Steps to reproduce
Why this matters
proxy_endpoint already has a Request parameter it can read request.app.state.maintenance_mode from directly -- the flag exists and is correctly toggled, the pipeline just never consults it. The check needs to run before any of the other pipeline stages do any work at all, and it must live only inside the catch-all proxy router, never in app/main.py's router registration, so the other admin/health endpoints stay reachable regardless.
Suggested approach
Think about exactly where in the existing pipeline (match route -> check method -> auth -> rate limit -> breaker -> forward) this check belongs, given that it should reject a request before any of the other stages do any work at all.
Acceptance criteria
Verification
pytest practice_tickets/tests/test_ticket_08_maintenance_mode_not_enforced.py -v
Hints (0/2)
Try it without hints first — the reading is the exercise.
Working on this ticket
Work on a branch named for the ticket — that's what you'll submit.
Branch off your fork
Sign in to create it automatically, or do it yourself:
$git checkout -b feat/maintenance-mode-not-enforcedFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin feat/maintenance-mode-not-enforcedSubmit it below
Paste your fork URL and the branch name, with a short write-up of the root cause.
Questions
Ask about anything unclear in the ticket — the maintainer and anyone who has solved it can answer. Please don't post full solutions.
Sign in to ask a question or reply.
Sign in/readyz/metrics/admin/*http://localhost:8080fast_echo/echo/.../large/{size_mb}slow_upstream/delay/{s}/flaky/always-downroutes.yamlcurl localhost:8080/healthzcurl localhost:8080/readyz/admin/*Authorization: Bearer <GATEWAY_ADMIN_TOKEN>You do not need Docker running at all to work the tickets — the test suite fakes Redis with fakeredis (plus lupa for real Lua-script support), so everything runs against a plain virtualenv:
python3 -m venv .venv && .venv/bin/pip install -r requirements-dev.txt
.venv/bin/pytest practice_tickets/tests/test_ticket_09_breaker_threshold_off_by_one.py -v # a single ticket
./practice_tickets/run_tickets.sh # all 15, clean pass/fail summary
./practice_tickets/run_tickets.sh 06 09 15 # just a few, by number
All 15 tests fail at the start; as you fix each ticket in app/, its test (and only its test) should flip to passing. .venv/bin/pytest tests/ runs the project's own main suite — as of writing it shows 8 pre-existing failures caused by ticket bugs 02, 04, 06, and 09; fixing those tickets fixes those failures too, not a separate task.
Level 2
Implement a feature
Extend the system within its own patterns.