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
@@ -0,0 +1,247 @@
1
+ import sys
2
+
3
+ import sentry_sdk
4
+ from sentry_sdk.consts import OP, SPANSTATUS
5
+ from sentry_sdk.integrations import _check_minimum_version, DidNotEnable, Integration
6
+ from sentry_sdk.integrations.logging import ignore_logger
7
+ from sentry_sdk.scope import should_send_default_pii
8
+ from sentry_sdk.tracing import Transaction, TransactionSource
9
+ from sentry_sdk.utils import (
10
+ capture_internal_exceptions,
11
+ ensure_integration_enabled,
12
+ event_from_exception,
13
+ SENSITIVE_DATA_SUBSTITUTE,
14
+ parse_version,
15
+ reraise,
16
+ )
17
+
18
+ try:
19
+ import arq.worker
20
+ from arq.version import VERSION as ARQ_VERSION
21
+ from arq.connections import ArqRedis
22
+ from arq.worker import JobExecutionFailed, Retry, RetryJob, Worker
23
+ except ImportError:
24
+ raise DidNotEnable("Arq is not installed")
25
+
26
+ from typing import TYPE_CHECKING
27
+
28
+ if TYPE_CHECKING:
29
+ from typing import Any, Dict, Optional, Union
30
+
31
+ from sentry_sdk._types import EventProcessor, Event, ExcInfo, Hint
32
+
33
+ from arq.cron import CronJob
34
+ from arq.jobs import Job
35
+ from arq.typing import WorkerCoroutine
36
+ from arq.worker import Function
37
+
38
+ ARQ_CONTROL_FLOW_EXCEPTIONS = (JobExecutionFailed, Retry, RetryJob)
39
+
40
+
41
+ class ArqIntegration(Integration):
42
+ identifier = "arq"
43
+ origin = f"auto.queue.{identifier}"
44
+
45
+ @staticmethod
46
+ def setup_once():
47
+ # type: () -> None
48
+
49
+ try:
50
+ if isinstance(ARQ_VERSION, str):
51
+ version = parse_version(ARQ_VERSION)
52
+ else:
53
+ version = ARQ_VERSION.version[:2]
54
+
55
+ except (TypeError, ValueError):
56
+ version = None
57
+
58
+ _check_minimum_version(ArqIntegration, version)
59
+
60
+ patch_enqueue_job()
61
+ patch_run_job()
62
+ patch_create_worker()
63
+
64
+ ignore_logger("arq.worker")
65
+
66
+
67
+ def patch_enqueue_job():
68
+ # type: () -> None
69
+ old_enqueue_job = ArqRedis.enqueue_job
70
+ original_kwdefaults = old_enqueue_job.__kwdefaults__
71
+
72
+ async def _sentry_enqueue_job(self, function, *args, **kwargs):
73
+ # type: (ArqRedis, str, *Any, **Any) -> Optional[Job]
74
+ integration = sentry_sdk.get_client().get_integration(ArqIntegration)
75
+ if integration is None:
76
+ return await old_enqueue_job(self, function, *args, **kwargs)
77
+
78
+ with sentry_sdk.start_span(
79
+ op=OP.QUEUE_SUBMIT_ARQ, name=function, origin=ArqIntegration.origin
80
+ ):
81
+ return await old_enqueue_job(self, function, *args, **kwargs)
82
+
83
+ _sentry_enqueue_job.__kwdefaults__ = original_kwdefaults
84
+ ArqRedis.enqueue_job = _sentry_enqueue_job
85
+
86
+
87
+ def patch_run_job():
88
+ # type: () -> None
89
+ old_run_job = Worker.run_job
90
+
91
+ async def _sentry_run_job(self, job_id, score):
92
+ # type: (Worker, str, int) -> None
93
+ integration = sentry_sdk.get_client().get_integration(ArqIntegration)
94
+ if integration is None:
95
+ return await old_run_job(self, job_id, score)
96
+
97
+ with sentry_sdk.isolation_scope() as scope:
98
+ scope._name = "arq"
99
+ scope.clear_breadcrumbs()
100
+
101
+ transaction = Transaction(
102
+ name="unknown arq task",
103
+ status="ok",
104
+ op=OP.QUEUE_TASK_ARQ,
105
+ source=TransactionSource.TASK,
106
+ origin=ArqIntegration.origin,
107
+ )
108
+
109
+ with sentry_sdk.start_transaction(transaction):
110
+ return await old_run_job(self, job_id, score)
111
+
112
+ Worker.run_job = _sentry_run_job
113
+
114
+
115
+ def _capture_exception(exc_info):
116
+ # type: (ExcInfo) -> None
117
+ scope = sentry_sdk.get_current_scope()
118
+
119
+ if scope.transaction is not None:
120
+ if exc_info[0] in ARQ_CONTROL_FLOW_EXCEPTIONS:
121
+ scope.transaction.set_status(SPANSTATUS.ABORTED)
122
+ return
123
+
124
+ scope.transaction.set_status(SPANSTATUS.INTERNAL_ERROR)
125
+
126
+ event, hint = event_from_exception(
127
+ exc_info,
128
+ client_options=sentry_sdk.get_client().options,
129
+ mechanism={"type": ArqIntegration.identifier, "handled": False},
130
+ )
131
+ sentry_sdk.capture_event(event, hint=hint)
132
+
133
+
134
+ def _make_event_processor(ctx, *args, **kwargs):
135
+ # type: (Dict[Any, Any], *Any, **Any) -> EventProcessor
136
+ def event_processor(event, hint):
137
+ # type: (Event, Hint) -> Optional[Event]
138
+
139
+ with capture_internal_exceptions():
140
+ scope = sentry_sdk.get_current_scope()
141
+ if scope.transaction is not None:
142
+ scope.transaction.name = ctx["job_name"]
143
+ event["transaction"] = ctx["job_name"]
144
+
145
+ tags = event.setdefault("tags", {})
146
+ tags["arq_task_id"] = ctx["job_id"]
147
+ tags["arq_task_retry"] = ctx["job_try"] > 1
148
+ extra = event.setdefault("extra", {})
149
+ extra["arq-job"] = {
150
+ "task": ctx["job_name"],
151
+ "args": (
152
+ args if should_send_default_pii() else SENSITIVE_DATA_SUBSTITUTE
153
+ ),
154
+ "kwargs": (
155
+ kwargs if should_send_default_pii() else SENSITIVE_DATA_SUBSTITUTE
156
+ ),
157
+ "retry": ctx["job_try"],
158
+ }
159
+
160
+ return event
161
+
162
+ return event_processor
163
+
164
+
165
+ def _wrap_coroutine(name, coroutine):
166
+ # type: (str, WorkerCoroutine) -> WorkerCoroutine
167
+
168
+ async def _sentry_coroutine(ctx, *args, **kwargs):
169
+ # type: (Dict[Any, Any], *Any, **Any) -> Any
170
+ integration = sentry_sdk.get_client().get_integration(ArqIntegration)
171
+ if integration is None:
172
+ return await coroutine(ctx, *args, **kwargs)
173
+
174
+ sentry_sdk.get_isolation_scope().add_event_processor(
175
+ _make_event_processor({**ctx, "job_name": name}, *args, **kwargs)
176
+ )
177
+
178
+ try:
179
+ result = await coroutine(ctx, *args, **kwargs)
180
+ except Exception:
181
+ exc_info = sys.exc_info()
182
+ _capture_exception(exc_info)
183
+ reraise(*exc_info)
184
+
185
+ return result
186
+
187
+ return _sentry_coroutine
188
+
189
+
190
+ def patch_create_worker():
191
+ # type: () -> None
192
+ old_create_worker = arq.worker.create_worker
193
+
194
+ @ensure_integration_enabled(ArqIntegration, old_create_worker)
195
+ def _sentry_create_worker(*args, **kwargs):
196
+ # type: (*Any, **Any) -> Worker
197
+ settings_cls = args[0]
198
+
199
+ if isinstance(settings_cls, dict):
200
+ if "functions" in settings_cls:
201
+ settings_cls["functions"] = [
202
+ _get_arq_function(func)
203
+ for func in settings_cls.get("functions", [])
204
+ ]
205
+ if "cron_jobs" in settings_cls:
206
+ settings_cls["cron_jobs"] = [
207
+ _get_arq_cron_job(cron_job)
208
+ for cron_job in settings_cls.get("cron_jobs", [])
209
+ ]
210
+
211
+ if hasattr(settings_cls, "functions"):
212
+ settings_cls.functions = [
213
+ _get_arq_function(func) for func in settings_cls.functions
214
+ ]
215
+ if hasattr(settings_cls, "cron_jobs"):
216
+ settings_cls.cron_jobs = [
217
+ _get_arq_cron_job(cron_job)
218
+ for cron_job in (settings_cls.cron_jobs or [])
219
+ ]
220
+
221
+ if "functions" in kwargs:
222
+ kwargs["functions"] = [
223
+ _get_arq_function(func) for func in kwargs.get("functions", [])
224
+ ]
225
+ if "cron_jobs" in kwargs:
226
+ kwargs["cron_jobs"] = [
227
+ _get_arq_cron_job(cron_job) for cron_job in kwargs.get("cron_jobs", [])
228
+ ]
229
+
230
+ return old_create_worker(*args, **kwargs)
231
+
232
+ arq.worker.create_worker = _sentry_create_worker
233
+
234
+
235
+ def _get_arq_function(func):
236
+ # type: (Union[str, Function, WorkerCoroutine]) -> Function
237
+ arq_func = arq.worker.func(func)
238
+ arq_func.coroutine = _wrap_coroutine(arq_func.name, arq_func.coroutine)
239
+
240
+ return arq_func
241
+
242
+
243
+ def _get_arq_cron_job(cron_job):
244
+ # type: (CronJob) -> CronJob
245
+ cron_job.coroutine = _wrap_coroutine(cron_job.name, cron_job.coroutine)
246
+
247
+ return cron_job