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
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  import sentry_sdk
2
3
  from sentry_sdk.crons import capture_checkin, MonitorStatus
3
4
  from sentry_sdk.integrations import DidNotEnable
@@ -42,8 +43,7 @@ except ImportError:
42
43
  RedBeatScheduler = None
43
44
 
44
45
 
45
- def _get_headers(task):
46
- # type: (Task) -> dict[str, Any]
46
+ def _get_headers(task: Task) -> dict[str, Any]:
47
47
  headers = task.request.get("headers") or {}
48
48
 
49
49
  # flatten nested headers
@@ -56,12 +56,13 @@ def _get_headers(task):
56
56
  return headers
57
57
 
58
58
 
59
- def _get_monitor_config(celery_schedule, app, monitor_name):
60
- # type: (Any, Celery, str) -> MonitorConfig
61
- monitor_config = {} # type: MonitorConfig
62
- schedule_type = None # type: Optional[MonitorConfigScheduleType]
63
- schedule_value = None # type: Optional[Union[str, int]]
64
- schedule_unit = None # type: Optional[MonitorConfigScheduleUnit]
59
+ def _get_monitor_config(
60
+ celery_schedule: Any, app: Celery, monitor_name: str
61
+ ) -> MonitorConfig:
62
+ monitor_config: MonitorConfig = {}
63
+ schedule_type: Optional[MonitorConfigScheduleType] = None
64
+ schedule_value: Optional[Union[str, int]] = None
65
+ schedule_unit: Optional[MonitorConfigScheduleUnit] = None
65
66
 
66
67
  if isinstance(celery_schedule, crontab):
67
68
  schedule_type = "crontab"
@@ -113,8 +114,11 @@ def _get_monitor_config(celery_schedule, app, monitor_name):
113
114
  return monitor_config
114
115
 
115
116
 
116
- def _apply_crons_data_to_schedule_entry(scheduler, schedule_entry, integration):
117
- # type: (Any, Any, sentry_sdk.integrations.celery.CeleryIntegration) -> None
117
+ def _apply_crons_data_to_schedule_entry(
118
+ scheduler: Any,
119
+ schedule_entry: Any,
120
+ integration: sentry_sdk.integrations.celery.CeleryIntegration,
121
+ ) -> None:
118
122
  """
119
123
  Add Sentry Crons information to the schedule_entry headers.
120
124
  """
@@ -158,8 +162,7 @@ def _apply_crons_data_to_schedule_entry(scheduler, schedule_entry, integration):
158
162
  schedule_entry.options["headers"] = headers
159
163
 
160
164
 
161
- def _wrap_beat_scheduler(original_function):
162
- # type: (Callable[..., Any]) -> Callable[..., Any]
165
+ def _wrap_beat_scheduler(original_function: Callable[..., Any]) -> Callable[..., Any]:
163
166
  """
164
167
  Makes sure that:
165
168
  - a new Sentry trace is started for each task started by Celery Beat and
@@ -178,8 +181,7 @@ def _wrap_beat_scheduler(original_function):
178
181
 
179
182
  from sentry_sdk.integrations.celery import CeleryIntegration
180
183
 
181
- def sentry_patched_scheduler(*args, **kwargs):
182
- # type: (*Any, **Any) -> None
184
+ def sentry_patched_scheduler(*args: Any, **kwargs: Any) -> None:
183
185
  integration = sentry_sdk.get_client().get_integration(CeleryIntegration)
184
186
  if integration is None:
185
187
  return original_function(*args, **kwargs)
@@ -197,29 +199,25 @@ def _wrap_beat_scheduler(original_function):
197
199
  return sentry_patched_scheduler
198
200
 
199
201
 
200
- def _patch_beat_apply_entry():
201
- # type: () -> None
202
+ def _patch_beat_apply_entry() -> None:
202
203
  Scheduler.apply_entry = _wrap_beat_scheduler(Scheduler.apply_entry)
203
204
 
204
205
 
205
- def _patch_redbeat_apply_async():
206
- # type: () -> None
206
+ def _patch_redbeat_apply_async() -> None:
207
207
  if RedBeatScheduler is None:
208
208
  return
209
209
 
210
210
  RedBeatScheduler.apply_async = _wrap_beat_scheduler(RedBeatScheduler.apply_async)
211
211
 
212
212
 
213
- def _setup_celery_beat_signals(monitor_beat_tasks):
214
- # type: (bool) -> None
213
+ def _setup_celery_beat_signals(monitor_beat_tasks: bool) -> None:
215
214
  if monitor_beat_tasks:
216
215
  task_success.connect(crons_task_success)
217
216
  task_failure.connect(crons_task_failure)
218
217
  task_retry.connect(crons_task_retry)
219
218
 
220
219
 
221
- def crons_task_success(sender, **kwargs):
222
- # type: (Task, dict[Any, Any]) -> None
220
+ def crons_task_success(sender: Task, **kwargs: dict[Any, Any]) -> None:
223
221
  logger.debug("celery_task_success %s", sender)
224
222
  headers = _get_headers(sender)
225
223
 
@@ -243,8 +241,7 @@ def crons_task_success(sender, **kwargs):
243
241
  )
244
242
 
245
243
 
246
- def crons_task_failure(sender, **kwargs):
247
- # type: (Task, dict[Any, Any]) -> None
244
+ def crons_task_failure(sender: Task, **kwargs: dict[Any, Any]) -> None:
248
245
  logger.debug("celery_task_failure %s", sender)
249
246
  headers = _get_headers(sender)
250
247
 
@@ -268,8 +265,7 @@ def crons_task_failure(sender, **kwargs):
268
265
  )
269
266
 
270
267
 
271
- def crons_task_retry(sender, **kwargs):
272
- # type: (Task, dict[Any, Any]) -> None
268
+ def crons_task_retry(sender: Task, **kwargs: dict[Any, Any]) -> None:
273
269
  logger.debug("celery_task_retry %s", sender)
274
270
  headers = _get_headers(sender)
275
271
 
@@ -1,13 +1,20 @@
1
+ from __future__ import annotations
1
2
  import time
2
- from typing import TYPE_CHECKING, cast
3
+ from typing import TYPE_CHECKING
3
4
 
4
5
  if TYPE_CHECKING:
5
- from typing import Any, Tuple
6
+ from typing import Any, Tuple, List
6
7
  from sentry_sdk._types import MonitorConfigScheduleUnit
7
8
 
8
9
 
9
- def _now_seconds_since_epoch():
10
- # type: () -> float
10
+ TIME_UNITS: List[Tuple[MonitorConfigScheduleUnit, float]] = [
11
+ ("day", 60 * 60 * 24.0),
12
+ ("hour", 60 * 60.0),
13
+ ("minute", 60.0),
14
+ ]
15
+
16
+
17
+ def _now_seconds_since_epoch() -> float:
11
18
  # We cannot use `time.perf_counter()` when dealing with the duration
12
19
  # of a Celery task, because the start of a Celery task and
13
20
  # the end are recorded in different processes.
@@ -16,28 +23,19 @@ def _now_seconds_since_epoch():
16
23
  return time.time()
17
24
 
18
25
 
19
- def _get_humanized_interval(seconds):
20
- # type: (float) -> Tuple[int, MonitorConfigScheduleUnit]
21
- TIME_UNITS = ( # noqa: N806
22
- ("day", 60 * 60 * 24.0),
23
- ("hour", 60 * 60.0),
24
- ("minute", 60.0),
25
- )
26
-
26
+ def _get_humanized_interval(seconds: float) -> Tuple[int, MonitorConfigScheduleUnit]:
27
27
  seconds = float(seconds)
28
28
  for unit, divider in TIME_UNITS:
29
29
  if seconds >= divider:
30
30
  interval = int(seconds / divider)
31
- return (interval, cast("MonitorConfigScheduleUnit", unit))
31
+ return (interval, unit)
32
32
 
33
33
  return (int(seconds), "second")
34
34
 
35
35
 
36
36
  class NoOpMgr:
37
- def __enter__(self):
38
- # type: () -> None
37
+ def __enter__(self) -> None:
39
38
  return None
40
39
 
41
- def __exit__(self, exc_type, exc_value, traceback):
42
- # type: (Any, Any, Any) -> None
40
+ def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
43
41
  return None
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  import sys
2
3
  from functools import wraps
3
4
 
@@ -32,8 +33,7 @@ if TYPE_CHECKING:
32
33
 
33
34
 
34
35
  class EventSourceHandler(ChaliceEventSourceHandler): # type: ignore
35
- def __call__(self, event, context):
36
- # type: (Any, Any) -> Any
36
+ def __call__(self, event: Any, context: Any) -> Any:
37
37
  client = sentry_sdk.get_client()
38
38
 
39
39
  with sentry_sdk.isolation_scope() as scope:
@@ -56,11 +56,9 @@ class EventSourceHandler(ChaliceEventSourceHandler): # type: ignore
56
56
  reraise(*exc_info)
57
57
 
58
58
 
59
- def _get_view_function_response(app, view_function, function_args):
60
- # type: (Any, F, Any) -> F
59
+ def _get_view_function_response(app: Any, view_function: F, function_args: Any) -> F:
61
60
  @wraps(view_function)
62
- def wrapped_view_function(**function_args):
63
- # type: (**Any) -> Any
61
+ def wrapped_view_function(**function_args: Any) -> Any:
64
62
  client = sentry_sdk.get_client()
65
63
  with sentry_sdk.isolation_scope() as scope:
66
64
  with capture_internal_exceptions():
@@ -99,8 +97,7 @@ class ChaliceIntegration(Integration):
99
97
  identifier = "chalice"
100
98
 
101
99
  @staticmethod
102
- def setup_once():
103
- # type: () -> None
100
+ def setup_once() -> None:
104
101
 
105
102
  version = parse_version(CHALICE_VERSION)
106
103
 
@@ -116,8 +113,9 @@ class ChaliceIntegration(Integration):
116
113
  RestAPIEventHandler._get_view_function_response
117
114
  )
118
115
 
119
- def sentry_event_response(app, view_function, function_args):
120
- # type: (Any, F, Dict[str, Any]) -> Any
116
+ def sentry_event_response(
117
+ app: Any, view_function: F, function_args: Dict[str, Any]
118
+ ) -> Any:
121
119
  wrapped_view_function = _get_view_function_response(
122
120
  app, view_function, function_args
123
121
  )
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  import sentry_sdk
2
3
  from sentry_sdk.consts import OP, SPANDATA
3
4
  from sentry_sdk.integrations import _check_minimum_version, Integration, DidNotEnable
@@ -9,27 +10,13 @@ from sentry_sdk.utils import (
9
10
  ensure_integration_enabled,
10
11
  )
11
12
 
12
- from typing import TYPE_CHECKING, cast, Any, Dict, TypeVar
13
+ from typing import TYPE_CHECKING
13
14
 
14
- # Hack to get new Python features working in older versions
15
- # without introducing a hard dependency on `typing_extensions`
16
- # from: https://stackoverflow.com/a/71944042/300572
17
15
  if TYPE_CHECKING:
18
- from typing import ParamSpec, Callable
19
- else:
20
- # Fake ParamSpec
21
- class ParamSpec:
22
- def __init__(self, _):
23
- self.args = None
24
- self.kwargs = None
16
+ from typing import ParamSpec, Callable, Any, Dict, TypeVar
25
17
 
26
- # Callable[anything] will return None
27
- class _Callable:
28
- def __getitem__(self, _):
29
- return None
30
-
31
- # Make instances
32
- Callable = _Callable()
18
+ P = ParamSpec("P")
19
+ T = TypeVar("T")
33
20
 
34
21
 
35
22
  try:
@@ -72,10 +59,6 @@ class ClickhouseDriverIntegration(Integration):
72
59
  )
73
60
 
74
61
 
75
- P = ParamSpec("P")
76
- T = TypeVar("T")
77
-
78
-
79
62
  def _wrap_start(f: Callable[P, T]) -> Callable[P, T]:
80
63
  @ensure_integration_enabled(ClickhouseDriverIntegration, f)
81
64
  def _inner(*args: P.args, **kwargs: P.kwargs) -> T:
@@ -88,13 +71,12 @@ def _wrap_start(f: Callable[P, T]) -> Callable[P, T]:
88
71
  op=OP.DB,
89
72
  name=query,
90
73
  origin=ClickhouseDriverIntegration.origin,
91
- only_if_parent=True,
74
+ only_as_child_span=True,
92
75
  )
93
76
 
94
77
  connection._sentry_span = span # type: ignore[attr-defined]
95
78
 
96
- data = _get_db_data(connection)
97
- data = cast("dict[str, Any]", data)
79
+ data: dict[str, Any] = _get_db_data(connection)
98
80
  data["db.query.text"] = query
99
81
 
100
82
  if query_id:
@@ -117,7 +99,11 @@ def _wrap_start(f: Callable[P, T]) -> Callable[P, T]:
117
99
  def _wrap_end(f: Callable[P, T]) -> Callable[P, T]:
118
100
  def _inner_end(*args: P.args, **kwargs: P.kwargs) -> T:
119
101
  res = f(*args, **kwargs)
120
- client = cast("clickhouse_driver.client.Client", args[0])
102
+
103
+ client = args[0]
104
+ if not isinstance(client, clickhouse_driver.client.Client):
105
+ return res
106
+
121
107
  connection = client.connection
122
108
 
123
109
  span = getattr(connection, "_sentry_span", None)
@@ -150,9 +136,11 @@ def _wrap_end(f: Callable[P, T]) -> Callable[P, T]:
150
136
 
151
137
  def _wrap_send_data(f: Callable[P, T]) -> Callable[P, T]:
152
138
  def _inner_send_data(*args: P.args, **kwargs: P.kwargs) -> T:
153
- client = cast("clickhouse_driver.client.Client", args[0])
139
+ client = args[0]
140
+ if not isinstance(client, clickhouse_driver.client.Client):
141
+ return f(*args, **kwargs)
142
+
154
143
  connection = client.connection
155
- db_params_data = cast("list[Any]", args[2])
156
144
  span = getattr(connection, "_sentry_span", None)
157
145
 
158
146
  if span is not None:
@@ -160,11 +148,13 @@ def _wrap_send_data(f: Callable[P, T]) -> Callable[P, T]:
160
148
  _set_on_span(span, data)
161
149
 
162
150
  if should_send_default_pii():
163
- saved_db_data = getattr(
151
+ saved_db_data: dict[str, Any] = getattr(
164
152
  connection, "_sentry_db_data", {}
165
- ) # type: dict[str, Any]
166
- db_params = saved_db_data.get("db.params") or [] # type: list[Any]
167
- db_params.extend(db_params_data)
153
+ )
154
+ db_params: list[Any] = saved_db_data.get("db.params") or []
155
+ db_params_data = args[2]
156
+ if isinstance(db_params_data, list):
157
+ db_params.extend(db_params_data)
168
158
  saved_db_data["db.params"] = db_params
169
159
  span.set_attribute("db.params", _serialize_span_attribute(db_params))
170
160
 
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  import json
2
3
  import urllib3
3
4
 
@@ -65,13 +66,11 @@ class CloudResourceContextIntegration(Integration):
65
66
 
66
67
  gcp_metadata = None
67
68
 
68
- def __init__(self, cloud_provider=""):
69
- # type: (str) -> None
69
+ def __init__(self, cloud_provider: str = "") -> None:
70
70
  CloudResourceContextIntegration.cloud_provider = cloud_provider
71
71
 
72
72
  @classmethod
73
- def _is_aws(cls):
74
- # type: () -> bool
73
+ def _is_aws(cls) -> bool:
75
74
  try:
76
75
  r = cls.http.request(
77
76
  "PUT",
@@ -95,8 +94,7 @@ class CloudResourceContextIntegration(Integration):
95
94
  return False
96
95
 
97
96
  @classmethod
98
- def _get_aws_context(cls):
99
- # type: () -> Dict[str, str]
97
+ def _get_aws_context(cls) -> Dict[str, str]:
100
98
  ctx = {
101
99
  "cloud.provider": CLOUD_PROVIDER.AWS,
102
100
  "cloud.platform": CLOUD_PLATFORM.AWS_EC2,
@@ -149,8 +147,7 @@ class CloudResourceContextIntegration(Integration):
149
147
  return ctx
150
148
 
151
149
  @classmethod
152
- def _is_gcp(cls):
153
- # type: () -> bool
150
+ def _is_gcp(cls) -> bool:
154
151
  try:
155
152
  r = cls.http.request(
156
153
  "GET",
@@ -174,8 +171,7 @@ class CloudResourceContextIntegration(Integration):
174
171
  return False
175
172
 
176
173
  @classmethod
177
- def _get_gcp_context(cls):
178
- # type: () -> Dict[str, str]
174
+ def _get_gcp_context(cls) -> Dict[str, str]:
179
175
  ctx = {
180
176
  "cloud.provider": CLOUD_PROVIDER.GCP,
181
177
  "cloud.platform": CLOUD_PLATFORM.GCP_COMPUTE_ENGINE,
@@ -229,8 +225,7 @@ class CloudResourceContextIntegration(Integration):
229
225
  return ctx
230
226
 
231
227
  @classmethod
232
- def _get_cloud_provider(cls):
233
- # type: () -> str
228
+ def _get_cloud_provider(cls) -> str:
234
229
  if cls._is_aws():
235
230
  return CLOUD_PROVIDER.AWS
236
231
 
@@ -240,8 +235,7 @@ class CloudResourceContextIntegration(Integration):
240
235
  return ""
241
236
 
242
237
  @classmethod
243
- def _get_cloud_resource_context(cls):
244
- # type: () -> Dict[str, str]
238
+ def _get_cloud_resource_context(cls) -> Dict[str, str]:
245
239
  cloud_provider = (
246
240
  cls.cloud_provider
247
241
  if cls.cloud_provider != ""
@@ -253,8 +247,7 @@ class CloudResourceContextIntegration(Integration):
253
247
  return {}
254
248
 
255
249
  @staticmethod
256
- def setup_once():
257
- # type: () -> None
250
+ def setup_once() -> None:
258
251
  cloud_provider = CloudResourceContextIntegration.cloud_provider
259
252
  unsupported_cloud_provider = (
260
253
  cloud_provider != "" and cloud_provider not in context_getters.keys()
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  from functools import wraps
2
3
 
3
4
  from sentry_sdk import consts
@@ -70,20 +71,17 @@ class CohereIntegration(Integration):
70
71
  identifier = "cohere"
71
72
  origin = f"auto.ai.{identifier}"
72
73
 
73
- def __init__(self, include_prompts=True):
74
- # type: (CohereIntegration, bool) -> None
74
+ def __init__(self: CohereIntegration, include_prompts: bool = True) -> None:
75
75
  self.include_prompts = include_prompts
76
76
 
77
77
  @staticmethod
78
- def setup_once():
79
- # type: () -> None
78
+ def setup_once() -> None:
80
79
  BaseCohere.chat = _wrap_chat(BaseCohere.chat, streaming=False)
81
80
  Client.embed = _wrap_embed(Client.embed)
82
81
  BaseCohere.chat_stream = _wrap_chat(BaseCohere.chat_stream, streaming=True)
83
82
 
84
83
 
85
- def _capture_exception(exc):
86
- # type: (Any) -> None
84
+ def _capture_exception(exc: Any) -> None:
87
85
  event, hint = event_from_exception(
88
86
  exc,
89
87
  client_options=sentry_sdk.get_client().options,
@@ -92,11 +90,11 @@ def _capture_exception(exc):
92
90
  sentry_sdk.capture_event(event, hint=hint)
93
91
 
94
92
 
95
- def _wrap_chat(f, streaming):
96
- # type: (Callable[..., Any], bool) -> Callable[..., Any]
93
+ def _wrap_chat(f: Callable[..., Any], streaming: bool) -> Callable[..., Any]:
97
94
 
98
- def collect_chat_response_fields(span, res, include_pii):
99
- # type: (Span, NonStreamedChatResponse, bool) -> None
95
+ def collect_chat_response_fields(
96
+ span: Span, res: NonStreamedChatResponse, include_pii: bool
97
+ ) -> None:
100
98
  if include_pii:
101
99
  if hasattr(res, "text"):
102
100
  set_data_normalized(
@@ -116,22 +114,21 @@ def _wrap_chat(f, streaming):
116
114
  if hasattr(res.meta, "billed_units"):
117
115
  record_token_usage(
118
116
  span,
119
- prompt_tokens=res.meta.billed_units.input_tokens,
120
- completion_tokens=res.meta.billed_units.output_tokens,
117
+ input_tokens=res.meta.billed_units.input_tokens,
118
+ output_tokens=res.meta.billed_units.output_tokens,
121
119
  )
122
120
  elif hasattr(res.meta, "tokens"):
123
121
  record_token_usage(
124
122
  span,
125
- prompt_tokens=res.meta.tokens.input_tokens,
126
- completion_tokens=res.meta.tokens.output_tokens,
123
+ input_tokens=res.meta.tokens.input_tokens,
124
+ output_tokens=res.meta.tokens.output_tokens,
127
125
  )
128
126
 
129
127
  if hasattr(res.meta, "warnings"):
130
128
  set_data_normalized(span, SPANDATA.AI_WARNINGS, res.meta.warnings)
131
129
 
132
130
  @wraps(f)
133
- def new_chat(*args, **kwargs):
134
- # type: (*Any, **Any) -> Any
131
+ def new_chat(*args: Any, **kwargs: Any) -> Any:
135
132
  integration = sentry_sdk.get_client().get_integration(CohereIntegration)
136
133
 
137
134
  if (
@@ -147,7 +144,7 @@ def _wrap_chat(f, streaming):
147
144
  op=consts.OP.COHERE_CHAT_COMPLETIONS_CREATE,
148
145
  name="cohere.client.Chat",
149
146
  origin=CohereIntegration.origin,
150
- only_if_parent=True,
147
+ only_as_child_span=True,
151
148
  )
152
149
  span.__enter__()
153
150
  try:
@@ -185,8 +182,7 @@ def _wrap_chat(f, streaming):
185
182
  if streaming:
186
183
  old_iterator = res
187
184
 
188
- def new_iterator():
189
- # type: () -> Iterator[StreamedChatResponse]
185
+ def new_iterator() -> Iterator[StreamedChatResponse]:
190
186
 
191
187
  with capture_internal_exceptions():
192
188
  for x in old_iterator:
@@ -220,12 +216,10 @@ def _wrap_chat(f, streaming):
220
216
  return new_chat
221
217
 
222
218
 
223
- def _wrap_embed(f):
224
- # type: (Callable[..., Any]) -> Callable[..., Any]
219
+ def _wrap_embed(f: Callable[..., Any]) -> Callable[..., Any]:
225
220
 
226
221
  @wraps(f)
227
- def new_embed(*args, **kwargs):
228
- # type: (*Any, **Any) -> Any
222
+ def new_embed(*args: Any, **kwargs: Any) -> Any:
229
223
  integration = sentry_sdk.get_client().get_integration(CohereIntegration)
230
224
  if integration is None:
231
225
  return f(*args, **kwargs)
@@ -234,7 +228,7 @@ def _wrap_embed(f):
234
228
  op=consts.OP.COHERE_EMBEDDINGS_CREATE,
235
229
  name="Cohere Embedding Creation",
236
230
  origin=CohereIntegration.origin,
237
- only_if_parent=True,
231
+ only_as_child_span=True,
238
232
  ) as span:
239
233
  if "texts" in kwargs and (
240
234
  should_send_default_pii() and integration.include_prompts
@@ -264,7 +258,7 @@ def _wrap_embed(f):
264
258
  ):
265
259
  record_token_usage(
266
260
  span,
267
- prompt_tokens=res.meta.billed_units.input_tokens,
261
+ input_tokens=res.meta.billed_units.input_tokens,
268
262
  total_tokens=res.meta.billed_units.input_tokens,
269
263
  )
270
264
  return res
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  import sentry_sdk
2
3
  from sentry_sdk.utils import ContextVar
3
4
  from sentry_sdk.integrations import Integration
@@ -14,16 +15,13 @@ if TYPE_CHECKING:
14
15
  class DedupeIntegration(Integration):
15
16
  identifier = "dedupe"
16
17
 
17
- def __init__(self):
18
- # type: () -> None
18
+ def __init__(self) -> None:
19
19
  self._last_seen = ContextVar("last-seen")
20
20
 
21
21
  @staticmethod
22
- def setup_once():
23
- # type: () -> None
22
+ def setup_once() -> None:
24
23
  @add_global_event_processor
25
- def processor(event, hint):
26
- # type: (Event, Optional[Hint]) -> Optional[Event]
24
+ def processor(event: Event, hint: Optional[Hint]) -> Optional[Event]:
27
25
  if hint is None:
28
26
  return event
29
27
 
@@ -42,8 +40,7 @@ class DedupeIntegration(Integration):
42
40
  return event
43
41
 
44
42
  @staticmethod
45
- def reset_last_seen():
46
- # type: () -> None
43
+ def reset_last_seen() -> None:
47
44
  integration = sentry_sdk.get_client().get_integration(DedupeIntegration)
48
45
  if integration is None:
49
46
  return