sentry-sdk 0.7.5__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 -30
  2. sentry_sdk/_compat.py +74 -61
  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 +289 -0
  8. sentry_sdk/_types.py +338 -0
  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 +496 -80
  14. sentry_sdk/attachments.py +75 -0
  15. sentry_sdk/client.py +1023 -103
  16. sentry_sdk/consts.py +1438 -66
  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 +15 -14
  22. sentry_sdk/envelope.py +369 -0
  23. sentry_sdk/feature_flags.py +71 -0
  24. sentry_sdk/hub.py +611 -280
  25. sentry_sdk/integrations/__init__.py +276 -49
  26. sentry_sdk/integrations/_asgi_common.py +108 -0
  27. sentry_sdk/integrations/_wsgi_common.py +180 -44
  28. sentry_sdk/integrations/aiohttp.py +291 -42
  29. sentry_sdk/integrations/anthropic.py +439 -0
  30. sentry_sdk/integrations/argv.py +9 -8
  31. sentry_sdk/integrations/ariadne.py +161 -0
  32. sentry_sdk/integrations/arq.py +247 -0
  33. sentry_sdk/integrations/asgi.py +341 -0
  34. sentry_sdk/integrations/asyncio.py +144 -0
  35. sentry_sdk/integrations/asyncpg.py +208 -0
  36. sentry_sdk/integrations/atexit.py +17 -10
  37. sentry_sdk/integrations/aws_lambda.py +377 -62
  38. sentry_sdk/integrations/beam.py +176 -0
  39. sentry_sdk/integrations/boto3.py +137 -0
  40. sentry_sdk/integrations/bottle.py +221 -0
  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 +134 -0
  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 +48 -14
  49. sentry_sdk/integrations/django/__init__.py +584 -191
  50. sentry_sdk/integrations/django/asgi.py +245 -0
  51. sentry_sdk/integrations/django/caching.py +204 -0
  52. sentry_sdk/integrations/django/middleware.py +187 -0
  53. sentry_sdk/integrations/django/signals_handlers.py +91 -0
  54. sentry_sdk/integrations/django/templates.py +79 -5
  55. sentry_sdk/integrations/django/transactions.py +49 -22
  56. sentry_sdk/integrations/django/views.py +96 -0
  57. sentry_sdk/integrations/dramatiq.py +226 -0
  58. sentry_sdk/integrations/excepthook.py +50 -13
  59. sentry_sdk/integrations/executing.py +67 -0
  60. sentry_sdk/integrations/falcon.py +272 -0
  61. sentry_sdk/integrations/fastapi.py +141 -0
  62. sentry_sdk/integrations/flask.py +142 -88
  63. sentry_sdk/integrations/gcp.py +239 -0
  64. sentry_sdk/integrations/gnu_backtrace.py +99 -0
  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 +307 -96
  87. sentry_sdk/integrations/loguru.py +213 -0
  88. sentry_sdk/integrations/mcp.py +566 -0
  89. sentry_sdk/integrations/modules.py +14 -31
  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 +141 -0
  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 +112 -68
  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 +95 -37
  143. sentry_sdk/integrations/rust_tracing.py +284 -0
  144. sentry_sdk/integrations/sanic.py +294 -123
  145. sentry_sdk/integrations/serverless.py +48 -19
  146. sentry_sdk/integrations/socket.py +96 -0
  147. sentry_sdk/integrations/spark/__init__.py +4 -0
  148. sentry_sdk/integrations/spark/spark_driver.py +316 -0
  149. sentry_sdk/integrations/spark/spark_worker.py +116 -0
  150. sentry_sdk/integrations/sqlalchemy.py +142 -0
  151. sentry_sdk/integrations/starlette.py +737 -0
  152. sentry_sdk/integrations/starlite.py +292 -0
  153. sentry_sdk/integrations/statsig.py +37 -0
  154. sentry_sdk/integrations/stdlib.py +235 -29
  155. sentry_sdk/integrations/strawberry.py +394 -0
  156. sentry_sdk/integrations/sys_exit.py +70 -0
  157. sentry_sdk/integrations/threading.py +158 -28
  158. sentry_sdk/integrations/tornado.py +84 -52
  159. sentry_sdk/integrations/trytond.py +50 -0
  160. sentry_sdk/integrations/typer.py +60 -0
  161. sentry_sdk/integrations/unleash.py +33 -0
  162. sentry_sdk/integrations/unraisablehook.py +53 -0
  163. sentry_sdk/integrations/wsgi.py +201 -119
  164. sentry_sdk/logger.py +96 -0
  165. sentry_sdk/metrics.py +81 -0
  166. sentry_sdk/monitor.py +120 -0
  167. sentry_sdk/profiler/__init__.py +49 -0
  168. sentry_sdk/profiler/continuous_profiler.py +730 -0
  169. sentry_sdk/profiler/transaction_profiler.py +839 -0
  170. sentry_sdk/profiler/utils.py +195 -0
  171. sentry_sdk/py.typed +0 -0
  172. sentry_sdk/scope.py +1713 -85
  173. sentry_sdk/scrubber.py +177 -0
  174. sentry_sdk/serializer.py +405 -0
  175. sentry_sdk/session.py +177 -0
  176. sentry_sdk/sessions.py +275 -0
  177. sentry_sdk/spotlight.py +242 -0
  178. sentry_sdk/tracing.py +1486 -0
  179. sentry_sdk/tracing_utils.py +1236 -0
  180. sentry_sdk/transport.py +806 -134
  181. sentry_sdk/types.py +52 -0
  182. sentry_sdk/utils.py +1625 -465
  183. sentry_sdk/worker.py +54 -25
  184. sentry_sdk-2.46.0.dist-info/METADATA +268 -0
  185. sentry_sdk-2.46.0.dist-info/RECORD +189 -0
  186. {sentry_sdk-0.7.5.dist-info → sentry_sdk-2.46.0.dist-info}/WHEEL +1 -1
  187. sentry_sdk-2.46.0.dist-info/entry_points.txt +2 -0
  188. sentry_sdk-2.46.0.dist-info/licenses/LICENSE +21 -0
  189. sentry_sdk/integrations/celery.py +0 -119
  190. sentry_sdk-0.7.5.dist-info/LICENSE +0 -9
  191. sentry_sdk-0.7.5.dist-info/METADATA +0 -36
  192. sentry_sdk-0.7.5.dist-info/RECORD +0 -39
  193. {sentry_sdk-0.7.5.dist-info → sentry_sdk-2.46.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,195 @@
1
+ import os
2
+ from collections import deque
3
+
4
+ from sentry_sdk._compat import PY311
5
+ from sentry_sdk.utils import filename_for_module
6
+
7
+ from typing import TYPE_CHECKING
8
+
9
+ if TYPE_CHECKING:
10
+ from sentry_sdk._lru_cache import LRUCache
11
+ from types import FrameType
12
+ from typing import Deque
13
+ from typing import List
14
+ from typing import Optional
15
+ from typing import Sequence
16
+ from typing import Tuple
17
+ from typing_extensions import TypedDict
18
+
19
+ ThreadId = str
20
+
21
+ ProcessedStack = List[int]
22
+
23
+ ProcessedFrame = TypedDict(
24
+ "ProcessedFrame",
25
+ {
26
+ "abs_path": str,
27
+ "filename": Optional[str],
28
+ "function": str,
29
+ "lineno": int,
30
+ "module": Optional[str],
31
+ },
32
+ )
33
+
34
+ ProcessedThreadMetadata = TypedDict(
35
+ "ProcessedThreadMetadata",
36
+ {"name": str},
37
+ )
38
+
39
+ FrameId = Tuple[
40
+ str, # abs_path
41
+ int, # lineno
42
+ str, # function
43
+ ]
44
+ FrameIds = Tuple[FrameId, ...]
45
+
46
+ # The exact value of this id is not very meaningful. The purpose
47
+ # of this id is to give us a compact and unique identifier for a
48
+ # raw stack that can be used as a key to a dictionary so that it
49
+ # can be used during the sampled format generation.
50
+ StackId = Tuple[int, int]
51
+
52
+ ExtractedStack = Tuple[StackId, FrameIds, List[ProcessedFrame]]
53
+ ExtractedSample = Sequence[Tuple[ThreadId, ExtractedStack]]
54
+
55
+ # The default sampling frequency to use. This is set at 101 in order to
56
+ # mitigate the effects of lockstep sampling.
57
+ DEFAULT_SAMPLING_FREQUENCY = 101
58
+
59
+
60
+ # We want to impose a stack depth limit so that samples aren't too large.
61
+ MAX_STACK_DEPTH = 128
62
+
63
+
64
+ if PY311:
65
+
66
+ def get_frame_name(frame):
67
+ # type: (FrameType) -> str
68
+ return frame.f_code.co_qualname
69
+
70
+ else:
71
+
72
+ def get_frame_name(frame):
73
+ # type: (FrameType) -> str
74
+
75
+ f_code = frame.f_code
76
+ co_varnames = f_code.co_varnames
77
+
78
+ # co_name only contains the frame name. If the frame was a method,
79
+ # the class name will NOT be included.
80
+ name = f_code.co_name
81
+
82
+ # if it was a method, we can get the class name by inspecting
83
+ # the f_locals for the `self` argument
84
+ try:
85
+ if (
86
+ # the co_varnames start with the frame's positional arguments
87
+ # and we expect the first to be `self` if its an instance method
88
+ co_varnames and co_varnames[0] == "self" and "self" in frame.f_locals
89
+ ):
90
+ for cls in type(frame.f_locals["self"]).__mro__:
91
+ if name in cls.__dict__:
92
+ return "{}.{}".format(cls.__name__, name)
93
+ except (AttributeError, ValueError):
94
+ pass
95
+
96
+ # if it was a class method, (decorated with `@classmethod`)
97
+ # we can get the class name by inspecting the f_locals for the `cls` argument
98
+ try:
99
+ if (
100
+ # the co_varnames start with the frame's positional arguments
101
+ # and we expect the first to be `cls` if its a class method
102
+ co_varnames and co_varnames[0] == "cls" and "cls" in frame.f_locals
103
+ ):
104
+ for cls in frame.f_locals["cls"].__mro__:
105
+ if name in cls.__dict__:
106
+ return "{}.{}".format(cls.__name__, name)
107
+ except (AttributeError, ValueError):
108
+ pass
109
+
110
+ # nothing we can do if it is a staticmethod (decorated with @staticmethod)
111
+
112
+ # we've done all we can, time to give up and return what we have
113
+ return name
114
+
115
+
116
+ def frame_id(raw_frame):
117
+ # type: (FrameType) -> FrameId
118
+ return (raw_frame.f_code.co_filename, raw_frame.f_lineno, get_frame_name(raw_frame))
119
+
120
+
121
+ def extract_frame(fid, raw_frame, cwd):
122
+ # type: (FrameId, FrameType, str) -> ProcessedFrame
123
+ abs_path = raw_frame.f_code.co_filename
124
+
125
+ try:
126
+ module = raw_frame.f_globals["__name__"]
127
+ except Exception:
128
+ module = None
129
+
130
+ # namedtuples can be many times slower when initialing
131
+ # and accessing attribute so we opt to use a tuple here instead
132
+ return {
133
+ # This originally was `os.path.abspath(abs_path)` but that had
134
+ # a large performance overhead.
135
+ #
136
+ # According to docs, this is equivalent to
137
+ # `os.path.normpath(os.path.join(os.getcwd(), path))`.
138
+ # The `os.getcwd()` call is slow here, so we precompute it.
139
+ #
140
+ # Additionally, since we are using normalized path already,
141
+ # we skip calling `os.path.normpath` entirely.
142
+ "abs_path": os.path.join(cwd, abs_path),
143
+ "module": module,
144
+ "filename": filename_for_module(module, abs_path) or None,
145
+ "function": fid[2],
146
+ "lineno": raw_frame.f_lineno,
147
+ }
148
+
149
+
150
+ def extract_stack(
151
+ raw_frame, # type: Optional[FrameType]
152
+ cache, # type: LRUCache
153
+ cwd, # type: str
154
+ max_stack_depth=MAX_STACK_DEPTH, # type: int
155
+ ):
156
+ # type: (...) -> ExtractedStack
157
+ """
158
+ Extracts the stack starting the specified frame. The extracted stack
159
+ assumes the specified frame is the top of the stack, and works back
160
+ to the bottom of the stack.
161
+
162
+ In the event that the stack is more than `MAX_STACK_DEPTH` frames deep,
163
+ only the first `MAX_STACK_DEPTH` frames will be returned.
164
+ """
165
+
166
+ raw_frames = deque(maxlen=max_stack_depth) # type: Deque[FrameType]
167
+
168
+ while raw_frame is not None:
169
+ f_back = raw_frame.f_back
170
+ raw_frames.append(raw_frame)
171
+ raw_frame = f_back
172
+
173
+ frame_ids = tuple(frame_id(raw_frame) for raw_frame in raw_frames)
174
+ frames = []
175
+ for i, fid in enumerate(frame_ids):
176
+ frame = cache.get(fid)
177
+ if frame is None:
178
+ frame = extract_frame(fid, raw_frames[i], cwd)
179
+ cache.set(fid, frame)
180
+ frames.append(frame)
181
+
182
+ # Instead of mapping the stack into frame ids and hashing
183
+ # that as a tuple, we can directly hash the stack.
184
+ # This saves us from having to generate yet another list.
185
+ # Additionally, using the stack as the key directly is
186
+ # costly because the stack can be large, so we pre-hash
187
+ # the stack, and use the hash as the key as this will be
188
+ # needed a few times to improve performance.
189
+ #
190
+ # To Reduce the likelihood of hash collisions, we include
191
+ # the stack depth. This means that only stacks of the same
192
+ # depth can suffer from hash collisions.
193
+ stack_id = len(raw_frames), hash(frame_ids)
194
+
195
+ return stack_id, frame_ids, frames
sentry_sdk/py.typed ADDED
File without changes