sentry-sdk 3.0.0a1__py2.py3-none-any.whl → 3.0.0a3__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of sentry-sdk might be problematic. Click here for more details.

Files changed (157) hide show
  1. sentry_sdk/__init__.py +2 -0
  2. sentry_sdk/_compat.py +5 -12
  3. sentry_sdk/_init_implementation.py +7 -7
  4. sentry_sdk/_log_batcher.py +17 -29
  5. sentry_sdk/_lru_cache.py +7 -9
  6. sentry_sdk/_queue.py +2 -4
  7. sentry_sdk/_types.py +11 -18
  8. sentry_sdk/_werkzeug.py +5 -7
  9. sentry_sdk/ai/monitoring.py +44 -31
  10. sentry_sdk/ai/utils.py +3 -4
  11. sentry_sdk/api.py +75 -87
  12. sentry_sdk/attachments.py +10 -12
  13. sentry_sdk/client.py +137 -155
  14. sentry_sdk/consts.py +430 -174
  15. sentry_sdk/crons/api.py +16 -17
  16. sentry_sdk/crons/decorator.py +25 -27
  17. sentry_sdk/debug.py +4 -6
  18. sentry_sdk/envelope.py +46 -112
  19. sentry_sdk/feature_flags.py +9 -15
  20. sentry_sdk/integrations/__init__.py +24 -19
  21. sentry_sdk/integrations/_asgi_common.py +15 -18
  22. sentry_sdk/integrations/_wsgi_common.py +22 -33
  23. sentry_sdk/integrations/aiohttp.py +32 -30
  24. sentry_sdk/integrations/anthropic.py +42 -37
  25. sentry_sdk/integrations/argv.py +3 -4
  26. sentry_sdk/integrations/ariadne.py +16 -18
  27. sentry_sdk/integrations/arq.py +21 -29
  28. sentry_sdk/integrations/asgi.py +63 -37
  29. sentry_sdk/integrations/asyncio.py +14 -16
  30. sentry_sdk/integrations/atexit.py +6 -10
  31. sentry_sdk/integrations/aws_lambda.py +26 -36
  32. sentry_sdk/integrations/beam.py +10 -18
  33. sentry_sdk/integrations/boto3.py +18 -16
  34. sentry_sdk/integrations/bottle.py +25 -34
  35. sentry_sdk/integrations/celery/__init__.py +41 -61
  36. sentry_sdk/integrations/celery/beat.py +23 -27
  37. sentry_sdk/integrations/celery/utils.py +15 -17
  38. sentry_sdk/integrations/chalice.py +8 -10
  39. sentry_sdk/integrations/clickhouse_driver.py +21 -31
  40. sentry_sdk/integrations/cloud_resource_context.py +9 -16
  41. sentry_sdk/integrations/cohere.py +27 -33
  42. sentry_sdk/integrations/dedupe.py +5 -8
  43. sentry_sdk/integrations/django/__init__.py +57 -72
  44. sentry_sdk/integrations/django/asgi.py +26 -34
  45. sentry_sdk/integrations/django/caching.py +23 -19
  46. sentry_sdk/integrations/django/middleware.py +17 -20
  47. sentry_sdk/integrations/django/signals_handlers.py +11 -10
  48. sentry_sdk/integrations/django/templates.py +19 -16
  49. sentry_sdk/integrations/django/transactions.py +16 -11
  50. sentry_sdk/integrations/django/views.py +6 -10
  51. sentry_sdk/integrations/dramatiq.py +21 -21
  52. sentry_sdk/integrations/excepthook.py +10 -10
  53. sentry_sdk/integrations/executing.py +3 -4
  54. sentry_sdk/integrations/falcon.py +27 -42
  55. sentry_sdk/integrations/fastapi.py +13 -16
  56. sentry_sdk/integrations/flask.py +31 -38
  57. sentry_sdk/integrations/gcp.py +13 -16
  58. sentry_sdk/integrations/gnu_backtrace.py +4 -6
  59. sentry_sdk/integrations/gql.py +16 -17
  60. sentry_sdk/integrations/graphene.py +13 -12
  61. sentry_sdk/integrations/grpc/__init__.py +19 -1
  62. sentry_sdk/integrations/grpc/aio/server.py +15 -14
  63. sentry_sdk/integrations/grpc/client.py +19 -9
  64. sentry_sdk/integrations/grpc/consts.py +2 -0
  65. sentry_sdk/integrations/grpc/server.py +12 -8
  66. sentry_sdk/integrations/httpx.py +9 -12
  67. sentry_sdk/integrations/huey.py +13 -20
  68. sentry_sdk/integrations/huggingface_hub.py +18 -18
  69. sentry_sdk/integrations/langchain.py +203 -113
  70. sentry_sdk/integrations/launchdarkly.py +13 -10
  71. sentry_sdk/integrations/litestar.py +37 -35
  72. sentry_sdk/integrations/logging.py +52 -65
  73. sentry_sdk/integrations/loguru.py +127 -57
  74. sentry_sdk/integrations/modules.py +3 -4
  75. sentry_sdk/integrations/openai.py +100 -88
  76. sentry_sdk/integrations/openai_agents/__init__.py +49 -0
  77. sentry_sdk/integrations/openai_agents/consts.py +1 -0
  78. sentry_sdk/integrations/openai_agents/patches/__init__.py +4 -0
  79. sentry_sdk/integrations/openai_agents/patches/agent_run.py +152 -0
  80. sentry_sdk/integrations/openai_agents/patches/models.py +52 -0
  81. sentry_sdk/integrations/openai_agents/patches/runner.py +42 -0
  82. sentry_sdk/integrations/openai_agents/patches/tools.py +84 -0
  83. sentry_sdk/integrations/openai_agents/spans/__init__.py +5 -0
  84. sentry_sdk/integrations/openai_agents/spans/agent_workflow.py +20 -0
  85. sentry_sdk/integrations/openai_agents/spans/ai_client.py +46 -0
  86. sentry_sdk/integrations/openai_agents/spans/execute_tool.py +47 -0
  87. sentry_sdk/integrations/openai_agents/spans/handoff.py +24 -0
  88. sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +41 -0
  89. sentry_sdk/integrations/openai_agents/utils.py +201 -0
  90. sentry_sdk/integrations/openfeature.py +11 -6
  91. sentry_sdk/integrations/pure_eval.py +6 -10
  92. sentry_sdk/integrations/pymongo.py +13 -17
  93. sentry_sdk/integrations/pyramid.py +31 -36
  94. sentry_sdk/integrations/quart.py +23 -28
  95. sentry_sdk/integrations/ray.py +73 -64
  96. sentry_sdk/integrations/redis/__init__.py +7 -4
  97. sentry_sdk/integrations/redis/_async_common.py +25 -12
  98. sentry_sdk/integrations/redis/_sync_common.py +19 -13
  99. sentry_sdk/integrations/redis/modules/caches.py +17 -8
  100. sentry_sdk/integrations/redis/modules/queries.py +9 -8
  101. sentry_sdk/integrations/redis/rb.py +3 -2
  102. sentry_sdk/integrations/redis/redis.py +4 -4
  103. sentry_sdk/integrations/redis/redis_cluster.py +21 -13
  104. sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +3 -2
  105. sentry_sdk/integrations/redis/utils.py +23 -24
  106. sentry_sdk/integrations/rq.py +13 -16
  107. sentry_sdk/integrations/rust_tracing.py +9 -6
  108. sentry_sdk/integrations/sanic.py +34 -46
  109. sentry_sdk/integrations/serverless.py +22 -27
  110. sentry_sdk/integrations/socket.py +27 -15
  111. sentry_sdk/integrations/spark/__init__.py +1 -0
  112. sentry_sdk/integrations/spark/spark_driver.py +45 -83
  113. sentry_sdk/integrations/spark/spark_worker.py +7 -11
  114. sentry_sdk/integrations/sqlalchemy.py +22 -19
  115. sentry_sdk/integrations/starlette.py +86 -90
  116. sentry_sdk/integrations/starlite.py +28 -34
  117. sentry_sdk/integrations/statsig.py +5 -4
  118. sentry_sdk/integrations/stdlib.py +28 -24
  119. sentry_sdk/integrations/strawberry.py +62 -49
  120. sentry_sdk/integrations/sys_exit.py +7 -11
  121. sentry_sdk/integrations/threading.py +12 -14
  122. sentry_sdk/integrations/tornado.py +28 -32
  123. sentry_sdk/integrations/trytond.py +4 -3
  124. sentry_sdk/integrations/typer.py +8 -6
  125. sentry_sdk/integrations/unleash.py +5 -4
  126. sentry_sdk/integrations/wsgi.py +47 -46
  127. sentry_sdk/logger.py +41 -10
  128. sentry_sdk/monitor.py +16 -28
  129. sentry_sdk/opentelemetry/consts.py +11 -4
  130. sentry_sdk/opentelemetry/contextvars_context.py +26 -16
  131. sentry_sdk/opentelemetry/propagator.py +38 -21
  132. sentry_sdk/opentelemetry/sampler.py +51 -34
  133. sentry_sdk/opentelemetry/scope.py +36 -37
  134. sentry_sdk/opentelemetry/span_processor.py +48 -58
  135. sentry_sdk/opentelemetry/tracing.py +58 -14
  136. sentry_sdk/opentelemetry/utils.py +186 -194
  137. sentry_sdk/profiler/continuous_profiler.py +108 -97
  138. sentry_sdk/profiler/transaction_profiler.py +70 -97
  139. sentry_sdk/profiler/utils.py +11 -15
  140. sentry_sdk/scope.py +251 -273
  141. sentry_sdk/scrubber.py +22 -26
  142. sentry_sdk/serializer.py +40 -54
  143. sentry_sdk/session.py +44 -61
  144. sentry_sdk/sessions.py +35 -49
  145. sentry_sdk/spotlight.py +15 -21
  146. sentry_sdk/tracing.py +121 -187
  147. sentry_sdk/tracing_utils.py +104 -122
  148. sentry_sdk/transport.py +131 -157
  149. sentry_sdk/utils.py +232 -309
  150. sentry_sdk/worker.py +16 -28
  151. {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/METADATA +3 -3
  152. sentry_sdk-3.0.0a3.dist-info/RECORD +168 -0
  153. {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/WHEEL +1 -1
  154. sentry_sdk-3.0.0a1.dist-info/RECORD +0 -154
  155. {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/entry_points.txt +0 -0
  156. {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/licenses/LICENSE +0 -0
  157. {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/top_level.txt +0 -0
sentry_sdk/tracing.py CHANGED
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  from datetime import datetime
2
3
  import json
3
4
  import warnings
@@ -15,7 +16,6 @@ from opentelemetry.trace.status import Status, StatusCode
15
16
  from opentelemetry.sdk.trace import ReadableSpan
16
17
  from opentelemetry.version import __version__ as otel_version
17
18
 
18
- import sentry_sdk
19
19
  from sentry_sdk.consts import (
20
20
  DEFAULT_SPAN_NAME,
21
21
  DEFAULT_SPAN_ORIGIN,
@@ -38,7 +38,10 @@ from sentry_sdk.opentelemetry.utils import (
38
38
  get_sentry_meta,
39
39
  serialize_trace_state,
40
40
  )
41
- from sentry_sdk.tracing_utils import get_span_status_from_http_code
41
+ from sentry_sdk.tracing_utils import (
42
+ get_span_status_from_http_code,
43
+ _is_span_origin_excluded,
44
+ )
42
45
  from sentry_sdk.utils import (
43
46
  _serialize_span_attribute,
44
47
  get_current_thread_meta,
@@ -46,29 +49,26 @@ from sentry_sdk.utils import (
46
49
  should_be_treated_as_error,
47
50
  )
48
51
 
49
- from typing import TYPE_CHECKING, cast
50
-
52
+ from typing import TYPE_CHECKING, overload
51
53
 
52
54
  if TYPE_CHECKING:
53
- from collections.abc import Callable
54
- from typing import Any
55
- from typing import Dict
56
- from typing import Iterator
57
- from typing import Optional
58
- from typing import overload
59
- from typing import ParamSpec
60
- from typing import Tuple
61
- from typing import Union
62
- from typing import TypeVar
55
+ from typing import (
56
+ Callable,
57
+ Any,
58
+ Dict,
59
+ Iterator,
60
+ Optional,
61
+ ParamSpec,
62
+ Tuple,
63
+ Union,
64
+ TypeVar,
65
+ )
66
+ from sentry_sdk._types import SamplingContext
67
+ from sentry_sdk.tracing_utils import Baggage
63
68
 
64
69
  P = ParamSpec("P")
65
70
  R = TypeVar("R")
66
71
 
67
- from sentry_sdk._types import (
68
- SamplingContext,
69
- )
70
-
71
- from sentry_sdk.tracing_utils import Baggage
72
72
 
73
73
  _FLAGS_CAPACITY = 10
74
74
  _OTEL_VERSION = parse_version(otel_version)
@@ -77,88 +77,65 @@ tracer = otel_trace.get_tracer(__name__)
77
77
 
78
78
 
79
79
  class NoOpSpan:
80
- def __init__(self, **kwargs):
81
- # type: (Any) -> None
80
+ def __init__(self, **kwargs: Any) -> None:
82
81
  pass
83
82
 
84
- def __repr__(self):
85
- # type: () -> str
83
+ def __repr__(self) -> str:
86
84
  return "<%s>" % self.__class__.__name__
87
85
 
88
86
  @property
89
- def root_span(self):
90
- # type: () -> Optional[Span]
87
+ def root_span(self) -> Optional[Span]:
91
88
  return None
92
89
 
93
- def start_child(self, **kwargs):
94
- # type: (**Any) -> NoOpSpan
90
+ def start_child(self, **kwargs: Any) -> NoOpSpan:
95
91
  return NoOpSpan()
96
92
 
97
- def to_traceparent(self):
98
- # type: () -> str
93
+ def to_traceparent(self) -> str:
99
94
  return ""
100
95
 
101
- def to_baggage(self):
102
- # type: () -> Optional[Baggage]
96
+ def to_baggage(self) -> Optional[Baggage]:
103
97
  return None
104
98
 
105
- def get_baggage(self):
106
- # type: () -> Optional[Baggage]
99
+ def get_baggage(self) -> Optional[Baggage]:
107
100
  return None
108
101
 
109
- def iter_headers(self):
110
- # type: () -> Iterator[Tuple[str, str]]
102
+ def iter_headers(self) -> Iterator[Tuple[str, str]]:
111
103
  return iter(())
112
104
 
113
- def set_tag(self, key, value):
114
- # type: (str, Any) -> None
105
+ def set_tag(self, key: str, value: Any) -> None:
115
106
  pass
116
107
 
117
- def set_data(self, key, value):
118
- # type: (str, Any) -> None
108
+ def set_data(self, key: str, value: Any) -> None:
119
109
  pass
120
110
 
121
- def set_status(self, value):
122
- # type: (str) -> None
111
+ def set_status(self, value: str) -> None:
123
112
  pass
124
113
 
125
- def set_http_status(self, http_status):
126
- # type: (int) -> None
114
+ def set_http_status(self, http_status: int) -> None:
127
115
  pass
128
116
 
129
- def is_success(self):
130
- # type: () -> bool
117
+ def is_success(self) -> bool:
131
118
  return True
132
119
 
133
- def to_json(self):
134
- # type: () -> Dict[str, Any]
120
+ def to_json(self) -> Dict[str, Any]:
135
121
  return {}
136
122
 
137
- def get_trace_context(self):
138
- # type: () -> Any
123
+ def get_trace_context(self) -> Any:
139
124
  return {}
140
125
 
141
- def get_profile_context(self):
142
- # type: () -> Any
126
+ def get_profile_context(self) -> Any:
143
127
  return {}
144
128
 
145
- def finish(
146
- self,
147
- end_timestamp=None, # type: Optional[Union[float, datetime]]
148
- ):
149
- # type: (...) -> None
129
+ def finish(self, end_timestamp: Optional[Union[float, datetime]] = None) -> None:
150
130
  pass
151
131
 
152
- def set_context(self, key, value):
153
- # type: (str, dict[str, Any]) -> None
132
+ def set_context(self, key: str, value: dict[str, Any]) -> None:
154
133
  pass
155
134
 
156
- def init_span_recorder(self, maxlen):
157
- # type: (int) -> None
135
+ def init_span_recorder(self, maxlen: int) -> None:
158
136
  pass
159
137
 
160
- def _set_initial_sampling_decision(self, sampling_context):
161
- # type: (SamplingContext) -> None
138
+ def _set_initial_sampling_decision(self, sampling_context: SamplingContext) -> None:
162
139
  pass
163
140
 
164
141
 
@@ -170,26 +147,25 @@ class Span:
170
147
  def __init__(
171
148
  self,
172
149
  *,
173
- op=None, # type: Optional[str]
174
- description=None, # type: Optional[str]
175
- status=None, # type: Optional[str]
176
- sampled=None, # type: Optional[bool]
177
- start_timestamp=None, # type: Optional[Union[datetime, float]]
178
- origin=None, # type: Optional[str]
179
- name=None, # type: Optional[str]
180
- source=TransactionSource.CUSTOM, # type: str
181
- attributes=None, # type: Optional[dict[str, Any]]
182
- only_if_parent=False, # type: bool
183
- parent_span=None, # type: Optional[Span]
184
- otel_span=None, # type: Optional[OtelSpan]
185
- span=None, # type: Optional[Span]
186
- ):
187
- # type: (...) -> None
150
+ op: Optional[str] = None,
151
+ description: Optional[str] = None,
152
+ status: Optional[str] = None,
153
+ sampled: Optional[bool] = None,
154
+ start_timestamp: Optional[Union[datetime, float]] = None,
155
+ origin: Optional[str] = None,
156
+ name: Optional[str] = None,
157
+ source: str = TransactionSource.CUSTOM,
158
+ attributes: Optional[dict[str, Any]] = None,
159
+ only_if_parent: bool = False,
160
+ parent_span: Optional[Span] = None,
161
+ otel_span: Optional[OtelSpan] = None,
162
+ span: Optional[Span] = None,
163
+ ) -> None:
188
164
  """
189
165
  If otel_span is passed explicitly, just acts as a proxy.
190
166
 
191
167
  If span is passed explicitly, use it. The only purpose of this param
192
- if backwards compatibility with start_transaction(transaction=...).
168
+ is backwards compatibility with start_transaction(transaction=...).
193
169
 
194
170
  If only_if_parent is True, just return an INVALID_SPAN
195
171
  and avoid instrumentation if there's no active parent span.
@@ -206,15 +182,18 @@ class Span:
206
182
  not parent_span_context.is_valid or parent_span_context.is_remote
207
183
  )
208
184
 
185
+ origin = origin or DEFAULT_SPAN_ORIGIN
186
+ if not skip_span and _is_span_origin_excluded(origin):
187
+ skip_span = True
188
+
209
189
  if skip_span:
210
190
  self._otel_span = INVALID_SPAN
211
191
  else:
212
-
213
192
  if start_timestamp is not None:
214
193
  # OTel timestamps have nanosecond precision
215
194
  start_timestamp = convert_to_otel_timestamp(start_timestamp)
216
195
 
217
- span_name = name or description or op or DEFAULT_SPAN_NAME
196
+ span_name = name or description or DEFAULT_SPAN_NAME
218
197
 
219
198
  # Prepopulate some attrs so that they're accessible in traces_sampler
220
199
  attributes = attributes or {}
@@ -240,7 +219,7 @@ class Span:
240
219
  attributes=attributes,
241
220
  )
242
221
 
243
- self.origin = origin or DEFAULT_SPAN_ORIGIN
222
+ self.origin = origin
244
223
  self.description = description
245
224
  self.name = span_name
246
225
 
@@ -249,14 +228,12 @@ class Span:
249
228
 
250
229
  self.update_active_thread()
251
230
 
252
- def __eq__(self, other):
253
- # type: (object) -> bool
231
+ def __eq__(self, other: object) -> bool:
254
232
  if not isinstance(other, Span):
255
233
  return False
256
234
  return self._otel_span == other._otel_span
257
235
 
258
- def __repr__(self):
259
- # type: () -> str
236
+ def __repr__(self) -> str:
260
237
  return (
261
238
  "<%s(op=%r, name:%r, trace_id=%r, span_id=%r, parent_span_id=%r, sampled=%r, origin=%r)>"
262
239
  % (
@@ -271,23 +248,23 @@ class Span:
271
248
  )
272
249
  )
273
250
 
274
- def __enter__(self):
275
- # type: () -> Span
276
- # XXX use_span? https://github.com/open-telemetry/opentelemetry-python/blob/3836da8543ce9751051e38a110c0468724042e62/opentelemetry-api/src/opentelemetry/trace/__init__.py#L547
277
- #
278
- # create a Context object with parent set as current span
251
+ def activate(self) -> None:
279
252
  ctx = otel_trace.set_span_in_context(self._otel_span)
280
253
  # set as the implicit current context
281
254
  self._ctx_token = context.attach(ctx)
282
255
 
283
- # get the new scope that was forked on context.attach
284
- self.scope = sentry_sdk.get_current_scope()
285
- self.scope.span = self
256
+ def deactivate(self) -> None:
257
+ if hasattr(self, "_ctx_token"):
258
+ context.detach(self._ctx_token)
259
+ del self._ctx_token
286
260
 
261
+ def __enter__(self) -> Span:
262
+ self.activate()
287
263
  return self
288
264
 
289
- def __exit__(self, ty, value, tb):
290
- # type: (Optional[Any], Optional[Any], Optional[Any]) -> None
265
+ def __exit__(
266
+ self, ty: Optional[Any], value: Optional[Any], tb: Optional[Any]
267
+ ) -> None:
291
268
  if value is not None and should_be_treated_as_error(ty, value):
292
269
  self.set_status(SPANSTATUS.INTERNAL_ERROR)
293
270
  else:
@@ -299,45 +276,37 @@ class Span:
299
276
  self.set_status(SPANSTATUS.OK)
300
277
 
301
278
  self.finish()
302
- context.detach(self._ctx_token)
303
- del self._ctx_token
279
+ self.deactivate()
304
280
 
305
281
  @property
306
- def description(self):
307
- # type: () -> Optional[str]
282
+ def description(self) -> Optional[str]:
308
283
  return self.get_attribute(SentrySpanAttribute.DESCRIPTION)
309
284
 
310
285
  @description.setter
311
- def description(self, value):
312
- # type: (Optional[str]) -> None
286
+ def description(self, value: Optional[str]) -> None:
313
287
  self.set_attribute(SentrySpanAttribute.DESCRIPTION, value)
314
288
 
315
289
  @property
316
- def origin(self):
317
- # type: () -> Optional[str]
290
+ def origin(self) -> Optional[str]:
318
291
  return self.get_attribute(SentrySpanAttribute.ORIGIN)
319
292
 
320
293
  @origin.setter
321
- def origin(self, value):
322
- # type: (Optional[str]) -> None
294
+ def origin(self, value: Optional[str]) -> None:
323
295
  self.set_attribute(SentrySpanAttribute.ORIGIN, value)
324
296
 
325
297
  @property
326
- def root_span(self):
327
- # type: () -> Optional[Span]
328
- root_otel_span = cast(
329
- "Optional[OtelSpan]", get_sentry_meta(self._otel_span, "root_span")
298
+ def root_span(self) -> Optional[Span]:
299
+ root_otel_span: Optional[OtelSpan] = get_sentry_meta(
300
+ self._otel_span, "root_span"
330
301
  )
331
302
  return Span(otel_span=root_otel_span) if root_otel_span else None
332
303
 
333
304
  @property
334
- def is_root_span(self):
335
- # type: () -> bool
305
+ def is_root_span(self) -> bool:
336
306
  return self.root_span == self
337
307
 
338
308
  @property
339
- def parent_span_id(self):
340
- # type: () -> Optional[str]
309
+ def parent_span_id(self) -> Optional[str]:
341
310
  if (
342
311
  not isinstance(self._otel_span, ReadableSpan)
343
312
  or self._otel_span.parent is None
@@ -346,70 +315,58 @@ class Span:
346
315
  return format_span_id(self._otel_span.parent.span_id)
347
316
 
348
317
  @property
349
- def trace_id(self):
350
- # type: () -> str
318
+ def trace_id(self) -> str:
351
319
  return format_trace_id(self._otel_span.get_span_context().trace_id)
352
320
 
353
321
  @property
354
- def span_id(self):
355
- # type: () -> str
322
+ def span_id(self) -> str:
356
323
  return format_span_id(self._otel_span.get_span_context().span_id)
357
324
 
358
325
  @property
359
- def is_valid(self):
360
- # type: () -> bool
326
+ def is_valid(self) -> bool:
361
327
  return self._otel_span.get_span_context().is_valid and isinstance(
362
328
  self._otel_span, ReadableSpan
363
329
  )
364
330
 
365
331
  @property
366
- def sampled(self):
367
- # type: () -> Optional[bool]
332
+ def sampled(self) -> Optional[bool]:
368
333
  return self._otel_span.get_span_context().trace_flags.sampled
369
334
 
370
335
  @property
371
- def sample_rate(self):
372
- # type: () -> Optional[float]
336
+ def sample_rate(self) -> Optional[float]:
373
337
  sample_rate = self._otel_span.get_span_context().trace_state.get(
374
338
  TRACESTATE_SAMPLE_RATE_KEY
375
339
  )
376
340
  return float(sample_rate) if sample_rate is not None else None
377
341
 
378
342
  @property
379
- def op(self):
380
- # type: () -> Optional[str]
343
+ def op(self) -> Optional[str]:
381
344
  return self.get_attribute(SentrySpanAttribute.OP)
382
345
 
383
346
  @op.setter
384
- def op(self, value):
385
- # type: (Optional[str]) -> None
347
+ def op(self, value: Optional[str]) -> None:
386
348
  self.set_attribute(SentrySpanAttribute.OP, value)
387
349
 
388
350
  @property
389
- def name(self):
390
- # type: () -> Optional[str]
351
+ def name(self) -> Optional[str]:
391
352
  return self.get_attribute(SentrySpanAttribute.NAME)
392
353
 
393
354
  @name.setter
394
- def name(self, value):
395
- # type: (Optional[str]) -> None
355
+ def name(self, value: Optional[str]) -> None:
396
356
  self.set_attribute(SentrySpanAttribute.NAME, value)
397
357
 
398
358
  @property
399
- def source(self):
400
- # type: () -> str
359
+ def source(self) -> str:
401
360
  return (
402
361
  self.get_attribute(SentrySpanAttribute.SOURCE) or TransactionSource.CUSTOM
403
362
  )
404
363
 
405
364
  @source.setter
406
- def source(self, value):
407
- # type: (str) -> None
365
+ def source(self, value: str) -> None:
408
366
  self.set_attribute(SentrySpanAttribute.SOURCE, value)
409
367
 
410
368
  @property
411
- def start_timestamp(self):
412
- # type: () -> Optional[datetime]
369
+ def start_timestamp(self) -> Optional[datetime]:
413
370
  if not isinstance(self._otel_span, ReadableSpan):
414
371
  return None
415
372
 
@@ -420,8 +377,7 @@ class Span:
420
377
  return convert_from_otel_timestamp(start_time)
421
378
 
422
379
  @property
423
- def timestamp(self):
424
- # type: () -> Optional[datetime]
380
+ def timestamp(self) -> Optional[datetime]:
425
381
  if not isinstance(self._otel_span, ReadableSpan):
426
382
  return None
427
383
 
@@ -431,17 +387,14 @@ class Span:
431
387
 
432
388
  return convert_from_otel_timestamp(end_time)
433
389
 
434
- def start_child(self, **kwargs):
435
- # type: (**Any) -> Span
390
+ def start_child(self, **kwargs: Any) -> Span:
436
391
  return Span(parent_span=self, **kwargs)
437
392
 
438
- def iter_headers(self):
439
- # type: () -> Iterator[Tuple[str, str]]
393
+ def iter_headers(self) -> Iterator[Tuple[str, str]]:
440
394
  yield SENTRY_TRACE_HEADER_NAME, self.to_traceparent()
441
395
  yield BAGGAGE_HEADER_NAME, serialize_trace_state(self.trace_state)
442
396
 
443
- def to_traceparent(self):
444
- # type: () -> str
397
+ def to_traceparent(self) -> str:
445
398
  if self.sampled is True:
446
399
  sampled = "1"
447
400
  elif self.sampled is False:
@@ -456,24 +409,19 @@ class Span:
456
409
  return traceparent
457
410
 
458
411
  @property
459
- def trace_state(self):
460
- # type: () -> TraceState
412
+ def trace_state(self) -> TraceState:
461
413
  return get_trace_state(self._otel_span)
462
414
 
463
- def to_baggage(self):
464
- # type: () -> Baggage
415
+ def to_baggage(self) -> Baggage:
465
416
  return self.get_baggage()
466
417
 
467
- def get_baggage(self):
468
- # type: () -> Baggage
418
+ def get_baggage(self) -> Baggage:
469
419
  return baggage_from_trace_state(self.trace_state)
470
420
 
471
- def set_tag(self, key, value):
472
- # type: (str, Any) -> None
421
+ def set_tag(self, key: str, value: Any) -> None:
473
422
  self.set_attribute(f"{SentrySpanAttribute.TAG}.{key}", value)
474
423
 
475
- def set_data(self, key, value):
476
- # type: (str, Any) -> None
424
+ def set_data(self, key: str, value: Any) -> None:
477
425
  warnings.warn(
478
426
  "`Span.set_data` is deprecated. Please use `Span.set_attribute` instead.",
479
427
  DeprecationWarning,
@@ -483,8 +431,7 @@ class Span:
483
431
  # TODO-neel-potel we cannot add dicts here
484
432
  self.set_attribute(key, value)
485
433
 
486
- def get_attribute(self, name):
487
- # type: (str) -> Optional[Any]
434
+ def get_attribute(self, name: str) -> Optional[Any]:
488
435
  if (
489
436
  not isinstance(self._otel_span, ReadableSpan)
490
437
  or not self._otel_span.attributes
@@ -492,8 +439,7 @@ class Span:
492
439
  return None
493
440
  return self._otel_span.attributes.get(name)
494
441
 
495
- def set_attribute(self, key, value):
496
- # type: (str, Any) -> None
442
+ def set_attribute(self, key: str, value: Any) -> None:
497
443
  # otel doesn't support None as values, preferring to not set the key
498
444
  # at all instead
499
445
  if value is None:
@@ -505,8 +451,7 @@ class Span:
505
451
  self._otel_span.set_attribute(key, serialized_value)
506
452
 
507
453
  @property
508
- def status(self):
509
- # type: () -> Optional[str]
454
+ def status(self) -> Optional[str]:
510
455
  """
511
456
  Return the Sentry `SPANSTATUS` corresponding to the underlying OTel status.
512
457
  Because differences in possible values in OTel `StatusCode` and
@@ -523,8 +468,7 @@ class Span:
523
468
  else:
524
469
  return SPANSTATUS.UNKNOWN_ERROR
525
470
 
526
- def set_status(self, status):
527
- # type: (str) -> None
471
+ def set_status(self, status: str) -> None:
528
472
  if status == SPANSTATUS.OK:
529
473
  otel_status = StatusCode.OK
530
474
  otel_description = None
@@ -537,37 +481,31 @@ class Span:
537
481
  else:
538
482
  self._otel_span.set_status(Status(otel_status, otel_description))
539
483
 
540
- def set_thread(self, thread_id, thread_name):
541
- # type: (Optional[int], Optional[str]) -> None
484
+ def set_thread(self, thread_id: Optional[int], thread_name: Optional[str]) -> None:
542
485
  if thread_id is not None:
543
486
  self.set_attribute(SPANDATA.THREAD_ID, str(thread_id))
544
487
 
545
488
  if thread_name is not None:
546
489
  self.set_attribute(SPANDATA.THREAD_NAME, thread_name)
547
490
 
548
- def update_active_thread(self):
549
- # type: () -> None
491
+ def update_active_thread(self) -> None:
550
492
  thread_id, thread_name = get_current_thread_meta()
551
493
  self.set_thread(thread_id, thread_name)
552
494
 
553
- def set_http_status(self, http_status):
554
- # type: (int) -> None
495
+ def set_http_status(self, http_status: int) -> None:
555
496
  self.set_attribute(SPANDATA.HTTP_STATUS_CODE, http_status)
556
497
  self.set_status(get_span_status_from_http_code(http_status))
557
498
 
558
- def is_success(self):
559
- # type: () -> bool
499
+ def is_success(self) -> bool:
560
500
  return self.status == SPANSTATUS.OK
561
501
 
562
- def finish(self, end_timestamp=None):
563
- # type: (Optional[Union[float, datetime]]) -> None
502
+ def finish(self, end_timestamp: Optional[Union[float, datetime]] = None) -> None:
564
503
  if end_timestamp is not None:
565
504
  self._otel_span.end(convert_to_otel_timestamp(end_timestamp))
566
505
  else:
567
506
  self._otel_span.end()
568
507
 
569
- def to_json(self):
570
- # type: () -> dict[str, Any]
508
+ def to_json(self) -> dict[str, Any]:
571
509
  """
572
510
  Only meant for testing. Not used internally anymore.
573
511
  """
@@ -575,21 +513,18 @@ class Span:
575
513
  return {}
576
514
  return json.loads(self._otel_span.to_json())
577
515
 
578
- def get_trace_context(self):
579
- # type: () -> dict[str, Any]
516
+ def get_trace_context(self) -> dict[str, Any]:
580
517
  if not isinstance(self._otel_span, ReadableSpan):
581
518
  return {}
582
519
 
583
520
  return get_trace_context(self._otel_span)
584
521
 
585
- def set_context(self, key, value):
586
- # type: (str, Any) -> None
522
+ def set_context(self, key: str, value: Any) -> None:
587
523
  # TODO-neel-potel we cannot add dicts here
588
524
 
589
525
  self.set_attribute(f"{SentrySpanAttribute.CONTEXT}.{key}", value)
590
526
 
591
- def set_flag(self, flag, value):
592
- # type: (str, bool) -> None
527
+ def set_flag(self, flag: str, value: bool) -> None:
593
528
  flag_count = self.get_attribute("_flag.count") or 0
594
529
  if flag_count < _FLAGS_CAPACITY:
595
530
  self.set_attribute(f"flag.evaluation.{flag}", value)
@@ -603,18 +538,17 @@ Transaction = Span
603
538
  if TYPE_CHECKING:
604
539
 
605
540
  @overload
606
- def trace(func=None):
607
- # type: (None) -> Callable[[Callable[P, R]], Callable[P, R]]
541
+ def trace(func: None = None) -> Callable[[Callable[P, R]], Callable[P, R]]:
608
542
  pass
609
543
 
610
544
  @overload
611
- def trace(func):
612
- # type: (Callable[P, R]) -> Callable[P, R]
545
+ def trace(func: Callable[P, R]) -> Callable[P, R]:
613
546
  pass
614
547
 
615
548
 
616
- def trace(func=None):
617
- # type: (Optional[Callable[P, R]]) -> Union[Callable[P, R], Callable[[Callable[P, R]], Callable[P, R]]]
549
+ def trace(
550
+ func: Optional[Callable[P, R]] = None,
551
+ ) -> Union[Callable[P, R], Callable[[Callable[P, R]], Callable[P, R]]]:
618
552
  """
619
553
  Decorator to start a child span under the existing current transaction.
620
554
  If there is no current transaction, then nothing will be traced.