How to Propagate X-Request-ID in Python
Generate a unique request ID when one is missing and pass it through API calls for distributed tracing.
Python code
27 linesimport uuid
def generate_request_id() -> str:
"""Generate a unique request ID similar to X-Request-ID header."""
return str(uuid.uuid4())
def propagate_request_id(request_id: str | None) -> str:
"""Return the request ID for propagation, generating one if missing."""
if request_id:
return request_id
return generate_request_id()
if __name__ == "__main__":
# Simulate an incoming request without an X-Request-ID
incoming = None
propagated = propagate_request_id(incoming)
print(f"Incoming X-Request-ID: {incoming}")
print(f"Propagated X-Request-ID: {propagated}")
# Simulate an incoming request that already has an X-Request-ID
incoming_with_id = "7f9c1b2a-3d4e-4f5a-9b8c-1d2e3f4a5b6c"
propagated_with_id = propagate_request_id(incoming_with_id)
print(f"\nIncoming X-Request-ID: {incoming_with_id}")
print(f"Propagated X-Request-ID: {propagated_with_id}")
Output
Incoming X-Request-ID: None
Propagated X-Request-ID: 7a1b2c3d-4e5f-4a6b-8c9d-0e1f2a3b4c5d
Incoming X-Request-ID: 7f9c1b2a-3d4e-4f5a-9b8c-1d2e3f4a5b6c
Propagated X-Request-ID: 7f9c1b2a-3d4e-4f5a-9b8c-1d2e3f4a5b6c
How it works
generate_request_id() uses uuid.uuid4() to produce a collision-resistant, RFC 4122-compliant ID. The propagate_request_id() function reuses any existing header value instead of generating a new one, preserving the trace across service hops. The | None type hint and string check handle both empty strings and missing headers gracefully. This pattern is the standard way to maintain a request trace ID across distributed systems.
Common mistakes
- Generating a new ID even when the incoming request already has one
- Returning an empty string instead of generating a fresh ID when the header is blank
- Using uuid1() which leaks MAC address and timestamp information
Variations
- Use `secrets.token_hex(16)` for a shorter, URL-safe ID
- Wrap the helper in a middleware class to automatically attach the header to every outbound request
Real-world use cases
- Forwarding the X-Request-ID header to downstream microservices for end-to-end log correlation.
- Attaching a correlation ID to every log line in a serverless function for easier debugging.
- Injecting the request ID into outbound HTTP calls so third-party APIs can trace failures back to you.
Sponsored
More from API design & gRPC
- Build a Bulk Array POST Mock Server in Python medium
- Build a Mock REST API with PUT and GET in Python medium
- Convert Protobuf to JSON and Dict in Python easy
- Create a Data Helper in Python for gRPC-style APIs easy
- Format data in Python using dataclasses like gRPC messages easy
- Generate an OpenAPI Spec from Mock Routes in Python easy
Keep learning
Related tutorials and quizzes for this topic.