diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py
index 466e1b5b12..c93dc19e87 100644
--- a/sentry_sdk/scope.py
+++ b/sentry_sdk/scope.py
@@ -525,14 +525,12 @@ def get_dynamic_sampling_context(self):
"""
Returns the Dynamic Sampling Context from the Propagation Context.
If not existing, creates a new one.
+
+ Deprecated: Logic moved to PropagationContext, don't use directly.
"""
if self._propagation_context is None:
return None
- baggage = self.get_baggage()
- if baggage is not None:
- self._propagation_context.baggage = baggage
-
return self._propagation_context.dynamic_sampling_context
def get_traceparent(self, *args, **kwargs):
@@ -547,16 +545,13 @@ def get_traceparent(self, *args, **kwargs):
if has_tracing_enabled(client.options) and self.span is not None:
return self.span.to_traceparent()
- # If this scope has a propagation context, return traceparent from there
- if self._propagation_context is not None:
- traceparent = "%s-%s" % (
- self._propagation_context.trace_id,
- self._propagation_context.span_id,
- )
- return traceparent
+ # else return traceparent from the propagation context
+ propagation_context = self.get_active_propagation_context()
+ if propagation_context is not None:
+ return propagation_context.to_traceparent()
- # Fall back to isolation scope's traceparent. It always has one
- return self.get_isolation_scope().get_traceparent()
+ # TODO-neel will never happen
+ return None
def get_baggage(self, *args, **kwargs):
# type: (Any, Any) -> Optional[Baggage]
@@ -570,12 +565,13 @@ def get_baggage(self, *args, **kwargs):
if has_tracing_enabled(client.options) and self.span is not None:
return self.span.to_baggage()
- # If this scope has a propagation context, return baggage from there
- if self._propagation_context is not None:
- return self._propagation_context.baggage or Baggage.from_options(self)
+ # else return baggage from the propagation context
+ propagation_context = self.get_active_propagation_context()
+ if propagation_context is not None:
+ return propagation_context.get_baggage()
- # Fall back to isolation scope's baggage. It always has one
- return self.get_isolation_scope().get_baggage()
+ # TODO-neel will never happen
+ return None
def get_trace_context(self):
# type: () -> Dict[str, Any]
@@ -599,7 +595,7 @@ def get_trace_context(self):
"trace_id": propagation_context.trace_id,
"span_id": propagation_context.span_id,
"parent_span_id": propagation_context.parent_span_id,
- "dynamic_sampling_context": self.get_dynamic_sampling_context(),
+ "dynamic_sampling_context": propagation_context.dynamic_sampling_context,
}
def trace_propagation_meta(self, *args, **kwargs):
@@ -616,19 +612,8 @@ def trace_propagation_meta(self, *args, **kwargs):
meta = ""
- sentry_trace = self.get_traceparent()
- if sentry_trace is not None:
- meta += '' % (
- SENTRY_TRACE_HEADER_NAME,
- sentry_trace,
- )
-
- baggage = self.get_baggage()
- if baggage is not None:
- meta += '' % (
- BAGGAGE_HEADER_NAME,
- baggage.serialize(),
- )
+ for name, content in self.iter_trace_propagation_headers():
+ meta += f''
return meta
@@ -636,16 +621,10 @@ def iter_headers(self):
# type: () -> Iterator[Tuple[str, str]]
"""
Creates a generator which returns the `sentry-trace` and `baggage` headers from the Propagation Context.
+ Deprecated: use PropagationContext.iter_headers instead.
"""
if self._propagation_context is not None:
- traceparent = self.get_traceparent()
- if traceparent is not None:
- yield SENTRY_TRACE_HEADER_NAME, traceparent
-
- dsc = self.get_dynamic_sampling_context()
- if dsc is not None:
- baggage = Baggage(dsc).serialize()
- yield BAGGAGE_HEADER_NAME, baggage
+ yield from self._propagation_context.iter_headers()
def iter_trace_propagation_headers(self, *args, **kwargs):
# type: (Any, Any) -> Generator[Tuple[str, str], None, None]
@@ -671,23 +650,10 @@ def iter_trace_propagation_headers(self, *args, **kwargs):
for header in span.iter_headers():
yield header
else:
- # If this scope has a propagation context, return headers from there
- # (it could be that self is not the current scope nor the isolation scope)
- if self._propagation_context is not None:
- for header in self.iter_headers():
+ propagation_context = self.get_active_propagation_context()
+ if propagation_context is not None:
+ for header in propagation_context.iter_headers():
yield header
- else:
- # otherwise try headers from current scope
- current_scope = self.get_current_scope()
- if current_scope._propagation_context is not None:
- for header in current_scope.iter_headers():
- yield header
- else:
- # otherwise fall back to headers from isolation scope
- isolation_scope = self.get_isolation_scope()
- if isolation_scope._propagation_context is not None:
- for header in isolation_scope.iter_headers():
- yield header
def get_active_propagation_context(self):
# type: () -> Optional[PropagationContext]
diff --git a/sentry_sdk/tracing_utils.py b/sentry_sdk/tracing_utils.py
index 69ba197ddf..df922faaa2 100644
--- a/sentry_sdk/tracing_utils.py
+++ b/sentry_sdk/tracing_utils.py
@@ -35,6 +35,8 @@
from typing import Generator
from typing import Optional
from typing import Union
+ from typing import Iterator
+ from typing import Tuple
from types import FrameType
@@ -506,7 +508,28 @@ def span_id(self, value):
@property
def dynamic_sampling_context(self):
# type: () -> Optional[Dict[str, Any]]
- return self.baggage.dynamic_sampling_context() if self.baggage else None
+ return self.get_baggage().dynamic_sampling_context()
+
+ def to_traceparent(self):
+ # type: () -> str
+ return f"{self.trace_id}-{self.span_id}"
+
+ def get_baggage(self):
+ # type: () -> Baggage
+ if self.baggage is None:
+ self.baggage = Baggage.populate_from_propagation_context(self)
+ return self.baggage
+
+ def iter_headers(self):
+ # type: () -> Iterator[Tuple[str, str]]
+ """
+ Creates a generator which returns the propagation_context's ``sentry-trace`` and ``baggage`` headers.
+ """
+ yield SENTRY_TRACE_HEADER_NAME, self.to_traceparent()
+
+ baggage = self.get_baggage().serialize()
+ if baggage:
+ yield BAGGAGE_HEADER_NAME, baggage
def update(self, other_dict):
# type: (Dict[str, Any]) -> None
@@ -649,21 +672,29 @@ def from_incoming_header(
@classmethod
def from_options(cls, scope):
# type: (sentry_sdk.scope.Scope) -> Optional[Baggage]
+ """
+ Deprecated: use populate_from_propagation_context
+ """
+ if scope._propagation_context is None:
+ return Baggage({})
+ return Baggage.populate_from_propagation_context(scope._propagation_context)
+
+ @classmethod
+ def populate_from_propagation_context(cls, propagation_context):
+ # type: (PropagationContext) -> Baggage
sentry_items = {} # type: Dict[str, str]
third_party_items = ""
mutable = False
client = sentry_sdk.get_client()
- if not client.is_active() or scope._propagation_context is None:
+ if not client.is_active():
return Baggage(sentry_items)
options = client.options
- propagation_context = scope._propagation_context
- if propagation_context is not None:
- sentry_items["trace_id"] = propagation_context.trace_id
+ sentry_items["trace_id"] = propagation_context.trace_id
if options.get("environment"):
sentry_items["environment"] = options["environment"]
diff --git a/tests/test_propagationcontext.py b/tests/test_propagationcontext.py
index e014012956..6c14aa2952 100644
--- a/tests/test_propagationcontext.py
+++ b/tests/test_propagationcontext.py
@@ -25,7 +25,7 @@ def test_empty_context():
assert ctx.parent_span_id is None
assert ctx.parent_sampled is None
- assert ctx.dynamic_sampling_context is None
+ assert ctx.dynamic_sampling_context == {}
def test_context_with_values():
@@ -72,7 +72,7 @@ def test_property_setters():
assert ctx.trace_id == "X234567890abcdef1234567890abcdef"
assert ctx._span_id == "X234567890abcdef"
assert ctx.span_id == "X234567890abcdef"
- assert ctx.dynamic_sampling_context is None
+ assert ctx.dynamic_sampling_context == {}
def test_update():
@@ -93,7 +93,7 @@ def test_update():
assert ctx._span_id is not None
assert ctx.parent_span_id == "Z234567890abcdef"
assert not ctx.parent_sampled
- assert ctx.dynamic_sampling_context is None
+ assert ctx.dynamic_sampling_context == {}
assert not hasattr(ctx, "foo")