Nobody has started this yet — be first.
Business impact
Ops sets LOGIN_ACCOUNT_LIMIT=5 expecting customers get 5 login attempts per window before being throttled. In reality they get 4. This kind of silent, invisible-in-the-dashboard gap between "what ops configured" and "what the system actually enforces" causes exactly the kind of confusing false-positive lockout complaints that eat on-call and support time disproportionately to how serious the underlying bug looks in a diff.
Problem
check_rate_limit() returns count < limit instead of count <= limit, so with a configured limit of N, only N-1 requests are allowed before the Nth (still within the intended budget) is rejected with 429.
Current behavior
The comparison is return count < limit, retry_after where count is Redis's post-increment counter -- one attempt too strict against the documented limit.
Expected behavior
Exactly limit requests within the window are allowed; the (limit + 1)th is rejected with 429.
Steps to reproduce
Why this matters
This is the same class of bug as ticket 01 (< vs <= on a boundary), but here the boundary is a security control, not a form validator -- worth noticing how identical-looking one-character mistakes carry very different weight depending on what they gate.
Suggested approach
Re-derive, from the function's own docstring ("Returns (allowed, retry_after_seconds)"), what count represents at the moment of the comparison (it is incremented before the check), and what the correct boundary condition against limit should be.
Acceptance criteria
Verification
pytest practice_tickets/tests/test_ticket_03.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 fix/rate-limit-off-by-oneFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin fix/rate-limit-off-by-oneSubmit 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 inhttp://localhost:5000make seedpyotpmake docker-prod-upYou do not need Docker running at all to work the tickets -- the test suite uses an in-memory SQLite database (via StaticPool, an isolated DB per test function) and fakeredis (TestingConfig.USE_FAKE_REDIS), so everything runs against a plain virtualenv:
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
pytest practice_tickets/tests/test_ticket_01.py -v # a single ticket
./practice_tickets/run_tickets.sh # all 15, clean pass/fail summary
All 15 tests fail at the start; as you fix each ticket in app/, its test (and only its test) should flip to passing. make test (pytest -q) runs the project's own main suite -- as of writing it shows 9 pre-existing failures caused by ticket bugs 02, 03, 07, 11, and 15; fixing those tickets fixes those failures too, not a separate task. Do not look at git diff / version control history to find the bugs if this repo is ever put under source control -- the point is to find them the way you would find a real bug: from a failing test and a description of broken behavior, not a diff.
Level 1
Fix a bug
Read existing behaviour, correct it.