sentry-sdk 3.0.0a2__py2.py3-none-any.whl → 3.0.0a4__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 (159) hide show
  1. sentry_sdk/__init__.py +4 -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 +9 -16
  8. sentry_sdk/_werkzeug.py +5 -7
  9. sentry_sdk/ai/monitoring.py +45 -33
  10. sentry_sdk/ai/utils.py +8 -5
  11. sentry_sdk/api.py +91 -87
  12. sentry_sdk/attachments.py +10 -12
  13. sentry_sdk/client.py +119 -159
  14. sentry_sdk/consts.py +432 -223
  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 +16 -18
  22. sentry_sdk/integrations/_wsgi_common.py +22 -33
  23. sentry_sdk/integrations/aiohttp.py +33 -31
  24. sentry_sdk/integrations/anthropic.py +43 -38
  25. sentry_sdk/integrations/argv.py +3 -4
  26. sentry_sdk/integrations/ariadne.py +16 -18
  27. sentry_sdk/integrations/arq.py +20 -29
  28. sentry_sdk/integrations/asgi.py +63 -37
  29. sentry_sdk/integrations/asyncio.py +15 -17
  30. sentry_sdk/integrations/asyncpg.py +1 -1
  31. sentry_sdk/integrations/atexit.py +6 -10
  32. sentry_sdk/integrations/aws_lambda.py +26 -36
  33. sentry_sdk/integrations/beam.py +10 -18
  34. sentry_sdk/integrations/boto3.py +20 -18
  35. sentry_sdk/integrations/bottle.py +25 -34
  36. sentry_sdk/integrations/celery/__init__.py +40 -59
  37. sentry_sdk/integrations/celery/beat.py +22 -26
  38. sentry_sdk/integrations/celery/utils.py +15 -17
  39. sentry_sdk/integrations/chalice.py +8 -10
  40. sentry_sdk/integrations/clickhouse_driver.py +22 -32
  41. sentry_sdk/integrations/cloud_resource_context.py +9 -16
  42. sentry_sdk/integrations/cohere.py +19 -25
  43. sentry_sdk/integrations/dedupe.py +5 -8
  44. sentry_sdk/integrations/django/__init__.py +69 -74
  45. sentry_sdk/integrations/django/asgi.py +25 -33
  46. sentry_sdk/integrations/django/caching.py +24 -20
  47. sentry_sdk/integrations/django/middleware.py +18 -21
  48. sentry_sdk/integrations/django/signals_handlers.py +12 -11
  49. sentry_sdk/integrations/django/templates.py +21 -18
  50. sentry_sdk/integrations/django/transactions.py +16 -11
  51. sentry_sdk/integrations/django/views.py +8 -12
  52. sentry_sdk/integrations/dramatiq.py +21 -21
  53. sentry_sdk/integrations/excepthook.py +10 -10
  54. sentry_sdk/integrations/executing.py +3 -4
  55. sentry_sdk/integrations/falcon.py +27 -42
  56. sentry_sdk/integrations/fastapi.py +13 -16
  57. sentry_sdk/integrations/flask.py +31 -38
  58. sentry_sdk/integrations/gcp.py +13 -16
  59. sentry_sdk/integrations/gnu_backtrace.py +7 -20
  60. sentry_sdk/integrations/gql.py +16 -17
  61. sentry_sdk/integrations/graphene.py +14 -13
  62. sentry_sdk/integrations/grpc/__init__.py +3 -2
  63. sentry_sdk/integrations/grpc/aio/client.py +2 -2
  64. sentry_sdk/integrations/grpc/aio/server.py +15 -14
  65. sentry_sdk/integrations/grpc/client.py +21 -11
  66. sentry_sdk/integrations/grpc/consts.py +2 -0
  67. sentry_sdk/integrations/grpc/server.py +12 -8
  68. sentry_sdk/integrations/httpx.py +11 -14
  69. sentry_sdk/integrations/huey.py +14 -21
  70. sentry_sdk/integrations/huggingface_hub.py +17 -17
  71. sentry_sdk/integrations/langchain.py +204 -114
  72. sentry_sdk/integrations/launchdarkly.py +13 -10
  73. sentry_sdk/integrations/litestar.py +40 -38
  74. sentry_sdk/integrations/logging.py +29 -36
  75. sentry_sdk/integrations/loguru.py +16 -20
  76. sentry_sdk/integrations/modules.py +3 -4
  77. sentry_sdk/integrations/openai.py +421 -204
  78. sentry_sdk/integrations/openai_agents/__init__.py +49 -0
  79. sentry_sdk/integrations/openai_agents/consts.py +1 -0
  80. sentry_sdk/integrations/openai_agents/patches/__init__.py +4 -0
  81. sentry_sdk/integrations/openai_agents/patches/agent_run.py +152 -0
  82. sentry_sdk/integrations/openai_agents/patches/models.py +52 -0
  83. sentry_sdk/integrations/openai_agents/patches/runner.py +42 -0
  84. sentry_sdk/integrations/openai_agents/patches/tools.py +84 -0
  85. sentry_sdk/integrations/openai_agents/spans/__init__.py +5 -0
  86. sentry_sdk/integrations/openai_agents/spans/agent_workflow.py +20 -0
  87. sentry_sdk/integrations/openai_agents/spans/ai_client.py +46 -0
  88. sentry_sdk/integrations/openai_agents/spans/execute_tool.py +47 -0
  89. sentry_sdk/integrations/openai_agents/spans/handoff.py +24 -0
  90. sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +41 -0
  91. sentry_sdk/integrations/openai_agents/utils.py +153 -0
  92. sentry_sdk/integrations/openfeature.py +12 -8
  93. sentry_sdk/integrations/pure_eval.py +6 -10
  94. sentry_sdk/integrations/pymongo.py +14 -18
  95. sentry_sdk/integrations/pyramid.py +31 -36
  96. sentry_sdk/integrations/quart.py +23 -28
  97. sentry_sdk/integrations/ray.py +73 -64
  98. sentry_sdk/integrations/redis/__init__.py +7 -4
  99. sentry_sdk/integrations/redis/_async_common.py +18 -12
  100. sentry_sdk/integrations/redis/_sync_common.py +16 -15
  101. sentry_sdk/integrations/redis/modules/caches.py +17 -8
  102. sentry_sdk/integrations/redis/modules/queries.py +9 -8
  103. sentry_sdk/integrations/redis/rb.py +3 -2
  104. sentry_sdk/integrations/redis/redis.py +4 -4
  105. sentry_sdk/integrations/redis/redis_cluster.py +10 -8
  106. sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +3 -2
  107. sentry_sdk/integrations/redis/utils.py +21 -22
  108. sentry_sdk/integrations/rq.py +13 -16
  109. sentry_sdk/integrations/rust_tracing.py +10 -7
  110. sentry_sdk/integrations/sanic.py +34 -46
  111. sentry_sdk/integrations/serverless.py +22 -27
  112. sentry_sdk/integrations/socket.py +29 -17
  113. sentry_sdk/integrations/spark/__init__.py +1 -0
  114. sentry_sdk/integrations/spark/spark_driver.py +45 -83
  115. sentry_sdk/integrations/spark/spark_worker.py +7 -11
  116. sentry_sdk/integrations/sqlalchemy.py +22 -19
  117. sentry_sdk/integrations/starlette.py +89 -93
  118. sentry_sdk/integrations/starlite.py +31 -37
  119. sentry_sdk/integrations/statsig.py +5 -4
  120. sentry_sdk/integrations/stdlib.py +32 -28
  121. sentry_sdk/integrations/strawberry.py +63 -50
  122. sentry_sdk/integrations/sys_exit.py +7 -11
  123. sentry_sdk/integrations/threading.py +13 -15
  124. sentry_sdk/integrations/tornado.py +28 -32
  125. sentry_sdk/integrations/trytond.py +4 -3
  126. sentry_sdk/integrations/typer.py +8 -6
  127. sentry_sdk/integrations/unleash.py +5 -4
  128. sentry_sdk/integrations/wsgi.py +47 -46
  129. sentry_sdk/logger.py +13 -9
  130. sentry_sdk/monitor.py +16 -28
  131. sentry_sdk/opentelemetry/consts.py +11 -4
  132. sentry_sdk/opentelemetry/contextvars_context.py +17 -15
  133. sentry_sdk/opentelemetry/propagator.py +38 -21
  134. sentry_sdk/opentelemetry/sampler.py +51 -34
  135. sentry_sdk/opentelemetry/scope.py +46 -37
  136. sentry_sdk/opentelemetry/span_processor.py +43 -59
  137. sentry_sdk/opentelemetry/tracing.py +32 -12
  138. sentry_sdk/opentelemetry/utils.py +180 -196
  139. sentry_sdk/profiler/continuous_profiler.py +108 -97
  140. sentry_sdk/profiler/transaction_profiler.py +70 -97
  141. sentry_sdk/profiler/utils.py +11 -15
  142. sentry_sdk/scope.py +251 -264
  143. sentry_sdk/scrubber.py +22 -26
  144. sentry_sdk/serializer.py +48 -65
  145. sentry_sdk/session.py +44 -61
  146. sentry_sdk/sessions.py +35 -49
  147. sentry_sdk/spotlight.py +15 -21
  148. sentry_sdk/tracing.py +118 -184
  149. sentry_sdk/tracing_utils.py +103 -123
  150. sentry_sdk/transport.py +131 -157
  151. sentry_sdk/utils.py +278 -309
  152. sentry_sdk/worker.py +16 -28
  153. {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/METADATA +1 -1
  154. sentry_sdk-3.0.0a4.dist-info/RECORD +168 -0
  155. sentry_sdk-3.0.0a2.dist-info/RECORD +0 -154
  156. {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/WHEEL +0 -0
  157. {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/entry_points.txt +0 -0
  158. {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/licenses/LICENSE +0 -0
  159. {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/top_level.txt +0 -0
sentry_sdk/client.py CHANGED
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  import os
2
3
  import uuid
3
4
  import random
@@ -5,7 +6,7 @@ import socket
5
6
  from collections.abc import Mapping
6
7
  from datetime import datetime, timezone
7
8
  from importlib import import_module
8
- from typing import TYPE_CHECKING, List, Dict, cast, overload
9
+ from typing import TYPE_CHECKING, overload
9
10
 
10
11
  import sentry_sdk
11
12
  from sentry_sdk._compat import check_uwsgi_thread_support
@@ -45,16 +46,18 @@ from sentry_sdk.profiler.transaction_profiler import (
45
46
  )
46
47
  from sentry_sdk.scrubber import EventScrubber
47
48
  from sentry_sdk.monitor import Monitor
48
- from sentry_sdk.spotlight import setup_spotlight
49
49
 
50
50
  if TYPE_CHECKING:
51
- from typing import Any
52
- from typing import Callable
53
- from typing import Optional
54
- from typing import Sequence
55
- from typing import Type
56
- from typing import Union
57
- from typing import TypeVar
51
+ from typing import (
52
+ Any,
53
+ Callable,
54
+ Optional,
55
+ Sequence,
56
+ Type,
57
+ Union,
58
+ TypeVar,
59
+ Dict,
60
+ )
58
61
 
59
62
  from sentry_sdk._types import Event, Hint, SDKInfo, Log
60
63
  from sentry_sdk.integrations import Integration
@@ -64,22 +67,22 @@ if TYPE_CHECKING:
64
67
  from sentry_sdk.transport import Transport
65
68
  from sentry_sdk._log_batcher import LogBatcher
66
69
 
67
- I = TypeVar("I", bound=Integration) # noqa: E741
70
+ IntegrationType = TypeVar("IntegrationType", bound=Integration) # noqa: E741
71
+
68
72
 
69
73
  _client_init_debug = ContextVar("client_init_debug")
70
74
 
71
75
 
72
- SDK_INFO = {
76
+ SDK_INFO: SDKInfo = {
73
77
  "name": "sentry.python", # SDK name will be overridden after integrations have been loaded with sentry_sdk.integrations.setup_integrations()
74
78
  "version": VERSION,
75
79
  "packages": [{"name": "pypi:sentry-sdk", "version": VERSION}],
76
- } # type: SDKInfo
80
+ }
77
81
 
78
82
 
79
- def _get_options(*args, **kwargs):
80
- # type: (*Optional[str], **Any) -> Dict[str, Any]
83
+ def _get_options(*args: Optional[str], **kwargs: Any) -> Dict[str, Any]:
81
84
  if args and (isinstance(args[0], (bytes, str)) or args[0] is None):
82
- dsn = args[0] # type: Optional[str]
85
+ dsn: Optional[str] = args[0]
83
86
  args = args[1:]
84
87
  else:
85
88
  dsn = None
@@ -149,37 +152,31 @@ class BaseClient:
149
152
  The basic definition of a client that is used for sending data to Sentry.
150
153
  """
151
154
 
152
- spotlight = None # type: Optional[SpotlightClient]
155
+ spotlight: Optional[SpotlightClient] = None
153
156
 
154
- def __init__(self, options=None):
155
- # type: (Optional[Dict[str, Any]]) -> None
156
- self.options = (
157
+ def __init__(self, options: Optional[Dict[str, Any]] = None) -> None:
158
+ self.options: Dict[str, Any] = (
157
159
  options if options is not None else DEFAULT_OPTIONS
158
- ) # type: Dict[str, Any]
160
+ )
159
161
 
160
- self.transport = None # type: Optional[Transport]
161
- self.monitor = None # type: Optional[Monitor]
162
- self.log_batcher = None # type: Optional[LogBatcher]
162
+ self.transport: Optional[Transport] = None
163
+ self.monitor: Optional[Monitor] = None
164
+ self.log_batcher: Optional[LogBatcher] = None
163
165
 
164
- def __getstate__(self, *args, **kwargs):
165
- # type: (*Any, **Any) -> Any
166
+ def __getstate__(self, *args: Any, **kwargs: Any) -> Any:
166
167
  return {"options": {}}
167
168
 
168
- def __setstate__(self, *args, **kwargs):
169
- # type: (*Any, **Any) -> None
169
+ def __setstate__(self, *args: Any, **kwargs: Any) -> None:
170
170
  pass
171
171
 
172
172
  @property
173
- def dsn(self):
174
- # type: () -> Optional[str]
173
+ def dsn(self) -> Optional[str]:
175
174
  return None
176
175
 
177
- def should_send_default_pii(self):
178
- # type: () -> bool
176
+ def should_send_default_pii(self) -> bool:
179
177
  return False
180
178
 
181
- def is_active(self):
182
- # type: () -> bool
179
+ def is_active(self) -> bool:
183
180
  """
184
181
  .. versionadded:: 2.0.0
185
182
 
@@ -187,48 +184,40 @@ class BaseClient:
187
184
  """
188
185
  return False
189
186
 
190
- def capture_event(self, *args, **kwargs):
191
- # type: (*Any, **Any) -> Optional[str]
187
+ def capture_event(self, *args: Any, **kwargs: Any) -> Optional[str]:
192
188
  return None
193
189
 
194
- def _capture_experimental_log(self, log):
195
- # type: (Log) -> None
190
+ def _capture_experimental_log(self, log: "Log") -> None:
196
191
  pass
197
192
 
198
- def capture_session(self, *args, **kwargs):
199
- # type: (*Any, **Any) -> None
193
+ def capture_session(self, *args: Any, **kwargs: Any) -> None:
200
194
  return None
201
195
 
202
196
  if TYPE_CHECKING:
203
197
 
204
198
  @overload
205
- def get_integration(self, name_or_class):
206
- # type: (str) -> Optional[Integration]
207
- ...
199
+ def get_integration(self, name_or_class: str) -> Optional[Integration]: ...
208
200
 
209
201
  @overload
210
- def get_integration(self, name_or_class):
211
- # type: (type[I]) -> Optional[I]
212
- ...
202
+ def get_integration(
203
+ self, name_or_class: type[IntegrationType]
204
+ ) -> Optional[IntegrationType]: ...
213
205
 
214
- def get_integration(self, name_or_class):
215
- # type: (Union[str, type[Integration]]) -> Optional[Integration]
206
+ def get_integration(
207
+ self, name_or_class: Union[str, type[Integration]]
208
+ ) -> Optional[Integration]:
216
209
  return None
217
210
 
218
- def close(self, *args, **kwargs):
219
- # type: (*Any, **Any) -> None
211
+ def close(self, *args: Any, **kwargs: Any) -> None:
220
212
  return None
221
213
 
222
- def flush(self, *args, **kwargs):
223
- # type: (*Any, **Any) -> None
214
+ def flush(self, *args: Any, **kwargs: Any) -> None:
224
215
  return None
225
216
 
226
- def __enter__(self):
227
- # type: () -> BaseClient
217
+ def __enter__(self) -> BaseClient:
228
218
  return self
229
219
 
230
- def __exit__(self, exc_type, exc_value, tb):
231
- # type: (Any, Any, Any) -> None
220
+ def __exit__(self, exc_type: Any, exc_value: Any, tb: Any) -> None:
232
221
  return None
233
222
 
234
223
 
@@ -252,22 +241,20 @@ class _Client(BaseClient):
252
241
  Alias of :py:class:`sentry_sdk.Client`. (Was created for better intelisense support)
253
242
  """
254
243
 
255
- def __init__(self, *args, **kwargs):
256
- # type: (*Any, **Any) -> None
257
- super(_Client, self).__init__(options=get_options(*args, **kwargs))
244
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
245
+ super(_Client, self).__init__(options=_get_options(*args, **kwargs))
258
246
  self._init_impl()
259
247
 
260
- def __getstate__(self):
261
- # type: () -> Any
248
+ def __getstate__(self) -> Any:
262
249
  return {"options": self.options}
263
250
 
264
- def __setstate__(self, state):
265
- # type: (Any) -> None
251
+ def __setstate__(self, state: Any) -> None:
266
252
  self.options = state["options"]
267
253
  self._init_impl()
268
254
 
269
- def _setup_instrumentation(self, functions_to_trace):
270
- # type: (Sequence[Dict[str, str]]) -> None
255
+ def _setup_instrumentation(
256
+ self, functions_to_trace: Sequence[Dict[str, str]]
257
+ ) -> None:
271
258
  """
272
259
  Instruments the functions given in the list `functions_to_trace` with the `@sentry_sdk.tracing.trace` decorator.
273
260
  """
@@ -317,12 +304,10 @@ class _Client(BaseClient):
317
304
  e,
318
305
  )
319
306
 
320
- def _init_impl(self):
321
- # type: () -> None
307
+ def _init_impl(self) -> None:
322
308
  old_debug = _client_init_debug.get(False)
323
309
 
324
- def _capture_envelope(envelope):
325
- # type: (Envelope) -> None
310
+ def _capture_envelope(envelope: Envelope) -> None:
326
311
  if self.transport is not None:
327
312
  self.transport.capture_envelope(envelope)
328
313
 
@@ -337,9 +322,9 @@ class _Client(BaseClient):
337
322
 
338
323
  self.session_flusher = SessionFlusher(capture_func=_capture_envelope)
339
324
 
340
- experiments = self.options.get("_experiments", {})
341
325
  self.log_batcher = None
342
- if experiments.get("enable_logs", False):
326
+
327
+ if self.options.get("enable_logs") is True:
343
328
  from sentry_sdk._log_batcher import LogBatcher
344
329
 
345
330
  self.log_batcher = LogBatcher(capture_func=_capture_envelope)
@@ -372,6 +357,10 @@ class _Client(BaseClient):
372
357
  )
373
358
 
374
359
  if self.options.get("spotlight"):
360
+ # This is intentionally here to prevent setting up spotlight
361
+ # stuff we don't need unless spotlight is explicitly enabled
362
+ from sentry_sdk.spotlight import setup_spotlight
363
+
375
364
  self.spotlight = setup_spotlight(self.options)
376
365
  if not self.options["dsn"]:
377
366
  sample_all = lambda *_args, **_kwargs: 1.0
@@ -423,8 +412,7 @@ class _Client(BaseClient):
423
412
  # need to check if it's safe to use them.
424
413
  check_uwsgi_thread_support()
425
414
 
426
- def is_active(self):
427
- # type: () -> bool
415
+ def is_active(self) -> bool:
428
416
  """
429
417
  .. versionadded:: 2.0.0
430
418
 
@@ -432,8 +420,7 @@ class _Client(BaseClient):
432
420
  """
433
421
  return True
434
422
 
435
- def should_send_default_pii(self):
436
- # type: () -> bool
423
+ def should_send_default_pii(self) -> bool:
437
424
  """
438
425
  .. versionadded:: 2.0.0
439
426
 
@@ -442,28 +429,26 @@ class _Client(BaseClient):
442
429
  return self.options.get("send_default_pii") or False
443
430
 
444
431
  @property
445
- def dsn(self):
446
- # type: () -> Optional[str]
432
+ def dsn(self) -> Optional[str]:
447
433
  """Returns the configured DSN as string."""
448
434
  return self.options["dsn"]
449
435
 
450
436
  def _prepare_event(
451
437
  self,
452
- event, # type: Event
453
- hint, # type: Hint
454
- scope, # type: Optional[Scope]
455
- ):
456
- # type: (...) -> Optional[Event]
438
+ event: Event,
439
+ hint: Hint,
440
+ scope: Optional[Scope],
441
+ ) -> Optional[Event]:
457
442
 
458
- previous_total_spans = None # type: Optional[int]
459
- previous_total_breadcrumbs = None # type: Optional[int]
443
+ previous_total_spans: Optional[int] = None
444
+ previous_total_breadcrumbs: Optional[int] = None
460
445
 
461
446
  if event.get("timestamp") is None:
462
447
  event["timestamp"] = datetime.now(timezone.utc)
463
448
 
464
449
  if scope is not None:
465
450
  is_transaction = event.get("type") == "transaction"
466
- spans_before = len(cast(List[Dict[str, object]], event.get("spans", [])))
451
+ spans_before = len(event.get("spans", []))
467
452
  event_ = scope.apply_to_event(event, hint, self.options)
468
453
 
469
454
  # one of the event/error processors returned None
@@ -481,16 +466,14 @@ class _Client(BaseClient):
481
466
  )
482
467
  return None
483
468
 
484
- event = event_ # type: Optional[Event] # type: ignore[no-redef]
485
- spans_delta = spans_before - len(
486
- cast(List[Dict[str, object]], event.get("spans", []))
487
- )
469
+ event = event_
470
+ spans_delta = spans_before - len(event.get("spans", []))
488
471
  if is_transaction and spans_delta > 0 and self.transport is not None:
489
472
  self.transport.record_lost_event(
490
473
  "event_processor", data_category="span", quantity=spans_delta
491
474
  )
492
475
 
493
- dropped_spans = event.pop("_dropped_spans", 0) + spans_delta # type: int
476
+ dropped_spans: int = event.pop("_dropped_spans", 0) + spans_delta
494
477
  if dropped_spans > 0:
495
478
  previous_total_spans = spans_before + dropped_spans
496
479
  if scope._n_breadcrumbs_truncated > 0:
@@ -562,14 +545,11 @@ class _Client(BaseClient):
562
545
  # Postprocess the event here so that annotated types do
563
546
  # generally not surface in before_send
564
547
  if event is not None:
565
- event = cast(
566
- "Event",
567
- serialize(
568
- cast("Dict[str, Any]", event),
569
- max_request_body_size=self.options.get("max_request_body_size"),
570
- max_value_length=self.options.get("max_value_length"),
571
- custom_repr=self.options.get("custom_repr"),
572
- ),
548
+ event: Event = serialize( # type: ignore[no-redef]
549
+ event,
550
+ max_request_body_size=self.options.get("max_request_body_size"),
551
+ max_value_length=self.options.get("max_value_length"),
552
+ custom_repr=self.options.get("custom_repr"),
573
553
  )
574
554
 
575
555
  before_send = self.options["before_send"]
@@ -578,7 +558,7 @@ class _Client(BaseClient):
578
558
  and event is not None
579
559
  and event.get("type") != "transaction"
580
560
  ):
581
- new_event = None # type: Optional[Event]
561
+ new_event: Optional["Event"] = None
582
562
  with capture_internal_exceptions():
583
563
  new_event = before_send(event, hint or {})
584
564
  if new_event is None:
@@ -595,7 +575,7 @@ class _Client(BaseClient):
595
575
  if event.get("exception"):
596
576
  DedupeIntegration.reset_last_seen()
597
577
 
598
- event = new_event # type: Optional[Event] # type: ignore[no-redef]
578
+ event = new_event
599
579
 
600
580
  before_send_transaction = self.options["before_send_transaction"]
601
581
  if (
@@ -604,7 +584,7 @@ class _Client(BaseClient):
604
584
  and event.get("type") == "transaction"
605
585
  ):
606
586
  new_event = None
607
- spans_before = len(cast(List[Dict[str, object]], event.get("spans", [])))
587
+ spans_before = len(event.get("spans", []))
608
588
  with capture_internal_exceptions():
609
589
  new_event = before_send_transaction(event, hint or {})
610
590
  if new_event is None:
@@ -619,20 +599,17 @@ class _Client(BaseClient):
619
599
  quantity=spans_before + 1, # +1 for the transaction itself
620
600
  )
621
601
  else:
622
- spans_delta = spans_before - len(
623
- cast(List[Dict[str, object]], new_event.get("spans", []))
624
- )
602
+ spans_delta = spans_before - len(new_event.get("spans", []))
625
603
  if spans_delta > 0 and self.transport is not None:
626
604
  self.transport.record_lost_event(
627
605
  reason="before_send", data_category="span", quantity=spans_delta
628
606
  )
629
607
 
630
- event = new_event # type: Optional[Event] # type: ignore[no-redef]
608
+ event = new_event
631
609
 
632
610
  return event
633
611
 
634
- def _is_ignored_error(self, event, hint):
635
- # type: (Event, Hint) -> bool
612
+ def _is_ignored_error(self, event: Event, hint: Hint) -> bool:
636
613
  exc_info = hint.get("exc_info")
637
614
  if exc_info is None:
638
615
  return False
@@ -655,11 +632,10 @@ class _Client(BaseClient):
655
632
 
656
633
  def _should_capture(
657
634
  self,
658
- event, # type: Event
659
- hint, # type: Hint
660
- scope=None, # type: Optional[Scope]
661
- ):
662
- # type: (...) -> bool
635
+ event: "Event",
636
+ hint: "Hint",
637
+ scope: Optional["Scope"] = None,
638
+ ) -> bool:
663
639
  # Transactions are sampled independent of error events.
664
640
  is_transaction = event.get("type") == "transaction"
665
641
  if is_transaction:
@@ -677,10 +653,9 @@ class _Client(BaseClient):
677
653
 
678
654
  def _should_sample_error(
679
655
  self,
680
- event, # type: Event
681
- hint, # type: Hint
682
- ):
683
- # type: (...) -> bool
656
+ event: Event,
657
+ hint: Hint,
658
+ ) -> bool:
684
659
  error_sampler = self.options.get("error_sampler", None)
685
660
 
686
661
  if callable(error_sampler):
@@ -725,10 +700,9 @@ class _Client(BaseClient):
725
700
 
726
701
  def _update_session_from_event(
727
702
  self,
728
- session, # type: Session
729
- event, # type: Event
730
- ):
731
- # type: (...) -> None
703
+ session: Session,
704
+ event: Event,
705
+ ) -> None:
732
706
 
733
707
  crashed = False
734
708
  errored = False
@@ -764,11 +738,10 @@ class _Client(BaseClient):
764
738
 
765
739
  def capture_event(
766
740
  self,
767
- event, # type: Event
768
- hint=None, # type: Optional[Hint]
769
- scope=None, # type: Optional[Scope]
770
- ):
771
- # type: (...) -> Optional[str]
741
+ event: Event,
742
+ hint: Optional[Hint] = None,
743
+ scope: Optional[Scope] = None,
744
+ ) -> Optional[str]:
772
745
  """Captures an event.
773
746
 
774
747
  :param event: A ready-made event that can be directly sent to Sentry.
@@ -779,7 +752,7 @@ class _Client(BaseClient):
779
752
 
780
753
  :returns: An event ID. May be `None` if there is no DSN set or of if the SDK decided to discard the event for other reasons. In such situations setting `debug=True` on `init()` may help.
781
754
  """
782
- hint = dict(hint or ()) # type: Hint
755
+ hint: Hint = dict(hint or ())
783
756
 
784
757
  if not self._should_capture(event, hint, scope):
785
758
  return None
@@ -814,10 +787,10 @@ class _Client(BaseClient):
814
787
  trace_context = event_opt.get("contexts", {}).get("trace") or {}
815
788
  dynamic_sampling_context = trace_context.pop("dynamic_sampling_context", {})
816
789
 
817
- headers = {
790
+ headers: dict[str, object] = {
818
791
  "event_id": event_opt["event_id"],
819
792
  "sent_at": format_timestamp(datetime.now(timezone.utc)),
820
- } # type: dict[str, object]
793
+ }
821
794
 
822
795
  if dynamic_sampling_context:
823
796
  headers["trace"] = dynamic_sampling_context
@@ -847,10 +820,8 @@ class _Client(BaseClient):
847
820
 
848
821
  return return_value
849
822
 
850
- def _capture_experimental_log(self, log):
851
- # type: (Log) -> None
852
- logs_enabled = self.options["_experiments"].get("enable_logs", False)
853
- if not logs_enabled:
823
+ def _capture_experimental_log(self, log: Optional[Log]) -> None:
824
+ if self.options.get("enable_logs") is not True or log is None:
854
825
  return
855
826
 
856
827
  current_scope = sentry_sdk.get_current_scope()
@@ -905,19 +876,17 @@ class _Client(BaseClient):
905
876
  f'[Sentry Logs] [{log.get("severity_text")}] {log.get("body")}'
906
877
  )
907
878
 
908
- before_send_log = self.options["_experiments"].get("before_send_log")
879
+ before_send_log = self.options.get("before_send_log")
909
880
  if before_send_log is not None:
910
881
  log = before_send_log(log, {})
882
+
911
883
  if log is None:
912
884
  return
913
885
 
914
886
  if self.log_batcher:
915
887
  self.log_batcher.add(log)
916
888
 
917
- def capture_session(
918
- self, session # type: Session
919
- ):
920
- # type: (...) -> None
889
+ def capture_session(self, session: Session) -> None:
921
890
  if not session.release:
922
891
  logger.info("Discarded session update because of missing release")
923
892
  else:
@@ -926,19 +895,16 @@ class _Client(BaseClient):
926
895
  if TYPE_CHECKING:
927
896
 
928
897
  @overload
929
- def get_integration(self, name_or_class):
930
- # type: (str) -> Optional[Integration]
931
- ...
898
+ def get_integration(self, name_or_class: str) -> Optional[Integration]: ...
932
899
 
933
900
  @overload
934
- def get_integration(self, name_or_class):
935
- # type: (type[I]) -> Optional[I]
936
- ...
901
+ def get_integration(
902
+ self, name_or_class: type[IntegrationType]
903
+ ) -> Optional[IntegrationType]: ...
937
904
 
938
905
  def get_integration(
939
- self, name_or_class # type: Union[str, Type[Integration]]
940
- ):
941
- # type: (...) -> Optional[Integration]
906
+ self, name_or_class: Union[str, Type[Integration]]
907
+ ) -> Optional[Integration]:
942
908
  """Returns the integration for this client by name or class.
943
909
  If the client does not have that integration then `None` is returned.
944
910
  """
@@ -953,10 +919,9 @@ class _Client(BaseClient):
953
919
 
954
920
  def close(
955
921
  self,
956
- timeout=None, # type: Optional[float]
957
- callback=None, # type: Optional[Callable[[int, float], None]]
958
- ):
959
- # type: (...) -> None
922
+ timeout: Optional[float] = None,
923
+ callback: Optional[Callable[[int, float], None]] = None,
924
+ ) -> None:
960
925
  """
961
926
  Close the client and shut down the transport. Arguments have the same
962
927
  semantics as :py:meth:`Client.flush`.
@@ -977,10 +942,9 @@ class _Client(BaseClient):
977
942
 
978
943
  def flush(
979
944
  self,
980
- timeout=None, # type: Optional[float]
981
- callback=None, # type: Optional[Callable[[int, float], None]]
982
- ):
983
- # type: (...) -> None
945
+ timeout: Optional[float] = None,
946
+ callback: Optional[Callable[[int, float], None]] = None,
947
+ ) -> None:
984
948
  """
985
949
  Wait for the current events to be sent.
986
950
 
@@ -998,17 +962,13 @@ class _Client(BaseClient):
998
962
 
999
963
  self.transport.flush(timeout=timeout, callback=callback)
1000
964
 
1001
- def __enter__(self):
1002
- # type: () -> _Client
965
+ def __enter__(self) -> _Client:
1003
966
  return self
1004
967
 
1005
- def __exit__(self, exc_type, exc_value, tb):
1006
- # type: (Any, Any, Any) -> None
968
+ def __exit__(self, exc_type: Any, exc_value: Any, tb: Any) -> None:
1007
969
  self.close()
1008
970
 
1009
971
 
1010
- from typing import TYPE_CHECKING
1011
-
1012
972
  if TYPE_CHECKING:
1013
973
  # Make mypy, PyCharm and other static analyzers think `get_options` is a
1014
974
  # type to have nicer autocompletion for params.