Nobody has started this yet — be first.
Business impact
A request ID is only useful for tracing/correlation if it is actually unique per request -- "every request gets the label stub-request-id" is equivalent to not having request IDs at all for debugging purposes (searching logs for it returns everything, which is the same as searching for nothing). And silently overwriting a client-supplied ID breaks any correlation the client was already trying to do across its own systems and this gateway.
Problem
Every successful proxied response already includes an X-Request-Id header -- the wiring in app/routers/proxy.py is done. But get_or_create_request_id() is a stub: it always returns the literal string "stub-request-id", regardless of the request.
Current behavior
Calling get_or_create_request_id(request) returns "stub-request-id" for every request, whether or not the client sent its own X-Request-Id header, and every response ends up with that exact same value.
Expected behavior
If the client's request already has an X-Request-Id header, that exact value is echoed back in the response's X-Request-Id header. If it does not, a fresh, unique value is generated for that request (a UUID4 is a reasonable choice) and returned. Two different requests that did not supply their own ID get two different generated IDs.
Steps to reproduce
Why this matters
get_or_create_request_id(request) already receives the Request -- it has everything it needs (the incoming headers, to check for an existing X-Request-Id; the standard library, to generate one when there is not) but its body never looks at any of that, returning a constant instead.
Suggested approach
Read the incoming X-Request-Id header off request.headers first; fall back to generating a fresh id (e.g. uuid.uuid4()) only when it is missing. Forwarding this ID upstream too, and correlating it into the latency/breaker metrics, would be natural follow-ups but are out of scope here -- this ticket is scoped to what the response header reports.
Acceptance criteria
Verification
pytest practice_tickets/tests/test_ticket_12_request_id_propagation.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/request-id-propagationFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin feat/request-id-propagationSubmit 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: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.