python 25 lines · 7 steps

Attaching per-request context in Django

A Django middleware that stamps each request with an ID, timing, tenant, and feature flags, then echoes them back on the response.

Explained by highlit
1import time
2import uuid
3 
4from django.utils.deprecation import MiddlewareMixin
5 
6 
7class RequestContextMiddleware(MiddlewareMixin):
8 def process_request(self, request):
9 request.request_id = request.headers.get("X-Request-ID") or uuid.uuid4().hex
10 request.started_at = time.monotonic()
11 
12 api_key = request.headers.get("Authorization", "").removeprefix("Bearer ").strip()
13 request.api_client = ApiClient.objects.filter(
14 key=api_key, is_active=True
15 ).select_related("organization").first()
16 
17 request.tenant = request.api_client.organization if request.api_client else None
18 request.feature_flags = FeatureFlag.flags_for(request.tenant)
19 
20 def process_response(self, request, response):
21 response["X-Request-ID"] = getattr(request, "request_id", "")
22 if hasattr(request, "started_at"):
23 elapsed_ms = (time.monotonic() - request.started_at) * 1000
24 response["X-Response-Time-ms"] = f"{elapsed_ms:.1f}"
25 return response
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Middleware is the natural place to resolve cross-cutting context once so every view can rely on it.
  2. 2Reusing an incoming request ID or minting a new one gives you end-to-end request tracing for free.
  3. 3process_request and process_response bracket a request, letting you measure and annotate the full round trip.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Attaching per-request context in Django — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code