diff --git a/pyproject.toml b/pyproject.toml index 6c6ee465..fe683c28 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ dependencies = [ "python-dateutil >=2.8.2", "typing-inspection >=0.4.0", "opentelemetry-api (>=1.33.1,<2.0.0)", - "opentelemetry-semantic-conventions (>=0.60b1,<0.61)", + "opentelemetry-semantic-conventions (>=0.60b1)", "jsonpath-python >=1.0.6", # required for speakeasy generated path with pagination ] @@ -68,7 +68,7 @@ dev = [ "pyyaml>=6.0.2,<7", "mypy==1.15.0", "msgpack>=1.1.0,<2.0.0", - "opentelemetry-instrumentation-httpx (>=0.60b1,<0.61)", + "opentelemetry-instrumentation-httpx (>=0.60b1)", "opentelemetry-sdk (>=1.33.1,<2.0.0)", "opentelemetry-exporter-otlp-proto-http (>=1.33.1,<2.0.0)", "pylint==3.2.3", diff --git a/src/mistralai/client/_hooks/traceparent.py b/src/mistralai/client/_hooks/traceparent.py index a8ddedf4..f500789e 100644 --- a/src/mistralai/client/_hooks/traceparent.py +++ b/src/mistralai/client/_hooks/traceparent.py @@ -12,6 +12,19 @@ "execute_workflow_registration_v1_workflows_registrations__workflow_registration_id__execute_post", } +_SAMPLED_FLAG = 0x01 + + +# https://www.w3.org/TR/trace-context/#traceparent-header +def _is_sampled(traceparent: str) -> bool: + parts = traceparent.split("-") + if len(parts) != 4: + return False + try: + return bool(int(parts[3], 16) & _SAMPLED_FLAG) + except ValueError: + return False + class TraceparentInjectionHook(BeforeRequestHook): """Inject a sampled traceparent on /execute requests so worker traces are always recorded.""" @@ -29,7 +42,7 @@ def before_request( carrier: Dict[str, str] = {} inject(carrier) traceparent = carrier.get("traceparent", "") - if not traceparent.endswith("-01"): + if not _is_sampled(traceparent): trace_id = random.getrandbits(128) span_id = random.getrandbits(64) traceparent = f"00-{trace_id:032x}-{span_id:016x}-01" diff --git a/src/mistralai/extra/tests/test_traceparent_hook.py b/src/mistralai/extra/tests/test_traceparent_hook.py index 8202f3d6..a5f45a72 100644 --- a/src/mistralai/extra/tests/test_traceparent_hook.py +++ b/src/mistralai/extra/tests/test_traceparent_hook.py @@ -86,7 +86,7 @@ def test_propagates_sampled_active_span(self): assert isinstance(result, httpx.Request) injected = result.headers["traceparent"] - self.assertTrue(injected.endswith("-01")) + self.assertTrue(int(injected.split("-")[3], 16) & 0x01) trace_id_hex = f"{span.get_span_context().trace_id:032x}" self.assertIn(trace_id_hex, injected)