Coverage for src/lexigram/web/middleware/tracing.py: 36%

25 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-25 04:37 +0800

1"""W3C Trace Context (traceparent) utilities for Lexigram Web. 

2 

3This module provides utilities for parsing and generating W3C traceparent headers, 

4enabling distributed tracing across web services. 

5""" 

6 

7from __future__ import annotations 

8 

9import re 

10from typing import TYPE_CHECKING 

11 

12from lexigram.contracts.core.trace_context import ( 

13 span_id_var, 

14 trace_flags_var, 

15 trace_id_var, 

16) 

17 

18if TYPE_CHECKING: 

19 from lexigram.primitives.context import RequestContext 

20 

21# W3C Traceparent Regex: version-traceid-spanid-flags 

22# trace-id (32 hex), span-id (16 hex), flags (2 hex) 

23TRACEPARENT_REGEX = re.compile( 

24 r"^[0-9a-f]{2}-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$", 

25) 

26 

27 

28def extract_traceparent(header: str) -> dict[str, str] | None: 

29 """Parse W3C traceparent header. 

30 

31 Returns a dict with trace_id, parent_id, and trace_flags if valid. 

32 """ 

33 match = TRACEPARENT_REGEX.match(header.strip()) 

34 if match: 

35 return { 

36 "trace_id": match.group(1), 

37 "parent_id": match.group(2), 

38 "trace_flags": match.group(3), 

39 } 

40 return None 

41 

42 

43def inject_traceparent() -> str | None: 

44 """Generate W3C traceparent header from current core context.""" 

45 trace_id = trace_id_var.get(None) 

46 span_id = span_id_var.get(None) 

47 flags = trace_flags_var.get(None) or "01" 

48 

49 if trace_id and span_id: 

50 return f"00-{trace_id}-{span_id}-{flags}" 

51 return None 

52 

53 

54def load_trace_to_context(ctx: RequestContext, header: str | None) -> None: 

55 """Load trace context from W3C traceparent header into a RequestContext in-memory.""" 

56 if not header: 

57 return 

58 data = extract_traceparent(header) 

59 if data: 

60 ctx.trace_id = data["trace_id"] 

61 ctx.trace_flags = data["trace_flags"] 

62 

63 

64__all__ = [ 

65 "TRACEPARENT_REGEX", 

66 "extract_traceparent", 

67 "inject_traceparent", 

68 "load_trace_to_context", 

69]