99from enum import Enum
1010from typing import TYPE_CHECKING
1111
12+ import sentry_sdk
13+ from sentry_sdk .tracing_utils import Baggage
1214from sentry_sdk .utils import format_attribute , logger
1315
1416if TYPE_CHECKING :
@@ -57,6 +59,66 @@ def __str__(self) -> str:
5759}
5860
5961
62+ def start_span (
63+ name : str ,
64+ attributes : "Optional[Attributes]" = None ,
65+ parent_span : "Optional[StreamedSpan]" = None ,
66+ active : bool = True ,
67+ ) -> "StreamedSpan" :
68+ """
69+ Start a span.
70+
71+ The span's parent, unless provided explicitly via the `parent_span` argument,
72+ will be the current active span, if any. If there is none, this span will
73+ become the root of a new span tree.
74+
75+ `start_span()` can either be used as context manager or you can use the span
76+ object it returns and explicitly end it via `span.end()`. The following is
77+ equivalent:
78+
79+ ```python
80+ import sentry_sdk
81+
82+ with sentry_sdk.traces.start_span(name="My Span"):
83+ # do something
84+
85+ # The span automatically finishes once the `with` block is exited
86+ ```
87+
88+ ```python
89+ import sentry_sdk
90+
91+ span = sentry_sdk.traces.start_span(name="My Span")
92+ # do something
93+ span.end()
94+ ```
95+
96+ :param name: The name to identify this span by.
97+ :type name: str
98+
99+ :param attributes: Key-value attributes to set on the span from the start.
100+ These will also be accessible in the traces sampler.
101+ :type attributes: "Optional[Attributes]"
102+
103+ :param parent_span: A span instance that the new span should consider its
104+ parent. If not provided, the parent will be set to the currently active
105+ span, if any.
106+ :type parent_span: "Optional[StreamedSpan]"
107+
108+ :param active: Controls whether spans started while this span is running
109+ will automatically become its children. That's the default behavior. If
110+ you want to create a span that shouldn't have any children (unless
111+ provided explicitly via the `parent_span` argument), set this to `False`.
112+ :type active: bool
113+
114+ :return: The span that has been started.
115+ :rtype: StreamedSpan
116+ """
117+ return sentry_sdk .get_current_scope ().start_streamed_span (
118+ name , attributes , parent_span , active
119+ )
120+
121+
60122class StreamedSpan :
61123 """
62124 A span holds timing information of a block of code.
@@ -73,7 +135,12 @@ class StreamedSpan:
73135 "_active" ,
74136 "_span_id" ,
75137 "_trace_id" ,
138+ "_parent_span_id" ,
139+ "_segment" ,
140+ "_parent_sampled" ,
76141 "_status" ,
142+ "_scope" ,
143+ "_baggage" ,
77144 )
78145
79146 def __init__ (
@@ -82,7 +149,12 @@ def __init__(
82149 name : str ,
83150 attributes : "Optional[Attributes]" = None ,
84151 active : bool = True ,
152+ scope : "sentry_sdk.Scope" ,
153+ segment : "Optional[StreamedSpan]" = None ,
85154 trace_id : "Optional[str]" = None ,
155+ parent_span_id : "Optional[str]" = None ,
156+ parent_sampled : "Optional[bool]" = None ,
157+ baggage : "Optional[Baggage]" = None ,
86158 ):
87159 self ._name : str = name
88160 self ._active : bool = active
@@ -91,8 +163,16 @@ def __init__(
91163 for attribute , value in attributes .items ():
92164 self .set_attribute (attribute , value )
93165
94- self ._span_id : "Optional[str]" = None
166+ self ._scope = scope
167+
168+ self ._segment = segment or self
169+
95170 self ._trace_id : "Optional[str]" = trace_id
171+ self ._parent_span_id = parent_span_id
172+ self ._parent_sampled = parent_sampled
173+ self ._baggage = baggage
174+
175+ self ._span_id : "Optional[str]" = None
96176
97177 self ._status = SpanStatus .OK .value
98178 self .set_attribute ("sentry.span.source" , SegmentSource .CUSTOM .value )
@@ -103,6 +183,7 @@ def __repr__(self) -> str:
103183 f"name={ self ._name } , "
104184 f"trace_id={ self .trace_id } , "
105185 f"span_id={ self .span_id } , "
186+ f"parent_span_id={ self ._parent_span_id } , "
106187 f"active={ self ._active } )>"
107188 )
108189
@@ -165,8 +246,15 @@ def trace_id(self) -> str:
165246
166247 return self ._trace_id
167248
249+ @property
250+ def sampled (self ) -> "Optional[bool]" :
251+ return True
252+
168253
169254class NoOpStreamedSpan (StreamedSpan ):
255+ def __init__ (self ) -> None :
256+ pass
257+
170258 def get_attributes (self ) -> "Attributes" :
171259 return {}
172260
@@ -206,3 +294,7 @@ def span_id(self) -> str:
206294 @property
207295 def trace_id (self ) -> str :
208296 return "00000000000000000000000000000000"
297+
298+ @property
299+ def sampled (self ) -> "Optional[bool]" :
300+ return False
0 commit comments