From 70d7ab31e34634354d5b535566493e1637cc9169 Mon Sep 17 00:00:00 2001 From: Lucas Soares Date: Tue, 7 Jul 2026 12:34:21 -0300 Subject: [PATCH 1/4] conversation id override for baggage span processor --- pyproject.toml | 1 - .../core/telemetry/auto_instrument.py | 7 +- .../span_processors/baggage_span_processor.py | 85 ++++++++ .../propagated_attributes_processor.py | 0 .../core/telemetry/user-guide.md | 3 +- .../telemetry/test_baggage_span_processor.py | 182 ++++++++++++++++++ .../test_propagated_attributes_processor.py | 2 +- 7 files changed, 274 insertions(+), 6 deletions(-) create mode 100644 src/sap_cloud_sdk/core/telemetry/span_processors/baggage_span_processor.py rename src/sap_cloud_sdk/core/telemetry/{ => span_processors}/propagated_attributes_processor.py (100%) create mode 100644 tests/core/unit/telemetry/test_baggage_span_processor.py diff --git a/pyproject.toml b/pyproject.toml index 3bbf3426..29a102df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,6 @@ dependencies = [ "hatchling~=1.27.0", "opentelemetry-exporter-otlp-proto-grpc~=1.42.1", "opentelemetry-exporter-otlp-proto-http~=1.42.1", - "opentelemetry-processor-baggage~=0.61b0", "traceloop-sdk~=0.61.0", "opentelemetry-instrumentation-langchain>=0.61.0", "httpx>=0.27.0", diff --git a/src/sap_cloud_sdk/core/telemetry/auto_instrument.py b/src/sap_cloud_sdk/core/telemetry/auto_instrument.py index bab3458f..fdd3c34f 100644 --- a/src/sap_cloud_sdk/core/telemetry/auto_instrument.py +++ b/src/sap_cloud_sdk/core/telemetry/auto_instrument.py @@ -11,7 +11,10 @@ from opentelemetry.exporter.otlp.proto.http.trace_exporter import ( OTLPSpanExporter as HTTPSpanExporter, ) -from opentelemetry.processor.baggage import ALLOW_ALL_BAGGAGE_KEYS, BaggageSpanProcessor +from sap_cloud_sdk.core.telemetry.span_processors.baggage_span_processor import ( + ALLOW_ALL_BAGGAGE_KEYS, + BaggageSpanProcessor, +) from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SpanExporter @@ -30,7 +33,7 @@ GenAIAttributeTransformer, ) from sap_cloud_sdk.core.telemetry.metrics_decorator import record_metrics -from sap_cloud_sdk.core.telemetry.propagated_attributes_processor import ( +from sap_cloud_sdk.core.telemetry.span_processors.propagated_attributes_processor import ( PropagatedAttributesSpanProcessor, ) diff --git a/src/sap_cloud_sdk/core/telemetry/span_processors/baggage_span_processor.py b/src/sap_cloud_sdk/core/telemetry/span_processors/baggage_span_processor.py new file mode 100644 index 00000000..3d41ce92 --- /dev/null +++ b/src/sap_cloud_sdk/core/telemetry/span_processors/baggage_span_processor.py @@ -0,0 +1,85 @@ +import logging +from collections.abc import MutableMapping +from typing import Any, Callable, Dict, Optional, cast + +from opentelemetry.baggage import get_all as get_all_baggage +from opentelemetry.context import Context +from opentelemetry.sdk.trace import ReadableSpan, SpanProcessor +from opentelemetry.trace import Span + +logger = logging.getLogger(__name__) + +BaggageKeyPredicateT = Callable[[str], bool] +ALLOW_ALL_BAGGAGE_KEYS: BaggageKeyPredicateT = lambda _: True # noqa: E731 + +# Baggage keys where the caller-supplied value must win over any value set by +# framework callbacks after on_start +_DEFAULT_OVERRIDE_KEYS: tuple[str, ...] = ("gen_ai.conversation.id",) + + +class BaggageSpanProcessor(SpanProcessor): + """Copies W3C baggage entries onto every span and enforces override keys. + + On ``on_start``: iterates all baggage entries, applies those matching + ``baggage_key_predicate`` to the span via ``set_attribute``, and snapshots + any ``override_keys`` values for re-application at end time. + + On ``on_end``: re-writes the snapshot override values directly into + ``span._attributes``, ensuring they survive any framework ``set_attribute`` + calls made during the span's lifetime. + + Args: + baggage_key_predicate: Called for each baggage key; attribute is copied + only when this returns ``True``. Use ``ALLOW_ALL_BAGGAGE_KEYS`` to + copy everything. + override_keys: Baggage keys whose value must always win over + framework-injected span attributes. Only keys actually present in + baggage at span start are tracked. + """ + + def __init__( + self, + baggage_key_predicate: BaggageKeyPredicateT, + override_keys: tuple[str, ...] = _DEFAULT_OVERRIDE_KEYS, + ) -> None: + self._baggage_key_predicate = baggage_key_predicate + self._override_keys = frozenset(override_keys) + self._pending: Dict[int, Dict[str, Any]] = {} + + def on_start(self, span: Span, parent_context: Optional[Context] = None) -> None: + if not span.is_recording(): + return + all_baggage = get_all_baggage(parent_context) + for key, value in all_baggage.items(): + if self._baggage_key_predicate(key): + span.set_attribute(key, value) + + overrides = {k: all_baggage[k] for k in self._override_keys if k in all_baggage} + if overrides: + span_id = getattr(getattr(span, "context", None), "span_id", None) + if span_id is not None: + self._pending[span_id] = overrides + + def on_end(self, span: ReadableSpan) -> None: + span_id = getattr(getattr(span, "context", None), "span_id", None) + if span_id is None: + return + overrides = self._pending.pop(span_id, None) + if not overrides: + return + if not hasattr(span, "_attributes") or span._attributes is None: + return + try: + cast(MutableMapping[str, Any], span._attributes).update(overrides) + except Exception as exc: + logger.debug( + "BaggageSpanProcessor: error enforcing overrides on span %r: %s", + getattr(span, "name", ""), + exc, + ) + + def shutdown(self) -> None: + pass + + def force_flush(self, timeout_millis: int = 30000) -> bool: + return True diff --git a/src/sap_cloud_sdk/core/telemetry/propagated_attributes_processor.py b/src/sap_cloud_sdk/core/telemetry/span_processors/propagated_attributes_processor.py similarity index 100% rename from src/sap_cloud_sdk/core/telemetry/propagated_attributes_processor.py rename to src/sap_cloud_sdk/core/telemetry/span_processors/propagated_attributes_processor.py diff --git a/src/sap_cloud_sdk/core/telemetry/user-guide.md b/src/sap_cloud_sdk/core/telemetry/user-guide.md index 19430a3e..019bc1ac 100644 --- a/src/sap_cloud_sdk/core/telemetry/user-guide.md +++ b/src/sap_cloud_sdk/core/telemetry/user-guide.md @@ -127,8 +127,7 @@ if ext_ctx: The extension baggage span processor (registered automatically by `auto_instrument()`) stamps `sap.extension.*` attributes on all spans created inside an `extension_context()` block, including spans from third-party instrumentation. -It uses the official `BaggageSpanProcessor` from `opentelemetry-processor-baggage` -under the hood, filtering to only propagate `sap.extension.*` baggage keys. +It uses a built-in `BaggageSpanProcessor` under the hood to stamp baggage keys. ### Available operations diff --git a/tests/core/unit/telemetry/test_baggage_span_processor.py b/tests/core/unit/telemetry/test_baggage_span_processor.py new file mode 100644 index 00000000..f48f7647 --- /dev/null +++ b/tests/core/unit/telemetry/test_baggage_span_processor.py @@ -0,0 +1,182 @@ +"""Tests for BaggageSpanProcessor.""" + +from typing import Any, Dict +from unittest.mock import MagicMock + +from opentelemetry import baggage, context + +from sap_cloud_sdk.core.telemetry.span_processors.baggage_span_processor import ( + ALLOW_ALL_BAGGAGE_KEYS, + BaggageSpanProcessor, +) + + +def _make_context_with_baggage(entries: Dict[str, Any]): + ctx = context.get_current() + for k, v in entries.items(): + ctx = baggage.set_baggage(k, v, context=ctx) + return ctx + + +def _make_recording_span(span_id: int = 1): + span = MagicMock() + span.is_recording.return_value = True + span.context.span_id = span_id + return span + + +def _make_ended_span(span_id: int = 1, attributes: Dict[str, Any] | None = None): + span = MagicMock() + span.context.span_id = span_id + span._attributes = dict(attributes or {}) + return span + + +class TestBaggageSpanProcessorOnStart: + def setup_method(self): + self.processor = BaggageSpanProcessor(ALLOW_ALL_BAGGAGE_KEYS) + + def test_copies_all_baggage_to_span(self): + ctx = _make_context_with_baggage({"user.id": "u1", "session.id": "s1"}) + span = _make_recording_span() + + self.processor.on_start(span, ctx) + + span.set_attribute.assert_any_call("user.id", "u1") + span.set_attribute.assert_any_call("session.id", "s1") + + def test_predicate_filters_keys(self): + ctx = _make_context_with_baggage({"keep.this": "yes", "drop.this": "no"}) + span = _make_recording_span() + processor = BaggageSpanProcessor(lambda k: k.startswith("keep")) + + processor.on_start(span, ctx) + + span.set_attribute.assert_called_once_with("keep.this", "yes") + + def test_no_op_when_baggage_empty(self): + span = _make_recording_span() + self.processor.on_start(span, context.get_current()) + span.set_attribute.assert_not_called() + + def test_no_op_for_non_recording_span(self): + ctx = _make_context_with_baggage({"gen_ai.conversation.id": "abc"}) + span = MagicMock() + span.is_recording.return_value = False + + self.processor.on_start(span, ctx) + + span.set_attribute.assert_not_called() + assert not self.processor._pending + + def test_snapshots_override_key_when_present_in_baggage(self): + ctx = _make_context_with_baggage({"gen_ai.conversation.id": "caller-uuid"}) + span = _make_recording_span(span_id=42) + + self.processor.on_start(span, ctx) + + assert self.processor._pending[42] == {"gen_ai.conversation.id": "caller-uuid"} + + def test_does_not_snapshot_when_override_key_absent(self): + ctx = _make_context_with_baggage({"other.key": "value"}) + span = _make_recording_span(span_id=42) + + self.processor.on_start(span, ctx) + + assert 42 not in self.processor._pending + + +class TestBaggageSpanProcessorOnEnd: + def setup_method(self): + self.processor = BaggageSpanProcessor(ALLOW_ALL_BAGGAGE_KEYS) + + def test_override_wins_after_framework_overwrites(self): + ctx = _make_context_with_baggage({"gen_ai.conversation.id": "caller-uuid"}) + span = _make_recording_span(span_id=7) + self.processor.on_start(span, ctx) + + # simulate framework callback overwriting the value mid-span + ended = _make_ended_span( + span_id=7, attributes={"gen_ai.conversation.id": "langgraph-thread-id"} + ) + self.processor.on_end(ended) + + assert ended._attributes["gen_ai.conversation.id"] == "caller-uuid" + + def test_pending_entry_cleaned_up_after_on_end(self): + ctx = _make_context_with_baggage({"gen_ai.conversation.id": "caller-uuid"}) + span = _make_recording_span(span_id=7) + self.processor.on_start(span, ctx) + + ended = _make_ended_span(span_id=7) + self.processor.on_end(ended) + + assert 7 not in self.processor._pending + + def test_on_end_no_op_when_key_not_in_baggage(self): + ctx = _make_context_with_baggage({"other.key": "value"}) + span = _make_recording_span(span_id=5) + self.processor.on_start(span, ctx) + + ended = _make_ended_span( + span_id=5, attributes={"gen_ai.conversation.id": "framework-set"} + ) + self.processor.on_end(ended) + + # no override was snapshotted so framework value is untouched + assert ended._attributes["gen_ai.conversation.id"] == "framework-set" + + def test_on_end_no_op_for_unknown_span_id(self): + ended = _make_ended_span( + span_id=99, attributes={"gen_ai.conversation.id": "framework-set"} + ) + self.processor.on_end(ended) # no KeyError + assert ended._attributes["gen_ai.conversation.id"] == "framework-set" + + def test_on_end_no_op_when_attributes_missing(self): + ctx = _make_context_with_baggage({"gen_ai.conversation.id": "caller-uuid"}) + span = _make_recording_span(span_id=3) + self.processor.on_start(span, ctx) + + ended = MagicMock() + ended.context.span_id = 3 + del ended._attributes # simulate missing _attributes + + self.processor.on_end(ended) # must not raise + + def test_on_end_swallows_mutation_error(self): + ctx = _make_context_with_baggage({"gen_ai.conversation.id": "caller-uuid"}) + span = _make_recording_span(span_id=8) + self.processor.on_start(span, ctx) + + ended = MagicMock() + ended.context.span_id = 8 + ended._attributes = MagicMock() + ended._attributes.update.side_effect = RuntimeError("immutable") + + self.processor.on_end(ended) # must not raise + + +class TestBaggageSpanProcessorCustomOverrideKeys: + def test_custom_override_key_is_enforced(self): + processor = BaggageSpanProcessor( + ALLOW_ALL_BAGGAGE_KEYS, override_keys=("my.custom.key",) + ) + ctx = _make_context_with_baggage({"my.custom.key": "baggage-val"}) + span = _make_recording_span(span_id=1) + processor.on_start(span, ctx) + + ended = _make_ended_span( + span_id=1, attributes={"my.custom.key": "framework-val"} + ) + processor.on_end(ended) + + assert ended._attributes["my.custom.key"] == "baggage-val" + + def test_empty_override_keys_skips_snapshot(self): + processor = BaggageSpanProcessor(ALLOW_ALL_BAGGAGE_KEYS, override_keys=()) + ctx = _make_context_with_baggage({"gen_ai.conversation.id": "caller-uuid"}) + span = _make_recording_span(span_id=1) + processor.on_start(span, ctx) + + assert not processor._pending diff --git a/tests/core/unit/telemetry/test_propagated_attributes_processor.py b/tests/core/unit/telemetry/test_propagated_attributes_processor.py index 9a7bb752..a4ae08f7 100644 --- a/tests/core/unit/telemetry/test_propagated_attributes_processor.py +++ b/tests/core/unit/telemetry/test_propagated_attributes_processor.py @@ -5,7 +5,7 @@ import pytest -from sap_cloud_sdk.core.telemetry.propagated_attributes_processor import ( +from sap_cloud_sdk.core.telemetry.span_processors.propagated_attributes_processor import ( PropagatedAttributesSpanProcessor, ) from sap_cloud_sdk.core.telemetry.telemetry import _propagated_attrs_var From fe3be45eea8438b950a6882925bc8d20ff6d0bbc Mon Sep 17 00:00:00 2001 From: Lucas Soares Date: Tue, 7 Jul 2026 13:04:51 -0300 Subject: [PATCH 2/4] Version bump --- pyproject.toml | 2 +- uv.lock | 32 +------------------------------- 2 files changed, 2 insertions(+), 32 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 29a102df..8cd30f63 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "sap-cloud-sdk" -version = "0.33.0" +version = "0.33.1" description = "SAP Cloud SDK for Python" readme = "README.md" license = "Apache-2.0" diff --git a/uv.lock b/uv.lock index b6dd1330..746e42d8 100644 --- a/uv.lock +++ b/uv.lock @@ -925,9 +925,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/42/3c/ff890b466eaba2b0f5e6bdfff025f8c75f41b8ffdc3dbc3d24ad261e764a/greenlet-3.5.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:73f78f9b9f0a5c06e5c946ba1e8e36f5114923b6be109ee618c54f079c3ea14f", size = 284764, upload-time = "2026-05-20T13:09:10.204Z" }, { url = "https://files.pythonhosted.org/packages/81/0e/5e5457be3d256918f6a4756f073548a3f0190836e2cc94aa6d0d617a940b/greenlet-3.5.1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a0cbed8bb44e23c5b199f888f4e4ce096b45ad9f25ff74a7ad0213875e936bb2", size = 603479, upload-time = "2026-05-20T14:00:04.757Z" }, { url = "https://files.pythonhosted.org/packages/6d/e1/f89a21d58d308298e6f275f13a1b472ed96c680b601a371b08be6a725989/greenlet-3.5.1-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a203a8bd0acb0701653d3bbb26e404854a68674139ed5cbb778830f42b09bb33", size = 615495, upload-time = "2026-05-20T14:05:40.87Z" }, - { url = "https://files.pythonhosted.org/packages/2c/f2/8fd452fd81adb9ec79c8275c1375702ab0fd6bee4952da12eaa09b9508d8/greenlet-3.5.1-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6ebeb75c81211f5c702576cf81f315e77e23cfdb2c7c6fcb9dd143e6de35c360", size = 623515, upload-time = "2026-05-20T14:09:07.853Z" }, { url = "https://files.pythonhosted.org/packages/75/de/af6cef182862d2ccd6975440d21c9058a77c3f9b469abf94e322dfd2e0e3/greenlet-3.5.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8a271fcd66c74615cda6a964fda3f304267a12e50a084472218a39bb0376f563", size = 614754, upload-time = "2026-05-20T13:14:24.947Z" }, - { url = "https://files.pythonhosted.org/packages/ec/bc/c318aa9f3ffc77320fddcee3d892be957b42e2ff947198d9450b004f3a38/greenlet-3.5.1-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:017a544f0385d441e88714160d089d6900ef46c9eff9d99b6715a5ef2d127747", size = 418439, upload-time = "2026-05-20T14:01:38.446Z" }, { url = "https://files.pythonhosted.org/packages/1a/c6/50e520283a9f19388a7326b05f9e8637e566003475eacaadad04f558c68d/greenlet-3.5.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ded7b068c7c31c1a8657d4fd42d886b3e051ae29f88b80c5ff9d502257b0f071", size = 1574097, upload-time = "2026-05-20T14:02:24.003Z" }, { url = "https://files.pythonhosted.org/packages/21/1c/13abd1f4860d987fa5e1170a01930d6e6cd40d328de487a3c9fdaff0ffd0/greenlet-3.5.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d0932b81d72f552ded9d810d00021b64d89f2195a91ce115b893f943b7a4ab3c", size = 1641058, upload-time = "2026-05-20T13:14:31.83Z" }, { url = "https://files.pythonhosted.org/packages/f5/56/5f332b7705545eac2dc01b4e9254d24a793f2656d55d5cc6b94ee59d22ae/greenlet-3.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:88e300d136eac057b2397aa1cfd7328b4c87c7eb66a09c7bc6a1292234db474e", size = 238089, upload-time = "2026-05-20T13:14:03.229Z" }, @@ -935,9 +933,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c4/37/4549f149c9797c21b32c2683c33522af22522099de128b2406672526d005/greenlet-3.5.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:fa4f98af3a528f0c3fd592a26df7f376f93329c8f4d987f6bb979057af8bf5e2", size = 286220, upload-time = "2026-05-20T13:07:28.463Z" }, { url = "https://files.pythonhosted.org/packages/38/ff/a4f436709716965eaab9f36ea7b906c8a927fbe32fb1372a2071d964f6b1/greenlet-3.5.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ffea73584b216150eab159b6d12348fb253e68757974de1e2c40d8a318ac89ed", size = 601585, upload-time = "2026-05-20T14:00:06.141Z" }, { url = "https://files.pythonhosted.org/packages/65/ad/54bc3fcee3ad368a61b19b67d88117f7a8c29727bf71fffdeda81fbd946e/greenlet-3.5.1-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1072b4f9edcc1e192d9283a66a3e68d6b84c561de33a83d7858beb9ba1effe10", size = 614215, upload-time = "2026-05-20T14:05:42.675Z" }, - { url = "https://files.pythonhosted.org/packages/7c/6c/de5b1b388cd2d9fbdfeab324863daba37d54e6e233ddbefd70b385a8c591/greenlet-3.5.1-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:89101bfd5011e069be974903cb3a4e4523845e4ece2d62dcd8d358933c0ef249", size = 620094, upload-time = "2026-05-20T14:09:09.18Z" }, { url = "https://files.pythonhosted.org/packages/40/69/b91cda0647df839483201545913514c2827ebea5e5ccdf931842763bc127/greenlet-3.5.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:add5217d68b31130f0beca584d7fef4878327d2e31642b66618a14eef312b63b", size = 611358, upload-time = "2026-05-20T13:14:26.37Z" }, - { url = "https://files.pythonhosted.org/packages/4a/43/1204baffab8a6476464795a7ccf394a3248d4f22c9f87173a15b36b6d971/greenlet-3.5.1-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:e6cd99ea59dd5d89f0c956606571d79bfe6f68c9eb7f4a4083a41a7f1587edee", size = 422782, upload-time = "2026-05-20T14:01:39.597Z" }, { url = "https://files.pythonhosted.org/packages/59/90/3cf77e080350cd02fa307bb2abf05df48f4482c240275bbd2c203ba8bb1c/greenlet-3.5.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a5ea42a752d47a145eae922b605cd1634665ac3d5ec1e72402d5048e8d60d207", size = 1570475, upload-time = "2026-05-20T14:02:25.29Z" }, { url = "https://files.pythonhosted.org/packages/65/2c/18cece62045e74598c3c393f70dce4a63f56222015ba29a5d4eeb04f764c/greenlet-3.5.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c5551170cf4f5ff5623e9af81323751979fee2c731e2287b61f73cd27257b823", size = 1635625, upload-time = "2026-05-20T13:14:34.027Z" }, { url = "https://files.pythonhosted.org/packages/30/f5/310d104ddf41eb5a70f4c268d22508dfb0c3c8e86fec152be34d0d2ed819/greenlet-3.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c8bb982ad117d29478ef8f5533e97df21f1e2befd17a299257b0c96d1371c0b", size = 238791, upload-time = "2026-05-20T13:10:39.018Z" }, @@ -945,9 +941,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/27/69/7f7e5372d998b81001899b1c0823c957aa413ba0f2662e65821611cc31e4/greenlet-3.5.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:51518ff74664078fc51bffcc6fc529b0df5ae58da192691cee765d45ce944a2b", size = 285060, upload-time = "2026-05-20T13:08:51.899Z" }, { url = "https://files.pythonhosted.org/packages/b1/bf/387f9b6b865fd2ae0d0be09e0004827295a01b71be76ed350dd1e28a91a4/greenlet-3.5.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ffdb3c0bb002c99cd8f298957e046c3dbf6006b5b7cdf11a4e19194624a0a0a", size = 604370, upload-time = "2026-05-20T14:00:07.492Z" }, { url = "https://files.pythonhosted.org/packages/32/f5/169ce3d4e4c67291bd18f8cbe0299c9f3e45102c7f1fb3c14780c93e4532/greenlet-3.5.1-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7715a5a2c3378ba602c3a440558261e13a820bb53a82693aacd7b7f6d964e283", size = 616987, upload-time = "2026-05-20T14:05:44.237Z" }, - { url = "https://files.pythonhosted.org/packages/19/ba/c24110c55dffa55aa6e1d98b45310da33801aeba7686ff0190fe5d46fd32/greenlet-3.5.1-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d40a890035c0058cadbdc4af7569800fd28a0e527a0fdbb7b5f9418f176846ce", size = 622911, upload-time = "2026-05-20T14:09:10.598Z" }, { url = "https://files.pythonhosted.org/packages/ee/e5/7f2e41d5273be07e77560d61ea4e56485b4d6c316d2a84518c62d1364061/greenlet-3.5.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc71ff466927a201b08305acac451ebe1aedfcea002f62f1f2f2ac2ac1e6a135", size = 613911, upload-time = "2026-05-20T13:14:27.539Z" }, - { url = "https://files.pythonhosted.org/packages/ec/7b/d20db2e8a5ad6c038702f3179b136f93f0a3d1a21a0c0777f3e470cdf4b2/greenlet-3.5.1-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:67821bb03e4e98664490edb787ff6af501194c29bbee0f5c1dfdcf1dc3d9d436", size = 425228, upload-time = "2026-05-20T14:01:40.837Z" }, { url = "https://files.pythonhosted.org/packages/c5/a4/fbdc67579b73615a1f91615e814303cc71e06128f7baaba87be79b8fb90c/greenlet-3.5.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cd443683db272ebaaca03af98c0b063ab30db70ea8a31a1559f35e3f7b744ccd", size = 1570689, upload-time = "2026-05-20T14:02:27.225Z" }, { url = "https://files.pythonhosted.org/packages/e6/b4/77abbe35078be39718a46cd49caf16bceb35662f97a34101dca28aa98e47/greenlet-3.5.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:089fff7a6ce8d9316d1f65ebc00273a56be258c1725b32b94de90a3a979557e1", size = 1635602, upload-time = "2026-05-20T13:14:36.344Z" }, { url = "https://files.pythonhosted.org/packages/37/f7/129f27ca700845b8ee8ca88ce7f43435a1239c2eddb7677fc938822762cf/greenlet-3.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:110a1ca7b49b014b097f6078272c3f4ed31af45b254de5228b79adba879f6af9", size = 238683, upload-time = "2026-05-20T13:11:50.57Z" }, @@ -955,9 +949,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8a/cb/c62454606daf5640369c94d8a9dd540599b1bfc090e2d2180cb77f4038d2/greenlet-3.5.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:d8ab31c9de8651a2facdd5c5bb0011f2380dd1a7af78ce2adf4b56095294fc07", size = 285579, upload-time = "2026-05-20T13:08:56.396Z" }, { url = "https://files.pythonhosted.org/packages/ec/71/c4270398c2eba968a6071af1dfbdcaeee6ec1c24bc8b435b8cc452700da6/greenlet-3.5.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5e300185139abc337ade480c327183adf42a875ac7181bfe66d7d4efea31fbea", size = 651106, upload-time = "2026-05-20T14:00:09.448Z" }, { url = "https://files.pythonhosted.org/packages/1a/ab/71e34b78a44ec271fb5f550c17bc46d301ddc5953890d935f270b0dcdb5a/greenlet-3.5.1-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7ffdb990dcaa0234cf9845aead5df2e3c3a8b6507d409274dd87e0d5ab05ffc2", size = 663478, upload-time = "2026-05-20T14:05:45.88Z" }, - { url = "https://files.pythonhosted.org/packages/c6/2d/2d80842910da44f78c286532d084b8a5c3717c844ae80ceb3858738ae89a/greenlet-3.5.1-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c09df69dc1712d131332054a858a3e5cca400967fa3a672e2324fbb0971448c", size = 667767, upload-time = "2026-05-20T14:09:12.15Z" }, { url = "https://files.pythonhosted.org/packages/77/96/4efd6fa5c62c85426a0c19077a586258ebc3a2a146ff2493e4312a697a22/greenlet-3.5.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2f82b3597e9d83b63408affed0b48fd0f54935edac4302237b9a837be0dae33c", size = 660800, upload-time = "2026-05-20T13:14:29.129Z" }, - { url = "https://files.pythonhosted.org/packages/e9/d3/dad2eecedfbb1ed7050a20dcfae40c1442b74bc7423608be2c7e03ee7133/greenlet-3.5.1-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:a4764e0bfc6a4d114c865b32520805c16a990ef5f286a514413b05d5ecd6a23d", size = 470786, upload-time = "2026-05-20T14:01:42.064Z" }, { url = "https://files.pythonhosted.org/packages/7a/e0/6c71401a25cac7000261304e866a2f2cc04dc74810d40e2f118aa4799495/greenlet-3.5.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c0141e37414c10164e702b8fb1473304221ad98f71600850c6ef7ff4880feba0", size = 1617518, upload-time = "2026-05-20T14:02:28.662Z" }, { url = "https://files.pythonhosted.org/packages/41/26/c5c06643e8c0af9e7bf18e16cb51d0ab7625155f0392e1c9015d66d556cd/greenlet-3.5.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:50ae25a67bea74ea41fb14b960bc532df73eb713417b2d61892dced82fe8d3bc", size = 1681593, upload-time = "2026-05-20T13:14:39.417Z" }, { url = "https://files.pythonhosted.org/packages/8a/bd/e11a108317485075e68af9d23039619b86b28130c3b50d227d42edece64b/greenlet-3.5.1-cp314-cp314-win_amd64.whl", hash = "sha256:8a17c42330e261299766b75ac1ea32caa437a9453c8f65d16a13140db378ecd3", size = 239800, upload-time = "2026-05-20T13:09:30.128Z" }, @@ -965,18 +957,14 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/90/12/41bf27fde4d3605d3773ae57751eda182b8be2f5398011c041173b1d9534/greenlet-3.5.1-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:ea8da1e900d758d078810d4255d8c6aa572181896a31ec79d779eb79c3adc9ad", size = 293637, upload-time = "2026-05-20T13:12:35.529Z" }, { url = "https://files.pythonhosted.org/packages/44/44/ba14b23e9757707050c2f397d305bbcae62e5d7cad122f8b6baec5ae4a1f/greenlet-3.5.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a19570c52a21420dcbc94e661994bc325c0b5b11304540fed514586da5dc8f2e", size = 650840, upload-time = "2026-05-20T14:00:11.079Z" }, { url = "https://files.pythonhosted.org/packages/a8/37/5ddc2b686a6844f91abecef43411842426da2e1573f60b49ecf2547f4ae1/greenlet-3.5.1-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3d955c89b75eeca4723d7cc14135f393cd47c32e2a6cb4a8e4c6e760a26b0986", size = 656416, upload-time = "2026-05-20T14:05:47.118Z" }, - { url = "https://files.pythonhosted.org/packages/8c/46/5987dcd1a2570ba84f3b187536b2ca3ae97613387e57f5cfa99df068fe5e/greenlet-3.5.1-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea37d5a157eb9493820d3792ac4ece28619a394391d2b9f2f78057d396ff0f0f", size = 656607, upload-time = "2026-05-20T14:09:13.949Z" }, { url = "https://files.pythonhosted.org/packages/e1/f0/d17510297c35a2992712f0bf84de3779749999f7d3d63aa1f09db7c62dbe/greenlet-3.5.1-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2daaaebd1a5aa88c49045b6baf9310b3263796bd88db713edf37cf53e7bb4e", size = 654397, upload-time = "2026-05-20T13:14:30.696Z" }, - { url = "https://files.pythonhosted.org/packages/2c/c1/6da0a9ddcc29d7e51ef14883fa3dc1e53b3f4ffba00582106c7bf55da1d8/greenlet-3.5.1-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:8d8a23250ea3ec7b36de8fa4b541e9e2db3ee82915cc060ab0631609ad8b28de", size = 488287, upload-time = "2026-05-20T14:01:43.143Z" }, { url = "https://files.pythonhosted.org/packages/37/eb/147387705bb89092645b012586e7273cb5ed3c90ef7eaf3a69173eaf0209/greenlet-3.5.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3bfbd69cc349e43bf3a8ae1c85548ff0718efc887615c2db16c3833d7b0b072d", size = 1614469, upload-time = "2026-05-20T14:02:30.192Z" }, { url = "https://files.pythonhosted.org/packages/a6/4e/37ee0da7732b7aa9896f17e15579a9df34b9fcb9dd494f0adfa749af6623/greenlet-3.5.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4378720dd888136c27215a0214d32a4d37c3852765d45bc37aad0623423cfd78", size = 1675115, upload-time = "2026-05-20T13:14:40.972Z" }, { url = "https://files.pythonhosted.org/packages/57/f3/97dfcf4a6eb5077f8a672234216fb5923eb89f2cab7081cb10b2cf75b605/greenlet-3.5.1-cp314-cp314t-win_amd64.whl", hash = "sha256:45718441607f9325d948db98cbc691276059316d0358c188c246da4e1d4d23d2", size = 245246, upload-time = "2026-05-20T13:12:22.646Z" }, { url = "https://files.pythonhosted.org/packages/5d/73/d7f72e34b582f694f4a9b248162db7b09cc458a259ba8f0c0bfa1a34ea7d/greenlet-3.5.1-cp315-cp315-macosx_11_0_universal2.whl", hash = "sha256:2baee5ca02031757ffe8cc3d69f0cc0aec7065ce362622da74f32d3bcab1c541", size = 285575, upload-time = "2026-05-20T13:12:07.043Z" }, { url = "https://files.pythonhosted.org/packages/df/59/fa9c6e87dc8ad27a95dabe2f29f372b733d05a8a67470f6c901ed9975655/greenlet-3.5.1-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9b1ec3274918a81d3ea778b9e75b56b72b33f300edb6cf7f3a7fe1dae56683de", size = 656428, upload-time = "2026-05-20T14:00:12.556Z" }, { url = "https://files.pythonhosted.org/packages/f6/f9/e753408871eaa61dfe35e619cfc67512b036fde99893685d50eea9e07146/greenlet-3.5.1-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:111e2390ffffc47d5840b01711dd7fac07d4c09283d0283e7f3264b14e284c64", size = 667064, upload-time = "2026-05-20T14:05:48.662Z" }, - { url = "https://files.pythonhosted.org/packages/dc/74/807a047255bf1e09303627c46dc043dca596b6958a354d904f32ab382005/greenlet-3.5.1-cp315-cp315-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:10a9a1c0bfbc93d41156ffcb90c75fbc05544054faf15dcc1fdf9765f8b607f0", size = 672962, upload-time = "2026-05-20T14:09:15.532Z" }, { url = "https://files.pythonhosted.org/packages/96/27/5565b5b40389f1c7753003a07e21892fda8660926787036d5bc0308b8113/greenlet-3.5.1-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e630136e905fe5ff43e86945ae41220b6d1470956a39220e708110ac48d01ea5", size = 665697, upload-time = "2026-05-20T13:14:32.943Z" }, - { url = "https://files.pythonhosted.org/packages/76/32/19d4e13225193c29b13e308015223f7d75fd3d8623d49dd19040d2ce8ec1/greenlet-3.5.1-cp315-cp315-manylinux_2_39_riscv64.whl", hash = "sha256:ef08c1567c78074b22d1a200183d52d04a14df447bf70bcbb6a3507a48e776fc", size = 476047, upload-time = "2026-05-20T14:01:44.39Z" }, { url = "https://files.pythonhosted.org/packages/cf/82/e7de4178c0c2d1c9a5a3be3cc0b33e46a85b3ee4a77c071bf7ad8600e079/greenlet-3.5.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:975eac34b44a7077ca4d421348455b94f0f518246a7f14bc6d2fdcfe5b584368", size = 1621256, upload-time = "2026-05-20T14:02:31.91Z" }, { url = "https://files.pythonhosted.org/packages/00/10/f2dddcf7dacac17dfc68691809589adad06135eb28930429cf58a6467a2f/greenlet-3.5.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:9ab3c3a0b2ae6198e67c898dad5215a49f9ae0d0081b3c3ec59f333e39eeca26", size = 1685956, upload-time = "2026-05-20T13:14:42.55Z" }, { url = "https://files.pythonhosted.org/packages/22/17/4a232b32133230ada52f70e9d7f5b65b0caef8772f01849bd8d149e7e4ca/greenlet-3.5.1-cp315-cp315-win_amd64.whl", hash = "sha256:cbfc69be86e10dcfef5b1e6269d1d6926552aa89ee39e1de3353360c1b6989ab", size = 239802, upload-time = "2026-05-20T13:13:15.481Z" }, @@ -984,9 +972,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7a/57/816d9cff29119da3505b3d6a5e14a8af89006ac36f47f891ff293ee05af1/greenlet-3.5.1-cp315-cp315t-macosx_11_0_universal2.whl", hash = "sha256:a6fdf2433a5441ef9a95464f7c3e674775da1c8c1177fff311cee1acad4626ed", size = 293877, upload-time = "2026-05-20T13:10:19.078Z" }, { url = "https://files.pythonhosted.org/packages/23/a1/59b0a7c7d140ff1a75626680b9a9899b79a9176cab298b394968fb023295/greenlet-3.5.1-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7546556f0d649f99f6a361098a55f761181bb2ea12ff150bb16d26092ad88244", size = 655333, upload-time = "2026-05-20T14:00:14.758Z" }, { url = "https://files.pythonhosted.org/packages/72/1b/5efe127597625042218939d01855109f352779050768b670b52edcc16a6c/greenlet-3.5.1-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d5ee3ea898009fa898f85f9982255d35278c477bebe185beca249cab42d4526c", size = 659443, upload-time = "2026-05-20T14:05:50.159Z" }, - { url = "https://files.pythonhosted.org/packages/c9/9d/1dcdf7b95ab3cf8c7b6d7277c18a5e167312f2b362ddfcc5d5e6d8d84b43/greenlet-3.5.1-cp315-cp315t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a57b0d05a0448eed231d59c0ceb287dde984551e54cbc51ac2d4865712838e9c", size = 659998, upload-time = "2026-05-20T14:09:16.912Z" }, { url = "https://files.pythonhosted.org/packages/6c/6d/c404246ea4d22d097a7426d0efb5b781bd7eb67715f09e79001bd552ab18/greenlet-3.5.1-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5c81f74d204d3edd136ebfd50dce53acbb776995d721a0fe801626cfc93b8cd", size = 658356, upload-time = "2026-05-20T13:14:35.091Z" }, - { url = "https://files.pythonhosted.org/packages/05/7e/c4959664fc231d587d66d8e81f2095e98056ba1954beafdcbe635e251052/greenlet-3.5.1-cp315-cp315t-manylinux_2_39_riscv64.whl", hash = "sha256:b0703c2cef53e01baec47f7a3868009913ad71ec678bbecb42a6f40895e4ce62", size = 494470, upload-time = "2026-05-20T14:01:45.611Z" }, { url = "https://files.pythonhosted.org/packages/51/02/f8ee37fb6d2219329f350af241c27fcf12df57e723d11f6fc6d3bacdadaa/greenlet-3.5.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:2c18ef16bf6d4dd410e4dd52996888ea1497be26892fe5bbc73580aba4287b8e", size = 1619216, upload-time = "2026-05-20T14:02:33.403Z" }, { url = "https://files.pythonhosted.org/packages/93/c5/3dc9475ace2c7a3680da12372cddd7f1ac874eb410a1ac48d3e9dab83782/greenlet-3.5.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:17d86354f0ae6b61bf9be5148d0dd34e06c3cb7c602c671f79f29ac3b150e659", size = 1678427, upload-time = "2026-05-20T13:14:43.71Z" }, { url = "https://files.pythonhosted.org/packages/df/4e/750c15c317a41ffb36f0bf40b933e3d744a7dede61889f74443ea69690cf/greenlet-3.5.1-cp315-cp315t-win_amd64.whl", hash = "sha256:e7516cf6ae6b8a582c2770a0caed47b8a48373ed732c33d69a72913ae6ac923e", size = 245225, upload-time = "2026-05-20T13:13:59.366Z" }, @@ -2597,20 +2583,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5e/a3/f2c38b8cd448ee536870bc7771d863ec57232446c850124adcd08bc8e3c0/opentelemetry_instrumentation_writer-0.52.3-py3-none-any.whl", hash = "sha256:c5155413d6f4e6ae7b842d6b1b2df21a244969c669e3ffb78a7ef7c57afb1da5", size = 11516, upload-time = "2026-02-10T14:54:43.197Z" }, ] -[[package]] -name = "opentelemetry-processor-baggage" -version = "0.61b0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "opentelemetry-api" }, - { name = "opentelemetry-sdk" }, - { name = "wrapt" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a3/0d/4afee20490ef53a449b1781b0671d84858742a2ccfb01c08de398a5d1ccd/opentelemetry_processor_baggage-0.61b0.tar.gz", hash = "sha256:4d1d2a624e3aa9a8b6c6d1f560ba2951f97acf875f57502a274c5078043a69d5", size = 7573, upload-time = "2026-03-04T14:20:54.941Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ac/24/0ef2cf49e6ac9b2b422400abbf528230a409c9e174572f2d13e2dff7ec7c/opentelemetry_processor_baggage-0.61b0-py3-none-any.whl", hash = "sha256:f6b5937e93bda8f380d8f5f667355c7d127e9296b38dfacf39fd328ab410262c", size = 8881, upload-time = "2026-03-04T14:20:05.25Z" }, -] - [[package]] name = "opentelemetry-proto" version = "1.42.1" @@ -3713,7 +3685,7 @@ wheels = [ [[package]] name = "sap-cloud-sdk" -version = "0.33.0" +version = "0.33.1" source = { editable = "." } dependencies = [ { name = "grpcio" }, @@ -3725,7 +3697,6 @@ dependencies = [ { name = "opentelemetry-exporter-otlp-proto-grpc" }, { name = "opentelemetry-exporter-otlp-proto-http" }, { name = "opentelemetry-instrumentation-langchain" }, - { name = "opentelemetry-processor-baggage" }, { name = "opentelemetry-sdk" }, { name = "protobuf" }, { name = "protovalidate" }, @@ -3782,7 +3753,6 @@ requires-dist = [ { name = "opentelemetry-exporter-otlp-proto-grpc", specifier = "~=1.42.1" }, { name = "opentelemetry-exporter-otlp-proto-http", specifier = "~=1.42.1" }, { name = "opentelemetry-instrumentation-langchain", specifier = ">=0.61.0" }, - { name = "opentelemetry-processor-baggage", specifier = "~=0.61b0" }, { name = "opentelemetry-sdk", specifier = ">=1.42.1" }, { name = "protobuf", specifier = ">=4.25.0" }, { name = "protovalidate", specifier = ">=0.13.0" }, From a2fe0b2cfd69e7ce398a53ec415f92041c2cc5d7 Mon Sep 17 00:00:00 2001 From: Lucas Soares Date: Tue, 7 Jul 2026 13:06:50 -0300 Subject: [PATCH 3/4] Type correctness --- .../telemetry/span_processors/baggage_span_processor.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sap_cloud_sdk/core/telemetry/span_processors/baggage_span_processor.py b/src/sap_cloud_sdk/core/telemetry/span_processors/baggage_span_processor.py index 3d41ce92..a94a9e51 100644 --- a/src/sap_cloud_sdk/core/telemetry/span_processors/baggage_span_processor.py +++ b/src/sap_cloud_sdk/core/telemetry/span_processors/baggage_span_processor.py @@ -6,6 +6,7 @@ from opentelemetry.context import Context from opentelemetry.sdk.trace import ReadableSpan, SpanProcessor from opentelemetry.trace import Span +from opentelemetry.util.types import AttributeValue logger = logging.getLogger(__name__) @@ -44,7 +45,7 @@ def __init__( ) -> None: self._baggage_key_predicate = baggage_key_predicate self._override_keys = frozenset(override_keys) - self._pending: Dict[int, Dict[str, Any]] = {} + self._pending: Dict[int, Dict[str, AttributeValue]] = {} def on_start(self, span: Span, parent_context: Optional[Context] = None) -> None: if not span.is_recording(): @@ -52,9 +53,9 @@ def on_start(self, span: Span, parent_context: Optional[Context] = None) -> None all_baggage = get_all_baggage(parent_context) for key, value in all_baggage.items(): if self._baggage_key_predicate(key): - span.set_attribute(key, value) + span.set_attribute(key, cast(AttributeValue, value)) - overrides = {k: all_baggage[k] for k in self._override_keys if k in all_baggage} + overrides = {k: cast(AttributeValue, all_baggage[k]) for k in self._override_keys if k in all_baggage} if overrides: span_id = getattr(getattr(span, "context", None), "span_id", None) if span_id is not None: From bbb21dabe3ea77e538accb1df95461dcebe59623 Mon Sep 17 00:00:00 2001 From: Lucas Soares Date: Tue, 7 Jul 2026 13:08:26 -0300 Subject: [PATCH 4/4] Linting --- .../telemetry/span_processors/baggage_span_processor.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sap_cloud_sdk/core/telemetry/span_processors/baggage_span_processor.py b/src/sap_cloud_sdk/core/telemetry/span_processors/baggage_span_processor.py index a94a9e51..f3f24971 100644 --- a/src/sap_cloud_sdk/core/telemetry/span_processors/baggage_span_processor.py +++ b/src/sap_cloud_sdk/core/telemetry/span_processors/baggage_span_processor.py @@ -55,7 +55,11 @@ def on_start(self, span: Span, parent_context: Optional[Context] = None) -> None if self._baggage_key_predicate(key): span.set_attribute(key, cast(AttributeValue, value)) - overrides = {k: cast(AttributeValue, all_baggage[k]) for k in self._override_keys if k in all_baggage} + overrides = { + k: cast(AttributeValue, all_baggage[k]) + for k in self._override_keys + if k in all_baggage + } if overrides: span_id = getattr(getattr(span, "context", None), "span_id", None) if span_id is not None: