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
@@ -1,49 +1,55 @@
1
1
  import weakref
2
+ import contextlib
2
3
  from inspect import iscoroutinefunction
3
4
 
4
- from sentry_sdk.hub import Hub, _should_send_default_pii
5
+ import sentry_sdk
6
+ from sentry_sdk.api import continue_trace
7
+ from sentry_sdk.consts import OP
8
+ from sentry_sdk.scope import should_send_default_pii
9
+ from sentry_sdk.tracing import TransactionSource
5
10
  from sentry_sdk.utils import (
6
11
  HAS_REAL_CONTEXTVARS,
7
12
  CONTEXTVARS_ERROR_MESSAGE,
13
+ ensure_integration_enabled,
8
14
  event_from_exception,
9
15
  capture_internal_exceptions,
10
16
  transaction_from_function,
11
17
  )
12
- from sentry_sdk.integrations import Integration, DidNotEnable
18
+ from sentry_sdk.integrations import _check_minimum_version, Integration, DidNotEnable
13
19
  from sentry_sdk.integrations._wsgi_common import (
14
20
  RequestExtractor,
15
21
  _filter_headers,
16
22
  _is_json_content_type,
17
23
  )
18
24
  from sentry_sdk.integrations.logging import ignore_logger
19
- from sentry_sdk._compat import iteritems
20
25
 
21
26
  try:
22
- from tornado import version_info as TORNADO_VERSION # type: ignore
27
+ from tornado import version_info as TORNADO_VERSION
23
28
  from tornado.web import RequestHandler, HTTPError
24
29
  from tornado.gen import coroutine
25
30
  except ImportError:
26
31
  raise DidNotEnable("Tornado not installed")
27
32
 
28
- from sentry_sdk._types import MYPY
33
+ from typing import TYPE_CHECKING
29
34
 
30
- if MYPY:
35
+ if TYPE_CHECKING:
31
36
  from typing import Any
32
37
  from typing import Optional
33
38
  from typing import Dict
34
39
  from typing import Callable
40
+ from typing import Generator
35
41
 
36
- from sentry_sdk._types import EventProcessor
42
+ from sentry_sdk._types import Event, EventProcessor
37
43
 
38
44
 
39
45
  class TornadoIntegration(Integration):
40
46
  identifier = "tornado"
47
+ origin = f"auto.http.{identifier}"
41
48
 
42
49
  @staticmethod
43
50
  def setup_once():
44
51
  # type: () -> None
45
- if TORNADO_VERSION < (5, 0):
46
- raise DidNotEnable("Tornado 5+ required")
52
+ _check_minimum_version(TornadoIntegration, TORNADO_VERSION)
47
53
 
48
54
  if not HAS_REAL_CONTEXTVARS:
49
55
  # Tornado is async. We better have contextvars or we're going to leak
@@ -55,7 +61,7 @@ class TornadoIntegration(Integration):
55
61
 
56
62
  ignore_logger("tornado.access")
57
63
 
58
- old_execute = RequestHandler._execute # type: ignore
64
+ old_execute = RequestHandler._execute
59
65
 
60
66
  awaitable = iscoroutinefunction(old_execute)
61
67
 
@@ -63,19 +69,8 @@ class TornadoIntegration(Integration):
63
69
  # Starting Tornado 6 RequestHandler._execute method is a standard Python coroutine (async/await)
64
70
  # In that case our method should be a coroutine function too
65
71
  async def sentry_execute_request_handler(self, *args, **kwargs):
66
- # type: (Any, *Any, **Any) -> Any
67
- hub = Hub.current
68
- integration = hub.get_integration(TornadoIntegration)
69
- if integration is None:
70
- return await old_execute(self, *args, **kwargs)
71
-
72
- weak_handler = weakref.ref(self)
73
-
74
- with Hub(hub) as hub:
75
- with hub.configure_scope() as scope:
76
- scope.clear_breadcrumbs()
77
- processor = _make_event_processor(weak_handler) # type: ignore
78
- scope.add_event_processor(processor)
72
+ # type: (RequestHandler, *Any, **Any) -> Any
73
+ with _handle_request_impl(self):
79
74
  return await old_execute(self, *args, **kwargs)
80
75
 
81
76
  else:
@@ -83,57 +78,76 @@ class TornadoIntegration(Integration):
83
78
  @coroutine # type: ignore
84
79
  def sentry_execute_request_handler(self, *args, **kwargs):
85
80
  # type: (RequestHandler, *Any, **Any) -> Any
86
- hub = Hub.current
87
- integration = hub.get_integration(TornadoIntegration)
88
- if integration is None:
89
- return old_execute(self, *args, **kwargs)
90
-
91
- weak_handler = weakref.ref(self)
92
-
93
- with Hub(hub) as hub:
94
- with hub.configure_scope() as scope:
95
- scope.clear_breadcrumbs()
96
- processor = _make_event_processor(weak_handler) # type: ignore
97
- scope.add_event_processor(processor)
81
+ with _handle_request_impl(self):
98
82
  result = yield from old_execute(self, *args, **kwargs)
99
83
  return result
100
84
 
101
- RequestHandler._execute = sentry_execute_request_handler # type: ignore
85
+ RequestHandler._execute = sentry_execute_request_handler
102
86
 
103
87
  old_log_exception = RequestHandler.log_exception
104
88
 
105
89
  def sentry_log_exception(self, ty, value, tb, *args, **kwargs):
106
90
  # type: (Any, type, BaseException, Any, *Any, **Any) -> Optional[Any]
107
91
  _capture_exception(ty, value, tb)
108
- return old_log_exception(self, ty, value, tb, *args, **kwargs) # type: ignore
92
+ return old_log_exception(self, ty, value, tb, *args, **kwargs)
93
+
94
+ RequestHandler.log_exception = sentry_log_exception
95
+
96
+
97
+ @contextlib.contextmanager
98
+ def _handle_request_impl(self):
99
+ # type: (RequestHandler) -> Generator[None, None, None]
100
+ integration = sentry_sdk.get_client().get_integration(TornadoIntegration)
109
101
 
110
- RequestHandler.log_exception = sentry_log_exception # type: ignore
102
+ if integration is None:
103
+ yield
111
104
 
105
+ weak_handler = weakref.ref(self)
112
106
 
107
+ with sentry_sdk.isolation_scope() as scope:
108
+ headers = self.request.headers
109
+
110
+ scope.clear_breadcrumbs()
111
+ processor = _make_event_processor(weak_handler)
112
+ scope.add_event_processor(processor)
113
+
114
+ transaction = continue_trace(
115
+ headers,
116
+ op=OP.HTTP_SERVER,
117
+ # Like with all other integrations, this is our
118
+ # fallback transaction in case there is no route.
119
+ # sentry_urldispatcher_resolve is responsible for
120
+ # setting a transaction name later.
121
+ name="generic Tornado request",
122
+ source=TransactionSource.ROUTE,
123
+ origin=TornadoIntegration.origin,
124
+ )
125
+
126
+ with sentry_sdk.start_transaction(
127
+ transaction, custom_sampling_context={"tornado_request": self.request}
128
+ ):
129
+ yield
130
+
131
+
132
+ @ensure_integration_enabled(TornadoIntegration)
113
133
  def _capture_exception(ty, value, tb):
114
134
  # type: (type, BaseException, Any) -> None
115
- hub = Hub.current
116
- if hub.get_integration(TornadoIntegration) is None:
117
- return
118
135
  if isinstance(value, HTTPError):
119
136
  return
120
137
 
121
- # If an integration is there, a client has to be there.
122
- client = hub.client # type: Any
123
-
124
138
  event, hint = event_from_exception(
125
139
  (ty, value, tb),
126
- client_options=client.options,
140
+ client_options=sentry_sdk.get_client().options,
127
141
  mechanism={"type": "tornado", "handled": False},
128
142
  )
129
143
 
130
- hub.capture_event(event, hint=hint)
144
+ sentry_sdk.capture_event(event, hint=hint)
131
145
 
132
146
 
133
147
  def _make_event_processor(weak_handler):
134
148
  # type: (Callable[[], RequestHandler]) -> EventProcessor
135
149
  def tornado_processor(event, hint):
136
- # type: (Dict[str, Any], Dict[str, Any]) -> Dict[str, Any]
150
+ # type: (Event, dict[str, Any]) -> Event
137
151
  handler = weak_handler()
138
152
  if handler is None:
139
153
  return event
@@ -141,8 +155,9 @@ def _make_event_processor(weak_handler):
141
155
  request = handler.request
142
156
 
143
157
  with capture_internal_exceptions():
144
- method = getattr(handler, handler.request.method.lower()) # type: ignore
145
- event["transaction"] = transaction_from_function(method)
158
+ method = getattr(handler, handler.request.method.lower())
159
+ event["transaction"] = transaction_from_function(method) or ""
160
+ event["transaction_info"] = {"source": TransactionSource.COMPONENT}
146
161
 
147
162
  with capture_internal_exceptions():
148
163
  extractor = TornadoRequestExtractor(request)
@@ -162,7 +177,7 @@ def _make_event_processor(weak_handler):
162
177
  request_info["headers"] = _filter_headers(dict(request.headers))
163
178
 
164
179
  with capture_internal_exceptions():
165
- if handler.current_user and _should_send_default_pii():
180
+ if handler.current_user and should_send_default_pii():
166
181
  event.setdefault("user", {}).setdefault("is_authenticated", True)
167
182
 
168
183
  return event
@@ -179,7 +194,7 @@ class TornadoRequestExtractor(RequestExtractor):
179
194
 
180
195
  def cookies(self):
181
196
  # type: () -> Dict[str, str]
182
- return {k: v.value for k, v in iteritems(self.request.cookies)}
197
+ return {k: v.value for k, v in self.request.cookies.items()}
183
198
 
184
199
  def raw_data(self):
185
200
  # type: () -> bytes
@@ -189,7 +204,7 @@ class TornadoRequestExtractor(RequestExtractor):
189
204
  # type: () -> Dict[str, Any]
190
205
  return {
191
206
  k: [v.decode("latin1", "replace") for v in vs]
192
- for k, vs in iteritems(self.request.body_arguments)
207
+ for k, vs in self.request.body_arguments.items()
193
208
  }
194
209
 
195
210
  def is_json(self):
@@ -198,7 +213,7 @@ class TornadoRequestExtractor(RequestExtractor):
198
213
 
199
214
  def files(self):
200
215
  # type: () -> Dict[str, Any]
201
- return {k: v[0] for k, v in iteritems(self.request.files) if v}
216
+ return {k: v[0] for k, v in self.request.files.items() if v}
202
217
 
203
218
  def size_of_file(self, file):
204
219
  # type: (Any) -> int
@@ -1,46 +1,41 @@
1
- import sentry_sdk.hub
2
- import sentry_sdk.utils
3
- import sentry_sdk.integrations
4
- import sentry_sdk.integrations.wsgi
5
- from sentry_sdk._types import MYPY
1
+ import sentry_sdk
2
+ from sentry_sdk.integrations import Integration
3
+ from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware
4
+ from sentry_sdk.utils import ensure_integration_enabled, event_from_exception
6
5
 
7
6
  from trytond.exceptions import TrytonException # type: ignore
8
7
  from trytond.wsgi import app # type: ignore
9
8
 
10
- if MYPY:
11
- from typing import Any
12
-
13
9
 
14
10
  # TODO: trytond-worker, trytond-cron and trytond-admin intergations
15
11
 
16
12
 
17
- class TrytondWSGIIntegration(sentry_sdk.integrations.Integration):
13
+ class TrytondWSGIIntegration(Integration):
18
14
  identifier = "trytond_wsgi"
15
+ origin = f"auto.http.{identifier}"
19
16
 
20
17
  def __init__(self): # type: () -> None
21
18
  pass
22
19
 
23
20
  @staticmethod
24
21
  def setup_once(): # type: () -> None
22
+ app.wsgi_app = SentryWsgiMiddleware(
23
+ app.wsgi_app,
24
+ span_origin=TrytondWSGIIntegration.origin,
25
+ )
25
26
 
26
- app.wsgi_app = sentry_sdk.integrations.wsgi.SentryWsgiMiddleware(app.wsgi_app)
27
-
27
+ @ensure_integration_enabled(TrytondWSGIIntegration)
28
28
  def error_handler(e): # type: (Exception) -> None
29
- hub = sentry_sdk.hub.Hub.current
30
-
31
- if hub.get_integration(TrytondWSGIIntegration) is None:
32
- return
33
- elif isinstance(e, TrytonException):
29
+ if isinstance(e, TrytonException):
34
30
  return
35
31
  else:
36
- # If an integration is there, a client has to be there.
37
- client = hub.client # type: Any
38
- event, hint = sentry_sdk.utils.event_from_exception(
32
+ client = sentry_sdk.get_client()
33
+ event, hint = event_from_exception(
39
34
  e,
40
35
  client_options=client.options,
41
36
  mechanism={"type": "trytond", "handled": False},
42
37
  )
43
- hub.capture_event(event, hint=hint)
38
+ sentry_sdk.capture_event(event, hint=hint)
44
39
 
45
40
  # Expected error handlers signature was changed
46
41
  # when the error_handler decorator was introduced
@@ -0,0 +1,60 @@
1
+ import sentry_sdk
2
+ from sentry_sdk.utils import (
3
+ capture_internal_exceptions,
4
+ event_from_exception,
5
+ )
6
+ from sentry_sdk.integrations import Integration, DidNotEnable
7
+
8
+ from typing import TYPE_CHECKING
9
+
10
+ if TYPE_CHECKING:
11
+ from typing import Callable
12
+ from typing import Any
13
+ from typing import Type
14
+ from typing import Optional
15
+
16
+ from types import TracebackType
17
+
18
+ Excepthook = Callable[
19
+ [Type[BaseException], BaseException, Optional[TracebackType]],
20
+ Any,
21
+ ]
22
+
23
+ try:
24
+ import typer
25
+ except ImportError:
26
+ raise DidNotEnable("Typer not installed")
27
+
28
+
29
+ class TyperIntegration(Integration):
30
+ identifier = "typer"
31
+
32
+ @staticmethod
33
+ def setup_once():
34
+ # type: () -> None
35
+ typer.main.except_hook = _make_excepthook(typer.main.except_hook) # type: ignore
36
+
37
+
38
+ def _make_excepthook(old_excepthook):
39
+ # type: (Excepthook) -> Excepthook
40
+ def sentry_sdk_excepthook(type_, value, traceback):
41
+ # type: (Type[BaseException], BaseException, Optional[TracebackType]) -> None
42
+ integration = sentry_sdk.get_client().get_integration(TyperIntegration)
43
+
44
+ # Note: If we replace this with ensure_integration_enabled then
45
+ # we break the exceptiongroup backport;
46
+ # See: https://github.com/getsentry/sentry-python/issues/3097
47
+ if integration is None:
48
+ return old_excepthook(type_, value, traceback)
49
+
50
+ with capture_internal_exceptions():
51
+ event, hint = event_from_exception(
52
+ (type_, value, traceback),
53
+ client_options=sentry_sdk.get_client().options,
54
+ mechanism={"type": "typer", "handled": False},
55
+ )
56
+ sentry_sdk.capture_event(event, hint=hint)
57
+
58
+ return old_excepthook(type_, value, traceback)
59
+
60
+ return sentry_sdk_excepthook
@@ -0,0 +1,33 @@
1
+ from functools import wraps
2
+ from typing import Any
3
+
4
+ from sentry_sdk.feature_flags import add_feature_flag
5
+ from sentry_sdk.integrations import Integration, DidNotEnable
6
+
7
+ try:
8
+ from UnleashClient import UnleashClient
9
+ except ImportError:
10
+ raise DidNotEnable("UnleashClient is not installed")
11
+
12
+
13
+ class UnleashIntegration(Integration):
14
+ identifier = "unleash"
15
+
16
+ @staticmethod
17
+ def setup_once():
18
+ # type: () -> None
19
+ # Wrap and patch evaluation methods (class methods)
20
+ old_is_enabled = UnleashClient.is_enabled
21
+
22
+ @wraps(old_is_enabled)
23
+ def sentry_is_enabled(self, feature, *args, **kwargs):
24
+ # type: (UnleashClient, str, *Any, **Any) -> Any
25
+ enabled = old_is_enabled(self, feature, *args, **kwargs)
26
+
27
+ # We have no way of knowing what type of unleash feature this is, so we have to treat
28
+ # it as a boolean / toggle feature.
29
+ add_feature_flag(feature, enabled)
30
+
31
+ return enabled
32
+
33
+ UnleashClient.is_enabled = sentry_is_enabled # type: ignore
@@ -0,0 +1,53 @@
1
+ import sys
2
+
3
+ import sentry_sdk
4
+ from sentry_sdk.utils import (
5
+ capture_internal_exceptions,
6
+ event_from_exception,
7
+ )
8
+ from sentry_sdk.integrations import Integration
9
+
10
+ from typing import TYPE_CHECKING
11
+
12
+ if TYPE_CHECKING:
13
+ from typing import Callable
14
+ from typing import Any
15
+
16
+
17
+ class UnraisablehookIntegration(Integration):
18
+ identifier = "unraisablehook"
19
+
20
+ @staticmethod
21
+ def setup_once():
22
+ # type: () -> None
23
+ sys.unraisablehook = _make_unraisable(sys.unraisablehook)
24
+
25
+
26
+ def _make_unraisable(old_unraisablehook):
27
+ # type: (Callable[[sys.UnraisableHookArgs], Any]) -> Callable[[sys.UnraisableHookArgs], Any]
28
+ def sentry_sdk_unraisablehook(unraisable):
29
+ # type: (sys.UnraisableHookArgs) -> None
30
+ integration = sentry_sdk.get_client().get_integration(UnraisablehookIntegration)
31
+
32
+ # Note: If we replace this with ensure_integration_enabled then
33
+ # we break the exceptiongroup backport;
34
+ # See: https://github.com/getsentry/sentry-python/issues/3097
35
+ if integration is None:
36
+ return old_unraisablehook(unraisable)
37
+
38
+ if unraisable.exc_value and unraisable.exc_traceback:
39
+ with capture_internal_exceptions():
40
+ event, hint = event_from_exception(
41
+ (
42
+ unraisable.exc_type,
43
+ unraisable.exc_value,
44
+ unraisable.exc_traceback,
45
+ ),
46
+ client_options=sentry_sdk.get_client().options,
47
+ mechanism={"type": "unraisablehook", "handled": False},
48
+ )
49
+ sentry_sdk.capture_event(event, hint=hint)
50
+
51
+ return old_unraisablehook(unraisable)
52
+
53
+ return sentry_sdk_unraisablehook