sentry-sdk 0.18.0__py2.py3-none-any.whl → 2.46.0__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.
Files changed (193) hide show
  1. sentry_sdk/__init__.py +48 -6
  2. sentry_sdk/_compat.py +64 -56
  3. sentry_sdk/_init_implementation.py +84 -0
  4. sentry_sdk/_log_batcher.py +172 -0
  5. sentry_sdk/_lru_cache.py +47 -0
  6. sentry_sdk/_metrics_batcher.py +167 -0
  7. sentry_sdk/_queue.py +81 -19
  8. sentry_sdk/_types.py +311 -11
  9. sentry_sdk/_werkzeug.py +98 -0
  10. sentry_sdk/ai/__init__.py +7 -0
  11. sentry_sdk/ai/monitoring.py +137 -0
  12. sentry_sdk/ai/utils.py +144 -0
  13. sentry_sdk/api.py +409 -67
  14. sentry_sdk/attachments.py +75 -0
  15. sentry_sdk/client.py +849 -103
  16. sentry_sdk/consts.py +1389 -34
  17. sentry_sdk/crons/__init__.py +10 -0
  18. sentry_sdk/crons/api.py +62 -0
  19. sentry_sdk/crons/consts.py +4 -0
  20. sentry_sdk/crons/decorator.py +135 -0
  21. sentry_sdk/debug.py +12 -15
  22. sentry_sdk/envelope.py +112 -61
  23. sentry_sdk/feature_flags.py +71 -0
  24. sentry_sdk/hub.py +442 -386
  25. sentry_sdk/integrations/__init__.py +228 -58
  26. sentry_sdk/integrations/_asgi_common.py +108 -0
  27. sentry_sdk/integrations/_wsgi_common.py +131 -40
  28. sentry_sdk/integrations/aiohttp.py +221 -72
  29. sentry_sdk/integrations/anthropic.py +439 -0
  30. sentry_sdk/integrations/argv.py +4 -6
  31. sentry_sdk/integrations/ariadne.py +161 -0
  32. sentry_sdk/integrations/arq.py +247 -0
  33. sentry_sdk/integrations/asgi.py +237 -135
  34. sentry_sdk/integrations/asyncio.py +144 -0
  35. sentry_sdk/integrations/asyncpg.py +208 -0
  36. sentry_sdk/integrations/atexit.py +13 -18
  37. sentry_sdk/integrations/aws_lambda.py +233 -80
  38. sentry_sdk/integrations/beam.py +27 -35
  39. sentry_sdk/integrations/boto3.py +137 -0
  40. sentry_sdk/integrations/bottle.py +91 -69
  41. sentry_sdk/integrations/celery/__init__.py +529 -0
  42. sentry_sdk/integrations/celery/beat.py +293 -0
  43. sentry_sdk/integrations/celery/utils.py +43 -0
  44. sentry_sdk/integrations/chalice.py +35 -28
  45. sentry_sdk/integrations/clickhouse_driver.py +177 -0
  46. sentry_sdk/integrations/cloud_resource_context.py +280 -0
  47. sentry_sdk/integrations/cohere.py +274 -0
  48. sentry_sdk/integrations/dedupe.py +32 -8
  49. sentry_sdk/integrations/django/__init__.py +343 -89
  50. sentry_sdk/integrations/django/asgi.py +201 -22
  51. sentry_sdk/integrations/django/caching.py +204 -0
  52. sentry_sdk/integrations/django/middleware.py +80 -32
  53. sentry_sdk/integrations/django/signals_handlers.py +91 -0
  54. sentry_sdk/integrations/django/templates.py +69 -2
  55. sentry_sdk/integrations/django/transactions.py +39 -14
  56. sentry_sdk/integrations/django/views.py +69 -16
  57. sentry_sdk/integrations/dramatiq.py +226 -0
  58. sentry_sdk/integrations/excepthook.py +19 -13
  59. sentry_sdk/integrations/executing.py +5 -6
  60. sentry_sdk/integrations/falcon.py +128 -65
  61. sentry_sdk/integrations/fastapi.py +141 -0
  62. sentry_sdk/integrations/flask.py +114 -75
  63. sentry_sdk/integrations/gcp.py +67 -36
  64. sentry_sdk/integrations/gnu_backtrace.py +14 -22
  65. sentry_sdk/integrations/google_genai/__init__.py +301 -0
  66. sentry_sdk/integrations/google_genai/consts.py +16 -0
  67. sentry_sdk/integrations/google_genai/streaming.py +155 -0
  68. sentry_sdk/integrations/google_genai/utils.py +576 -0
  69. sentry_sdk/integrations/gql.py +162 -0
  70. sentry_sdk/integrations/graphene.py +151 -0
  71. sentry_sdk/integrations/grpc/__init__.py +168 -0
  72. sentry_sdk/integrations/grpc/aio/__init__.py +7 -0
  73. sentry_sdk/integrations/grpc/aio/client.py +95 -0
  74. sentry_sdk/integrations/grpc/aio/server.py +100 -0
  75. sentry_sdk/integrations/grpc/client.py +91 -0
  76. sentry_sdk/integrations/grpc/consts.py +1 -0
  77. sentry_sdk/integrations/grpc/server.py +66 -0
  78. sentry_sdk/integrations/httpx.py +178 -0
  79. sentry_sdk/integrations/huey.py +174 -0
  80. sentry_sdk/integrations/huggingface_hub.py +378 -0
  81. sentry_sdk/integrations/langchain.py +1132 -0
  82. sentry_sdk/integrations/langgraph.py +337 -0
  83. sentry_sdk/integrations/launchdarkly.py +61 -0
  84. sentry_sdk/integrations/litellm.py +287 -0
  85. sentry_sdk/integrations/litestar.py +315 -0
  86. sentry_sdk/integrations/logging.py +261 -85
  87. sentry_sdk/integrations/loguru.py +213 -0
  88. sentry_sdk/integrations/mcp.py +566 -0
  89. sentry_sdk/integrations/modules.py +6 -33
  90. sentry_sdk/integrations/openai.py +725 -0
  91. sentry_sdk/integrations/openai_agents/__init__.py +61 -0
  92. sentry_sdk/integrations/openai_agents/consts.py +1 -0
  93. sentry_sdk/integrations/openai_agents/patches/__init__.py +5 -0
  94. sentry_sdk/integrations/openai_agents/patches/agent_run.py +140 -0
  95. sentry_sdk/integrations/openai_agents/patches/error_tracing.py +77 -0
  96. sentry_sdk/integrations/openai_agents/patches/models.py +50 -0
  97. sentry_sdk/integrations/openai_agents/patches/runner.py +45 -0
  98. sentry_sdk/integrations/openai_agents/patches/tools.py +77 -0
  99. sentry_sdk/integrations/openai_agents/spans/__init__.py +5 -0
  100. sentry_sdk/integrations/openai_agents/spans/agent_workflow.py +21 -0
  101. sentry_sdk/integrations/openai_agents/spans/ai_client.py +42 -0
  102. sentry_sdk/integrations/openai_agents/spans/execute_tool.py +48 -0
  103. sentry_sdk/integrations/openai_agents/spans/handoff.py +19 -0
  104. sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +86 -0
  105. sentry_sdk/integrations/openai_agents/utils.py +199 -0
  106. sentry_sdk/integrations/openfeature.py +35 -0
  107. sentry_sdk/integrations/opentelemetry/__init__.py +7 -0
  108. sentry_sdk/integrations/opentelemetry/consts.py +5 -0
  109. sentry_sdk/integrations/opentelemetry/integration.py +58 -0
  110. sentry_sdk/integrations/opentelemetry/propagator.py +117 -0
  111. sentry_sdk/integrations/opentelemetry/span_processor.py +391 -0
  112. sentry_sdk/integrations/otlp.py +82 -0
  113. sentry_sdk/integrations/pure_eval.py +20 -11
  114. sentry_sdk/integrations/pydantic_ai/__init__.py +47 -0
  115. sentry_sdk/integrations/pydantic_ai/consts.py +1 -0
  116. sentry_sdk/integrations/pydantic_ai/patches/__init__.py +4 -0
  117. sentry_sdk/integrations/pydantic_ai/patches/agent_run.py +215 -0
  118. sentry_sdk/integrations/pydantic_ai/patches/graph_nodes.py +110 -0
  119. sentry_sdk/integrations/pydantic_ai/patches/model_request.py +40 -0
  120. sentry_sdk/integrations/pydantic_ai/patches/tools.py +98 -0
  121. sentry_sdk/integrations/pydantic_ai/spans/__init__.py +3 -0
  122. sentry_sdk/integrations/pydantic_ai/spans/ai_client.py +246 -0
  123. sentry_sdk/integrations/pydantic_ai/spans/execute_tool.py +49 -0
  124. sentry_sdk/integrations/pydantic_ai/spans/invoke_agent.py +112 -0
  125. sentry_sdk/integrations/pydantic_ai/utils.py +223 -0
  126. sentry_sdk/integrations/pymongo.py +214 -0
  127. sentry_sdk/integrations/pyramid.py +71 -60
  128. sentry_sdk/integrations/quart.py +237 -0
  129. sentry_sdk/integrations/ray.py +165 -0
  130. sentry_sdk/integrations/redis/__init__.py +48 -0
  131. sentry_sdk/integrations/redis/_async_common.py +116 -0
  132. sentry_sdk/integrations/redis/_sync_common.py +119 -0
  133. sentry_sdk/integrations/redis/consts.py +19 -0
  134. sentry_sdk/integrations/redis/modules/__init__.py +0 -0
  135. sentry_sdk/integrations/redis/modules/caches.py +118 -0
  136. sentry_sdk/integrations/redis/modules/queries.py +65 -0
  137. sentry_sdk/integrations/redis/rb.py +32 -0
  138. sentry_sdk/integrations/redis/redis.py +69 -0
  139. sentry_sdk/integrations/redis/redis_cluster.py +107 -0
  140. sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +50 -0
  141. sentry_sdk/integrations/redis/utils.py +148 -0
  142. sentry_sdk/integrations/rq.py +62 -52
  143. sentry_sdk/integrations/rust_tracing.py +284 -0
  144. sentry_sdk/integrations/sanic.py +248 -114
  145. sentry_sdk/integrations/serverless.py +13 -22
  146. sentry_sdk/integrations/socket.py +96 -0
  147. sentry_sdk/integrations/spark/spark_driver.py +115 -62
  148. sentry_sdk/integrations/spark/spark_worker.py +42 -50
  149. sentry_sdk/integrations/sqlalchemy.py +82 -37
  150. sentry_sdk/integrations/starlette.py +737 -0
  151. sentry_sdk/integrations/starlite.py +292 -0
  152. sentry_sdk/integrations/statsig.py +37 -0
  153. sentry_sdk/integrations/stdlib.py +100 -58
  154. sentry_sdk/integrations/strawberry.py +394 -0
  155. sentry_sdk/integrations/sys_exit.py +70 -0
  156. sentry_sdk/integrations/threading.py +142 -38
  157. sentry_sdk/integrations/tornado.py +68 -53
  158. sentry_sdk/integrations/trytond.py +15 -20
  159. sentry_sdk/integrations/typer.py +60 -0
  160. sentry_sdk/integrations/unleash.py +33 -0
  161. sentry_sdk/integrations/unraisablehook.py +53 -0
  162. sentry_sdk/integrations/wsgi.py +126 -125
  163. sentry_sdk/logger.py +96 -0
  164. sentry_sdk/metrics.py +81 -0
  165. sentry_sdk/monitor.py +120 -0
  166. sentry_sdk/profiler/__init__.py +49 -0
  167. sentry_sdk/profiler/continuous_profiler.py +730 -0
  168. sentry_sdk/profiler/transaction_profiler.py +839 -0
  169. sentry_sdk/profiler/utils.py +195 -0
  170. sentry_sdk/scope.py +1542 -112
  171. sentry_sdk/scrubber.py +177 -0
  172. sentry_sdk/serializer.py +152 -210
  173. sentry_sdk/session.py +177 -0
  174. sentry_sdk/sessions.py +202 -179
  175. sentry_sdk/spotlight.py +242 -0
  176. sentry_sdk/tracing.py +1202 -294
  177. sentry_sdk/tracing_utils.py +1236 -0
  178. sentry_sdk/transport.py +693 -189
  179. sentry_sdk/types.py +52 -0
  180. sentry_sdk/utils.py +1395 -228
  181. sentry_sdk/worker.py +30 -17
  182. sentry_sdk-2.46.0.dist-info/METADATA +268 -0
  183. sentry_sdk-2.46.0.dist-info/RECORD +189 -0
  184. {sentry_sdk-0.18.0.dist-info → sentry_sdk-2.46.0.dist-info}/WHEEL +1 -1
  185. sentry_sdk-2.46.0.dist-info/entry_points.txt +2 -0
  186. sentry_sdk-2.46.0.dist-info/licenses/LICENSE +21 -0
  187. sentry_sdk/_functools.py +0 -66
  188. sentry_sdk/integrations/celery.py +0 -275
  189. sentry_sdk/integrations/redis.py +0 -103
  190. sentry_sdk-0.18.0.dist-info/LICENSE +0 -9
  191. sentry_sdk-0.18.0.dist-info/METADATA +0 -66
  192. sentry_sdk-0.18.0.dist-info/RECORD +0 -65
  193. {sentry_sdk-0.18.0.dist-info → sentry_sdk-2.46.0.dist-info}/top_level.txt +0 -0
sentry_sdk/api.py CHANGED
@@ -1,13 +1,22 @@
1
1
  import inspect
2
+ import warnings
3
+ from contextlib import contextmanager
2
4
 
3
- from sentry_sdk.hub import Hub
4
- from sentry_sdk.scope import Scope
5
+ from sentry_sdk import tracing_utils, Client
6
+ from sentry_sdk._init_implementation import init
7
+ from sentry_sdk.consts import INSTRUMENTER
8
+ from sentry_sdk.scope import Scope, _ScopeManager, new_scope, isolation_scope
9
+ from sentry_sdk.tracing import NoOpSpan, Transaction, trace
10
+ from sentry_sdk.crons import monitor
5
11
 
6
- from sentry_sdk._types import MYPY
12
+ from typing import TYPE_CHECKING
13
+
14
+ if TYPE_CHECKING:
15
+ from collections.abc import Mapping
7
16
 
8
- if MYPY:
9
17
  from typing import Any
10
18
  from typing import Dict
19
+ from typing import Generator
11
20
  from typing import Optional
12
21
  from typing import overload
13
22
  from typing import Callable
@@ -15,8 +24,20 @@ if MYPY:
15
24
  from typing import ContextManager
16
25
  from typing import Union
17
26
 
18
- from sentry_sdk._types import Event, Hint, Breadcrumb, BreadcrumbHint, ExcInfo
19
- from sentry_sdk.tracing import Span, Transaction
27
+ from typing_extensions import Unpack
28
+
29
+ from sentry_sdk.client import BaseClient
30
+ from sentry_sdk._types import (
31
+ Event,
32
+ Hint,
33
+ Breadcrumb,
34
+ BreadcrumbHint,
35
+ ExcInfo,
36
+ MeasurementUnit,
37
+ LogLevelStr,
38
+ SamplingContext,
39
+ )
40
+ from sentry_sdk.tracing import Span, TransactionKwargs
20
41
 
21
42
  T = TypeVar("T")
22
43
  F = TypeVar("F", bound=Callable[..., Any])
@@ -27,87 +48,173 @@ else:
27
48
  return x
28
49
 
29
50
 
51
+ # When changing this, update __all__ in __init__.py too
30
52
  __all__ = [
53
+ "init",
54
+ "add_attachment",
55
+ "add_breadcrumb",
31
56
  "capture_event",
32
- "capture_message",
33
57
  "capture_exception",
34
- "add_breadcrumb",
58
+ "capture_message",
35
59
  "configure_scope",
36
- "push_scope",
60
+ "continue_trace",
37
61
  "flush",
62
+ "get_baggage",
63
+ "get_client",
64
+ "get_global_scope",
65
+ "get_isolation_scope",
66
+ "get_current_scope",
67
+ "get_current_span",
68
+ "get_traceparent",
69
+ "is_initialized",
70
+ "isolation_scope",
38
71
  "last_event_id",
39
- "start_span",
40
- "start_transaction",
41
- "set_tag",
72
+ "new_scope",
73
+ "push_scope",
42
74
  "set_context",
43
75
  "set_extra",
44
- "set_user",
45
76
  "set_level",
77
+ "set_measurement",
78
+ "set_tag",
79
+ "set_tags",
80
+ "set_user",
81
+ "start_span",
82
+ "start_transaction",
83
+ "trace",
84
+ "monitor",
85
+ "start_session",
86
+ "end_session",
87
+ "set_transaction_name",
88
+ "update_current_span",
46
89
  ]
47
90
 
48
91
 
49
- def hubmethod(f):
92
+ def scopemethod(f):
50
93
  # type: (F) -> F
51
94
  f.__doc__ = "%s\n\n%s" % (
52
- "Alias for :py:meth:`sentry_sdk.Hub.%s`" % f.__name__,
53
- inspect.getdoc(getattr(Hub, f.__name__)),
95
+ "Alias for :py:meth:`sentry_sdk.Scope.%s`" % f.__name__,
96
+ inspect.getdoc(getattr(Scope, f.__name__)),
54
97
  )
55
98
  return f
56
99
 
57
100
 
58
- def scopemethod(f):
101
+ def clientmethod(f):
59
102
  # type: (F) -> F
60
103
  f.__doc__ = "%s\n\n%s" % (
61
- "Alias for :py:meth:`sentry_sdk.Scope.%s`" % f.__name__,
62
- inspect.getdoc(getattr(Scope, f.__name__)),
104
+ "Alias for :py:meth:`sentry_sdk.Client.%s`" % f.__name__,
105
+ inspect.getdoc(getattr(Client, f.__name__)),
63
106
  )
64
107
  return f
65
108
 
66
109
 
67
- @hubmethod
110
+ @scopemethod
111
+ def get_client():
112
+ # type: () -> BaseClient
113
+ return Scope.get_client()
114
+
115
+
116
+ def is_initialized():
117
+ # type: () -> bool
118
+ """
119
+ .. versionadded:: 2.0.0
120
+
121
+ Returns whether Sentry has been initialized or not.
122
+
123
+ If a client is available and the client is active
124
+ (meaning it is configured to send data) then
125
+ Sentry is initialized.
126
+ """
127
+ return get_client().is_active()
128
+
129
+
130
+ @scopemethod
131
+ def get_global_scope():
132
+ # type: () -> Scope
133
+ return Scope.get_global_scope()
134
+
135
+
136
+ @scopemethod
137
+ def get_isolation_scope():
138
+ # type: () -> Scope
139
+ return Scope.get_isolation_scope()
140
+
141
+
142
+ @scopemethod
143
+ def get_current_scope():
144
+ # type: () -> Scope
145
+ return Scope.get_current_scope()
146
+
147
+
148
+ @scopemethod
149
+ def last_event_id():
150
+ # type: () -> Optional[str]
151
+ """
152
+ See :py:meth:`sentry_sdk.Scope.last_event_id` documentation regarding
153
+ this method's limitations.
154
+ """
155
+ return Scope.last_event_id()
156
+
157
+
158
+ @scopemethod
68
159
  def capture_event(
69
160
  event, # type: Event
70
161
  hint=None, # type: Optional[Hint]
71
162
  scope=None, # type: Optional[Any]
72
- **scope_args # type: Dict[str, Any]
163
+ **scope_kwargs, # type: Any
73
164
  ):
74
165
  # type: (...) -> Optional[str]
75
- return Hub.current.capture_event(event, hint, scope=scope, **scope_args)
166
+ return get_current_scope().capture_event(event, hint, scope=scope, **scope_kwargs)
76
167
 
77
168
 
78
- @hubmethod
169
+ @scopemethod
79
170
  def capture_message(
80
171
  message, # type: str
81
- level=None, # type: Optional[str]
172
+ level=None, # type: Optional[LogLevelStr]
82
173
  scope=None, # type: Optional[Any]
83
- **scope_args # type: Dict[str, Any]
174
+ **scope_kwargs, # type: Any
84
175
  ):
85
176
  # type: (...) -> Optional[str]
86
- return Hub.current.capture_message(message, level, scope=scope, **scope_args)
177
+ return get_current_scope().capture_message(
178
+ message, level, scope=scope, **scope_kwargs
179
+ )
87
180
 
88
181
 
89
- @hubmethod
182
+ @scopemethod
90
183
  def capture_exception(
91
184
  error=None, # type: Optional[Union[BaseException, ExcInfo]]
92
185
  scope=None, # type: Optional[Any]
93
- **scope_args # type: Dict[str, Any]
186
+ **scope_kwargs, # type: Any
94
187
  ):
95
188
  # type: (...) -> Optional[str]
96
- return Hub.current.capture_exception(error, scope=scope, **scope_args)
189
+ return get_current_scope().capture_exception(error, scope=scope, **scope_kwargs)
97
190
 
98
191
 
99
- @hubmethod
192
+ @scopemethod
193
+ def add_attachment(
194
+ bytes=None, # type: Union[None, bytes, Callable[[], bytes]]
195
+ filename=None, # type: Optional[str]
196
+ path=None, # type: Optional[str]
197
+ content_type=None, # type: Optional[str]
198
+ add_to_transactions=False, # type: bool
199
+ ):
200
+ # type: (...) -> None
201
+ return get_isolation_scope().add_attachment(
202
+ bytes, filename, path, content_type, add_to_transactions
203
+ )
204
+
205
+
206
+ @scopemethod
100
207
  def add_breadcrumb(
101
208
  crumb=None, # type: Optional[Breadcrumb]
102
209
  hint=None, # type: Optional[BreadcrumbHint]
103
- **kwargs # type: Any
210
+ **kwargs, # type: Any
104
211
  ):
105
212
  # type: (...) -> None
106
- return Hub.current.add_breadcrumb(crumb, hint, **kwargs)
213
+ return get_isolation_scope().add_breadcrumb(crumb, hint, **kwargs)
107
214
 
108
215
 
109
216
  @overload
110
- def configure_scope(): # noqa: F811
217
+ def configure_scope():
111
218
  # type: () -> ContextManager[Scope]
112
219
  pass
113
220
 
@@ -120,16 +227,44 @@ def configure_scope( # noqa: F811
120
227
  pass
121
228
 
122
229
 
123
- @hubmethod
124
230
  def configure_scope( # noqa: F811
125
231
  callback=None, # type: Optional[Callable[[Scope], None]]
126
232
  ):
127
233
  # type: (...) -> Optional[ContextManager[Scope]]
128
- return Hub.current.configure_scope(callback)
234
+ """
235
+ Reconfigures the scope.
236
+
237
+ :param callback: If provided, call the callback with the current scope.
238
+
239
+ :returns: If no callback is provided, returns a context manager that returns the scope.
240
+ """
241
+ warnings.warn(
242
+ "sentry_sdk.configure_scope is deprecated and will be removed in the next major version. "
243
+ "Please consult our migration guide to learn how to migrate to the new API: "
244
+ "https://docs.sentry.io/platforms/python/migration/1.x-to-2.x#scope-configuring",
245
+ DeprecationWarning,
246
+ stacklevel=2,
247
+ )
248
+
249
+ scope = get_isolation_scope()
250
+ scope.generate_propagation_context()
251
+
252
+ if callback is not None:
253
+ # TODO: used to return None when client is None. Check if this changes behavior.
254
+ callback(scope)
255
+
256
+ return None
257
+
258
+ @contextmanager
259
+ def inner():
260
+ # type: () -> Generator[Scope, None, None]
261
+ yield scope
262
+
263
+ return inner()
129
264
 
130
265
 
131
266
  @overload
132
- def push_scope(): # noqa: F811
267
+ def push_scope():
133
268
  # type: () -> ContextManager[Scope]
134
269
  pass
135
270
 
@@ -142,72 +277,279 @@ def push_scope( # noqa: F811
142
277
  pass
143
278
 
144
279
 
145
- @hubmethod
146
280
  def push_scope( # noqa: F811
147
281
  callback=None, # type: Optional[Callable[[Scope], None]]
148
282
  ):
149
283
  # type: (...) -> Optional[ContextManager[Scope]]
150
- return Hub.current.push_scope(callback)
284
+ """
285
+ Pushes a new layer on the scope stack.
286
+
287
+ :param callback: If provided, this method pushes a scope, calls
288
+ `callback`, and pops the scope again.
289
+
290
+ :returns: If no `callback` is provided, a context manager that should
291
+ be used to pop the scope again.
292
+ """
293
+ warnings.warn(
294
+ "sentry_sdk.push_scope is deprecated and will be removed in the next major version. "
295
+ "Please consult our migration guide to learn how to migrate to the new API: "
296
+ "https://docs.sentry.io/platforms/python/migration/1.x-to-2.x#scope-pushing",
297
+ DeprecationWarning,
298
+ stacklevel=2,
299
+ )
300
+
301
+ if callback is not None:
302
+ with warnings.catch_warnings():
303
+ warnings.simplefilter("ignore", DeprecationWarning)
304
+ with push_scope() as scope:
305
+ callback(scope)
306
+ return None
151
307
 
308
+ return _ScopeManager()
152
309
 
153
- @scopemethod # noqa
310
+
311
+ @scopemethod
154
312
  def set_tag(key, value):
155
313
  # type: (str, Any) -> None
156
- return Hub.current.scope.set_tag(key, value)
314
+ return get_isolation_scope().set_tag(key, value)
315
+
157
316
 
317
+ @scopemethod
318
+ def set_tags(tags):
319
+ # type: (Mapping[str, object]) -> None
320
+ return get_isolation_scope().set_tags(tags)
158
321
 
159
- @scopemethod # noqa
322
+
323
+ @scopemethod
160
324
  def set_context(key, value):
161
- # type: (str, Any) -> None
162
- return Hub.current.scope.set_context(key, value)
325
+ # type: (str, Dict[str, Any]) -> None
326
+ return get_isolation_scope().set_context(key, value)
163
327
 
164
328
 
165
- @scopemethod # noqa
329
+ @scopemethod
166
330
  def set_extra(key, value):
167
331
  # type: (str, Any) -> None
168
- return Hub.current.scope.set_extra(key, value)
332
+ return get_isolation_scope().set_extra(key, value)
169
333
 
170
334
 
171
- @scopemethod # noqa
335
+ @scopemethod
172
336
  def set_user(value):
173
- # type: (Dict[str, Any]) -> None
174
- return Hub.current.scope.set_user(value)
337
+ # type: (Optional[Dict[str, Any]]) -> None
338
+ return get_isolation_scope().set_user(value)
175
339
 
176
340
 
177
- @scopemethod # noqa
341
+ @scopemethod
178
342
  def set_level(value):
179
- # type: (str) -> None
180
- return Hub.current.scope.set_level(value)
343
+ # type: (LogLevelStr) -> None
344
+ return get_isolation_scope().set_level(value)
181
345
 
182
346
 
183
- @hubmethod
347
+ @clientmethod
184
348
  def flush(
185
349
  timeout=None, # type: Optional[float]
186
350
  callback=None, # type: Optional[Callable[[int, float], None]]
187
351
  ):
188
352
  # type: (...) -> None
189
- return Hub.current.flush(timeout=timeout, callback=callback)
353
+ return get_client().flush(timeout=timeout, callback=callback)
190
354
 
191
355
 
192
- @hubmethod
193
- def last_event_id():
194
- # type: () -> Optional[str]
195
- return Hub.current.last_event_id()
196
-
197
-
198
- @hubmethod
356
+ @scopemethod
199
357
  def start_span(
200
- span=None, # type: Optional[Span]
201
- **kwargs # type: Any
358
+ **kwargs, # type: Any
202
359
  ):
203
360
  # type: (...) -> Span
204
- return Hub.current.start_span(span=span, **kwargs)
361
+ return get_current_scope().start_span(**kwargs)
205
362
 
206
363
 
207
- @hubmethod
364
+ @scopemethod
208
365
  def start_transaction(
209
366
  transaction=None, # type: Optional[Transaction]
210
- **kwargs # type: Any
367
+ instrumenter=INSTRUMENTER.SENTRY, # type: str
368
+ custom_sampling_context=None, # type: Optional[SamplingContext]
369
+ **kwargs, # type: Unpack[TransactionKwargs]
370
+ ):
371
+ # type: (...) -> Union[Transaction, NoOpSpan]
372
+ """
373
+ Start and return a transaction on the current scope.
374
+
375
+ Start an existing transaction if given, otherwise create and start a new
376
+ transaction with kwargs.
377
+
378
+ This is the entry point to manual tracing instrumentation.
379
+
380
+ A tree structure can be built by adding child spans to the transaction,
381
+ and child spans to other spans. To start a new child span within the
382
+ transaction or any span, call the respective `.start_child()` method.
383
+
384
+ Every child span must be finished before the transaction is finished,
385
+ otherwise the unfinished spans are discarded.
386
+
387
+ When used as context managers, spans and transactions are automatically
388
+ finished at the end of the `with` block. If not using context managers,
389
+ call the `.finish()` method.
390
+
391
+ When the transaction is finished, it will be sent to Sentry with all its
392
+ finished child spans.
393
+
394
+ :param transaction: The transaction to start. If omitted, we create and
395
+ start a new transaction.
396
+ :param instrumenter: This parameter is meant for internal use only. It
397
+ will be removed in the next major version.
398
+ :param custom_sampling_context: The transaction's custom sampling context.
399
+ :param kwargs: Optional keyword arguments to be passed to the Transaction
400
+ constructor. See :py:class:`sentry_sdk.tracing.Transaction` for
401
+ available arguments.
402
+ """
403
+ return get_current_scope().start_transaction(
404
+ transaction, instrumenter, custom_sampling_context, **kwargs
405
+ )
406
+
407
+
408
+ def set_measurement(name, value, unit=""):
409
+ # type: (str, float, MeasurementUnit) -> None
410
+ """
411
+ .. deprecated:: 2.28.0
412
+ This function is deprecated and will be removed in the next major release.
413
+ """
414
+ transaction = get_current_scope().transaction
415
+ if transaction is not None:
416
+ transaction.set_measurement(name, value, unit)
417
+
418
+
419
+ def get_current_span(scope=None):
420
+ # type: (Optional[Scope]) -> Optional[Span]
421
+ """
422
+ Returns the currently active span if there is one running, otherwise `None`
423
+ """
424
+ return tracing_utils.get_current_span(scope)
425
+
426
+
427
+ def get_traceparent():
428
+ # type: () -> Optional[str]
429
+ """
430
+ Returns the traceparent either from the active span or from the scope.
431
+ """
432
+ return get_current_scope().get_traceparent()
433
+
434
+
435
+ def get_baggage():
436
+ # type: () -> Optional[str]
437
+ """
438
+ Returns Baggage either from the active span or from the scope.
439
+ """
440
+ baggage = get_current_scope().get_baggage()
441
+ if baggage is not None:
442
+ return baggage.serialize()
443
+
444
+ return None
445
+
446
+
447
+ def continue_trace(
448
+ environ_or_headers, op=None, name=None, source=None, origin="manual"
211
449
  ):
212
- # type: (...) -> Transaction
213
- return Hub.current.start_transaction(transaction, **kwargs)
450
+ # type: (Dict[str, Any], Optional[str], Optional[str], Optional[str], str) -> Transaction
451
+ """
452
+ Sets the propagation context from environment or headers and returns a transaction.
453
+ """
454
+ return get_isolation_scope().continue_trace(
455
+ environ_or_headers, op, name, source, origin
456
+ )
457
+
458
+
459
+ @scopemethod
460
+ def start_session(
461
+ session_mode="application", # type: str
462
+ ):
463
+ # type: (...) -> None
464
+ return get_isolation_scope().start_session(session_mode=session_mode)
465
+
466
+
467
+ @scopemethod
468
+ def end_session():
469
+ # type: () -> None
470
+ return get_isolation_scope().end_session()
471
+
472
+
473
+ @scopemethod
474
+ def set_transaction_name(name, source=None):
475
+ # type: (str, Optional[str]) -> None
476
+ return get_current_scope().set_transaction_name(name, source)
477
+
478
+
479
+ def update_current_span(op=None, name=None, attributes=None, data=None):
480
+ # type: (Optional[str], Optional[str], Optional[dict[str, Union[str, int, float, bool]]], Optional[dict[str, Any]]) -> None
481
+ """
482
+ Update the current active span with the provided parameters.
483
+
484
+ This function allows you to modify properties of the currently active span.
485
+ If no span is currently active, this function will do nothing.
486
+
487
+ :param op: The operation name for the span. This is a high-level description
488
+ of what the span represents (e.g., "http.client", "db.query").
489
+ You can use predefined constants from :py:class:`sentry_sdk.consts.OP`
490
+ or provide your own string. If not provided, the span's operation will
491
+ remain unchanged.
492
+ :type op: str or None
493
+
494
+ :param name: The human-readable name/description for the span. This provides
495
+ more specific details about what the span represents (e.g., "GET /api/users",
496
+ "SELECT * FROM users"). If not provided, the span's name will remain unchanged.
497
+ :type name: str or None
498
+
499
+ :param data: A dictionary of key-value pairs to add as data to the span. This
500
+ data will be merged with any existing span data. If not provided,
501
+ no data will be added.
502
+
503
+ .. deprecated:: 2.35.0
504
+ Use ``attributes`` instead. The ``data`` parameter will be removed
505
+ in a future version.
506
+ :type data: dict[str, Union[str, int, float, bool]] or None
507
+
508
+ :param attributes: A dictionary of key-value pairs to add as attributes to the span.
509
+ Attribute values must be strings, integers, floats, or booleans. These
510
+ attributes will be merged with any existing span data. If not provided,
511
+ no attributes will be added.
512
+ :type attributes: dict[str, Union[str, int, float, bool]] or None
513
+
514
+ :returns: None
515
+
516
+ .. versionadded:: 2.35.0
517
+
518
+ Example::
519
+
520
+ import sentry_sdk
521
+ from sentry_sdk.consts import OP
522
+
523
+ sentry_sdk.update_current_span(
524
+ op=OP.FUNCTION,
525
+ name="process_user_data",
526
+ attributes={"user_id": 123, "batch_size": 50}
527
+ )
528
+ """
529
+ current_span = get_current_span()
530
+
531
+ if current_span is None:
532
+ return
533
+
534
+ if op is not None:
535
+ current_span.op = op
536
+
537
+ if name is not None:
538
+ # internally it is still description
539
+ current_span.description = name
540
+
541
+ if data is not None and attributes is not None:
542
+ raise ValueError(
543
+ "Cannot provide both `data` and `attributes`. Please use only `attributes`."
544
+ )
545
+
546
+ if data is not None:
547
+ warnings.warn(
548
+ "The `data` parameter is deprecated. Please use `attributes` instead.",
549
+ DeprecationWarning,
550
+ stacklevel=2,
551
+ )
552
+ attributes = data
553
+
554
+ if attributes is not None:
555
+ current_span.update_data(attributes)
@@ -0,0 +1,75 @@
1
+ import os
2
+ import mimetypes
3
+
4
+ from sentry_sdk.envelope import Item, PayloadRef
5
+
6
+ from typing import TYPE_CHECKING
7
+
8
+ if TYPE_CHECKING:
9
+ from typing import Optional, Union, Callable
10
+
11
+
12
+ class Attachment:
13
+ """Additional files/data to send along with an event.
14
+
15
+ This class stores attachments that can be sent along with an event. Attachments are files or other data, e.g.
16
+ config or log files, that are relevant to an event. Attachments are set on the ``Scope``, and are sent along with
17
+ all non-transaction events (or all events including transactions if ``add_to_transactions`` is ``True``) that are
18
+ captured within the ``Scope``.
19
+
20
+ To add an attachment to a ``Scope``, use :py:meth:`sentry_sdk.Scope.add_attachment`. The parameters for
21
+ ``add_attachment`` are the same as the parameters for this class's constructor.
22
+
23
+ :param bytes: Raw bytes of the attachment, or a function that returns the raw bytes. Must be provided unless
24
+ ``path`` is provided.
25
+ :param filename: The filename of the attachment. Must be provided unless ``path`` is provided.
26
+ :param path: Path to a file to attach. Must be provided unless ``bytes`` is provided.
27
+ :param content_type: The content type of the attachment. If not provided, it will be guessed from the ``filename``
28
+ parameter, if available, or the ``path`` parameter if ``filename`` is ``None``.
29
+ :param add_to_transactions: Whether to add this attachment to transactions. Defaults to ``False``.
30
+ """
31
+
32
+ def __init__(
33
+ self,
34
+ bytes=None, # type: Union[None, bytes, Callable[[], bytes]]
35
+ filename=None, # type: Optional[str]
36
+ path=None, # type: Optional[str]
37
+ content_type=None, # type: Optional[str]
38
+ add_to_transactions=False, # type: bool
39
+ ):
40
+ # type: (...) -> None
41
+ if bytes is None and path is None:
42
+ raise TypeError("path or raw bytes required for attachment")
43
+ if filename is None and path is not None:
44
+ filename = os.path.basename(path)
45
+ if filename is None:
46
+ raise TypeError("filename is required for attachment")
47
+ if content_type is None:
48
+ content_type = mimetypes.guess_type(filename)[0]
49
+ self.bytes = bytes
50
+ self.filename = filename
51
+ self.path = path
52
+ self.content_type = content_type
53
+ self.add_to_transactions = add_to_transactions
54
+
55
+ def to_envelope_item(self):
56
+ # type: () -> Item
57
+ """Returns an envelope item for this attachment."""
58
+ payload = None # type: Union[None, PayloadRef, bytes]
59
+ if self.bytes is not None:
60
+ if callable(self.bytes):
61
+ payload = self.bytes()
62
+ else:
63
+ payload = self.bytes
64
+ else:
65
+ payload = PayloadRef(path=self.path)
66
+ return Item(
67
+ payload=payload,
68
+ type="attachment",
69
+ content_type=self.content_type,
70
+ filename=self.filename,
71
+ )
72
+
73
+ def __repr__(self):
74
+ # type: () -> str
75
+ return "<Attachment %r>" % (self.filename,)