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,284 @@
1
+ """
2
+ This integration ingests tracing data from native extensions written in Rust.
3
+
4
+ Using it requires additional setup on the Rust side to accept a
5
+ `RustTracingLayer` Python object and register it with the `tracing-subscriber`
6
+ using an adapter from the `pyo3-python-tracing-subscriber` crate. For example:
7
+ ```rust
8
+ #[pyfunction]
9
+ pub fn initialize_tracing(py_impl: Bound<'_, PyAny>) {
10
+ tracing_subscriber::registry()
11
+ .with(pyo3_python_tracing_subscriber::PythonCallbackLayerBridge::new(py_impl))
12
+ .init();
13
+ }
14
+ ```
15
+
16
+ Usage in Python would then look like:
17
+ ```
18
+ sentry_sdk.init(
19
+ dsn=sentry_dsn,
20
+ integrations=[
21
+ RustTracingIntegration(
22
+ "demo_rust_extension",
23
+ demo_rust_extension.initialize_tracing,
24
+ event_type_mapping=event_type_mapping,
25
+ )
26
+ ],
27
+ )
28
+ ```
29
+
30
+ Each native extension requires its own integration.
31
+ """
32
+
33
+ import json
34
+ from enum import Enum, auto
35
+ from typing import Any, Callable, Dict, Tuple, Optional
36
+
37
+ import sentry_sdk
38
+ from sentry_sdk.integrations import Integration
39
+ from sentry_sdk.scope import should_send_default_pii
40
+ from sentry_sdk.tracing import Span as SentrySpan
41
+ from sentry_sdk.utils import SENSITIVE_DATA_SUBSTITUTE
42
+
43
+ TraceState = Optional[Tuple[Optional[SentrySpan], SentrySpan]]
44
+
45
+
46
+ class RustTracingLevel(Enum):
47
+ Trace = "TRACE"
48
+ Debug = "DEBUG"
49
+ Info = "INFO"
50
+ Warn = "WARN"
51
+ Error = "ERROR"
52
+
53
+
54
+ class EventTypeMapping(Enum):
55
+ Ignore = auto()
56
+ Exc = auto()
57
+ Breadcrumb = auto()
58
+ Event = auto()
59
+
60
+
61
+ def tracing_level_to_sentry_level(level):
62
+ # type: (str) -> sentry_sdk._types.LogLevelStr
63
+ level = RustTracingLevel(level)
64
+ if level in (RustTracingLevel.Trace, RustTracingLevel.Debug):
65
+ return "debug"
66
+ elif level == RustTracingLevel.Info:
67
+ return "info"
68
+ elif level == RustTracingLevel.Warn:
69
+ return "warning"
70
+ elif level == RustTracingLevel.Error:
71
+ return "error"
72
+ else:
73
+ # Better this than crashing
74
+ return "info"
75
+
76
+
77
+ def extract_contexts(event: Dict[str, Any]) -> Dict[str, Any]:
78
+ metadata = event.get("metadata", {})
79
+ contexts = {}
80
+
81
+ location = {}
82
+ for field in ["module_path", "file", "line"]:
83
+ if field in metadata:
84
+ location[field] = metadata[field]
85
+ if len(location) > 0:
86
+ contexts["rust_tracing_location"] = location
87
+
88
+ fields = {}
89
+ for field in metadata.get("fields", []):
90
+ fields[field] = event.get(field)
91
+ if len(fields) > 0:
92
+ contexts["rust_tracing_fields"] = fields
93
+
94
+ return contexts
95
+
96
+
97
+ def process_event(event: Dict[str, Any]) -> None:
98
+ metadata = event.get("metadata", {})
99
+
100
+ logger = metadata.get("target")
101
+ level = tracing_level_to_sentry_level(metadata.get("level"))
102
+ message = event.get("message") # type: sentry_sdk._types.Any
103
+ contexts = extract_contexts(event)
104
+
105
+ sentry_event = {
106
+ "logger": logger,
107
+ "level": level,
108
+ "message": message,
109
+ "contexts": contexts,
110
+ } # type: sentry_sdk._types.Event
111
+
112
+ sentry_sdk.capture_event(sentry_event)
113
+
114
+
115
+ def process_exception(event: Dict[str, Any]) -> None:
116
+ process_event(event)
117
+
118
+
119
+ def process_breadcrumb(event: Dict[str, Any]) -> None:
120
+ level = tracing_level_to_sentry_level(event.get("metadata", {}).get("level"))
121
+ message = event.get("message")
122
+
123
+ sentry_sdk.add_breadcrumb(level=level, message=message)
124
+
125
+
126
+ def default_span_filter(metadata: Dict[str, Any]) -> bool:
127
+ return RustTracingLevel(metadata.get("level")) in (
128
+ RustTracingLevel.Error,
129
+ RustTracingLevel.Warn,
130
+ RustTracingLevel.Info,
131
+ )
132
+
133
+
134
+ def default_event_type_mapping(metadata: Dict[str, Any]) -> EventTypeMapping:
135
+ level = RustTracingLevel(metadata.get("level"))
136
+ if level == RustTracingLevel.Error:
137
+ return EventTypeMapping.Exc
138
+ elif level in (RustTracingLevel.Warn, RustTracingLevel.Info):
139
+ return EventTypeMapping.Breadcrumb
140
+ elif level in (RustTracingLevel.Debug, RustTracingLevel.Trace):
141
+ return EventTypeMapping.Ignore
142
+ else:
143
+ return EventTypeMapping.Ignore
144
+
145
+
146
+ class RustTracingLayer:
147
+ def __init__(
148
+ self,
149
+ origin: str,
150
+ event_type_mapping: Callable[
151
+ [Dict[str, Any]], EventTypeMapping
152
+ ] = default_event_type_mapping,
153
+ span_filter: Callable[[Dict[str, Any]], bool] = default_span_filter,
154
+ include_tracing_fields: Optional[bool] = None,
155
+ ):
156
+ self.origin = origin
157
+ self.event_type_mapping = event_type_mapping
158
+ self.span_filter = span_filter
159
+ self.include_tracing_fields = include_tracing_fields
160
+
161
+ def _include_tracing_fields(self) -> bool:
162
+ """
163
+ By default, the values of tracing fields are not included in case they
164
+ contain PII. A user may override that by passing `True` for the
165
+ `include_tracing_fields` keyword argument of this integration or by
166
+ setting `send_default_pii` to `True` in their Sentry client options.
167
+ """
168
+ return (
169
+ should_send_default_pii()
170
+ if self.include_tracing_fields is None
171
+ else self.include_tracing_fields
172
+ )
173
+
174
+ def on_event(self, event: str, _span_state: TraceState) -> None:
175
+ deserialized_event = json.loads(event)
176
+ metadata = deserialized_event.get("metadata", {})
177
+
178
+ event_type = self.event_type_mapping(metadata)
179
+ if event_type == EventTypeMapping.Ignore:
180
+ return
181
+ elif event_type == EventTypeMapping.Exc:
182
+ process_exception(deserialized_event)
183
+ elif event_type == EventTypeMapping.Breadcrumb:
184
+ process_breadcrumb(deserialized_event)
185
+ elif event_type == EventTypeMapping.Event:
186
+ process_event(deserialized_event)
187
+
188
+ def on_new_span(self, attrs: str, span_id: str) -> TraceState:
189
+ attrs = json.loads(attrs)
190
+ metadata = attrs.get("metadata", {})
191
+
192
+ if not self.span_filter(metadata):
193
+ return None
194
+
195
+ module_path = metadata.get("module_path")
196
+ name = metadata.get("name")
197
+ message = attrs.get("message")
198
+
199
+ if message is not None:
200
+ sentry_span_name = message
201
+ elif module_path is not None and name is not None:
202
+ sentry_span_name = f"{module_path}::{name}" # noqa: E231
203
+ elif name is not None:
204
+ sentry_span_name = name
205
+ else:
206
+ sentry_span_name = "<unknown>"
207
+
208
+ kwargs = {
209
+ "op": "function",
210
+ "name": sentry_span_name,
211
+ "origin": self.origin,
212
+ }
213
+
214
+ scope = sentry_sdk.get_current_scope()
215
+ parent_sentry_span = scope.span
216
+ if parent_sentry_span:
217
+ sentry_span = parent_sentry_span.start_child(**kwargs)
218
+ else:
219
+ sentry_span = scope.start_span(**kwargs)
220
+
221
+ fields = metadata.get("fields", [])
222
+ for field in fields:
223
+ if self._include_tracing_fields():
224
+ sentry_span.set_data(field, attrs.get(field))
225
+ else:
226
+ sentry_span.set_data(field, SENSITIVE_DATA_SUBSTITUTE)
227
+
228
+ scope.span = sentry_span
229
+ return (parent_sentry_span, sentry_span)
230
+
231
+ def on_close(self, span_id: str, span_state: TraceState) -> None:
232
+ if span_state is None:
233
+ return
234
+
235
+ parent_sentry_span, sentry_span = span_state
236
+ sentry_span.finish()
237
+ sentry_sdk.get_current_scope().span = parent_sentry_span
238
+
239
+ def on_record(self, span_id: str, values: str, span_state: TraceState) -> None:
240
+ if span_state is None:
241
+ return
242
+ _parent_sentry_span, sentry_span = span_state
243
+
244
+ deserialized_values = json.loads(values)
245
+ for key, value in deserialized_values.items():
246
+ if self._include_tracing_fields():
247
+ sentry_span.set_data(key, value)
248
+ else:
249
+ sentry_span.set_data(key, SENSITIVE_DATA_SUBSTITUTE)
250
+
251
+
252
+ class RustTracingIntegration(Integration):
253
+ """
254
+ Ingests tracing data from a Rust native extension's `tracing` instrumentation.
255
+
256
+ If a project uses more than one Rust native extension, each one will need
257
+ its own instance of `RustTracingIntegration` with an initializer function
258
+ specific to that extension.
259
+
260
+ Since all of the setup for this integration requires instance-specific state
261
+ which is not available in `setup_once()`, setup instead happens in `__init__()`.
262
+ """
263
+
264
+ def __init__(
265
+ self,
266
+ identifier: str,
267
+ initializer: Callable[[RustTracingLayer], None],
268
+ event_type_mapping: Callable[
269
+ [Dict[str, Any]], EventTypeMapping
270
+ ] = default_event_type_mapping,
271
+ span_filter: Callable[[Dict[str, Any]], bool] = default_span_filter,
272
+ include_tracing_fields: Optional[bool] = None,
273
+ ):
274
+ self.identifier = identifier
275
+ origin = f"auto.function.rust_tracing.{identifier}"
276
+ self.tracing_layer = RustTracingLayer(
277
+ origin, event_type_mapping, span_filter, include_tracing_fields
278
+ )
279
+
280
+ initializer(self.tracing_layer)
281
+
282
+ @staticmethod
283
+ def setup_once() -> None:
284
+ pass