Skip to content

feat(hosting): expose correlation_id on request.state + structlog recipe (#164) - #167

Merged
antosubash merged 2 commits into
mainfrom
worktree-issue-164-request-id-middleware
May 21, 2026
Merged

antosubash merged 2 commits into
mainfrom
worktree-issue-164-request-id-middleware

Conversation

@antosubash

Copy link
Copy Markdown
Owner

Closes #164.

Summary

  • CorrelationIdMiddleware now also writes the ID to request.state.correlation_id (the docs already claimed it did — making it true). Written by direct scope["state"] assignment so the hot path doesn't allocate a Request per call.
  • docs/framework/middleware.md corrected: the header is X-Correlation-ID, not X-Request-ID, and the existing CorrelationIdMiddleware satisfies the intent of simple_module_hosting: ship request_id middleware that propagates into log records #164 (smpy_gis T4 will adopt correlation_id instead of inventing a parallel request_id).
  • New 3-line(-ish) structlog wire-up recipe in the same doc, with a callout that structlog.contextvars.merge_contextvars is not a drop-in substitute (it only sees structlog_-prefixed contextvars).
  • New test test_state_contextvar_and_header_agree spins up a minimal Starlette app with the middleware and asserts 3-way parity between request.state.correlation_id, the correlation_id ContextVar, and the X-Correlation-ID response header.

Verification

  • Live-server smoke (/vf Stage 2a, see .verify/smoke.txt & .verify/structlog_recipe.txt):
    • GET /health (no header) → 32-char UUID4 hex generated and echoed
    • GET /health with X-Correlation-ID: vf-smoke-trace-001 → echoed verbatim
    • Two consecutive GET /healths → distinct IDs (per-request)
    • GET /dashboard (Inertia HTML path) → 302 with X-Correlation-ID set, proving the middleware fires across the whole pipeline
    • Docs structlog recipe end-to-end: log line contains "correlation_id": "vf-recipe-7"
  • Python: ruff format-check, ruff check, ty, file-size cap, hardcoded-string check — all green.
  • 1187 Python tests pass (incl. the new test), 1 skipped (e2e marker), 2 deselected.
  • JS lint, JS typecheck, 16 JS tests — all green.
  • Skipped: full Playwright e2e suite — the single existing e2e test (test_toggle_host_multi_tenant_persists) is unrelated to hosting-middleware behavior and would only verify "did I break the request pipeline", which the unit suite + live smoke already covered.

Test plan

  • Reviewer runs curl -i http://localhost:8000/health after make dev and confirms an X-Correlation-ID header is present in the response.
  • Reviewer drops the structlog recipe from docs/framework/middleware.md into a scratch script and confirms log events carry correlation_id.
  • CI is green.

…ipe (#164)

CorrelationIdMiddleware already wrote a ContextVar and X-Correlation-ID header;
docs claimed it also exposed request.state.correlation_id but the code never
did. Write straight into scope["state"] so Request(scope).state.correlation_id
is available to handlers without a Request allocation in the middleware.

Fix the middleware docs (header was wrong — said X-Request-ID) and add a 3-line
structlog wire-up recipe for smpy_gis T4 observability. Verified end-to-end that
the recipe makes log lines carry correlation_id; documented why structlog's
merge_contextvars cannot be used as a drop-in substitute (it only sees
structlog_-prefixed contextvars, not stdlib ones).
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented May 21, 2026 •

Copy link
Copy Markdown

Deploying simple-module-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: 5decbec
Status: ✅  Deploy successful!
Preview URL: https://8ee2fcdb.simple-module-python.pages.dev
Branch Preview URL: https://worktree-issue-164-request-i.simple-module-python.pages.dev

View logs

@antosubash
antosubash merged commit 5c6cf4c into main May 21, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

simple_module_hosting: ship request_id middleware that propagates into log records

1 participant