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
sentry_sdk/scrubber.py ADDED
@@ -0,0 +1,177 @@
1
+ from sentry_sdk.utils import (
2
+ capture_internal_exceptions,
3
+ AnnotatedValue,
4
+ iter_event_frames,
5
+ )
6
+
7
+ from typing import TYPE_CHECKING, cast, List, Dict
8
+
9
+ if TYPE_CHECKING:
10
+ from sentry_sdk._types import Event
11
+ from typing import Optional
12
+
13
+
14
+ DEFAULT_DENYLIST = [
15
+ # stolen from relay
16
+ "password",
17
+ "passwd",
18
+ "secret",
19
+ "api_key",
20
+ "apikey",
21
+ "auth",
22
+ "credentials",
23
+ "mysql_pwd",
24
+ "privatekey",
25
+ "private_key",
26
+ "token",
27
+ "session",
28
+ # django
29
+ "csrftoken",
30
+ "sessionid",
31
+ # wsgi
32
+ "x_csrftoken",
33
+ "x_forwarded_for",
34
+ "set_cookie",
35
+ "cookie",
36
+ "authorization",
37
+ "x_api_key",
38
+ # other common names used in the wild
39
+ "aiohttp_session", # aiohttp
40
+ "connect.sid", # Express
41
+ "csrf_token", # Pyramid
42
+ "csrf", # (this is a cookie name used in accepted answers on stack overflow)
43
+ "_csrf", # Express
44
+ "_csrf_token", # Bottle
45
+ "PHPSESSID", # PHP
46
+ "_session", # Sanic
47
+ "symfony", # Symfony
48
+ "user_session", # Vue
49
+ "_xsrf", # Tornado
50
+ "XSRF-TOKEN", # Angular, Laravel
51
+ ]
52
+
53
+ DEFAULT_PII_DENYLIST = [
54
+ "x_forwarded_for",
55
+ "x_real_ip",
56
+ "ip_address",
57
+ "remote_addr",
58
+ ]
59
+
60
+
61
+ class EventScrubber:
62
+ def __init__(
63
+ self, denylist=None, recursive=False, send_default_pii=False, pii_denylist=None
64
+ ):
65
+ # type: (Optional[List[str]], bool, bool, Optional[List[str]]) -> None
66
+ """
67
+ A scrubber that goes through the event payload and removes sensitive data configured through denylists.
68
+
69
+ :param denylist: A security denylist that is always scrubbed, defaults to DEFAULT_DENYLIST.
70
+ :param recursive: Whether to scrub the event payload recursively, default False.
71
+ :param send_default_pii: Whether pii is sending is on, pii fields are not scrubbed.
72
+ :param pii_denylist: The denylist to use for scrubbing when pii is not sent, defaults to DEFAULT_PII_DENYLIST.
73
+ """
74
+ self.denylist = DEFAULT_DENYLIST.copy() if denylist is None else denylist
75
+
76
+ if not send_default_pii:
77
+ pii_denylist = (
78
+ DEFAULT_PII_DENYLIST.copy() if pii_denylist is None else pii_denylist
79
+ )
80
+ self.denylist += pii_denylist
81
+
82
+ self.denylist = [x.lower() for x in self.denylist]
83
+ self.recursive = recursive
84
+
85
+ def scrub_list(self, lst):
86
+ # type: (object) -> None
87
+ """
88
+ If a list is passed to this method, the method recursively searches the list and any
89
+ nested lists for any dictionaries. The method calls scrub_dict on all dictionaries
90
+ it finds.
91
+ If the parameter passed to this method is not a list, the method does nothing.
92
+ """
93
+ if not isinstance(lst, list):
94
+ return
95
+
96
+ for v in lst:
97
+ self.scrub_dict(v) # no-op unless v is a dict
98
+ self.scrub_list(v) # no-op unless v is a list
99
+
100
+ def scrub_dict(self, d):
101
+ # type: (object) -> None
102
+ """
103
+ If a dictionary is passed to this method, the method scrubs the dictionary of any
104
+ sensitive data. The method calls itself recursively on any nested dictionaries (
105
+ including dictionaries nested in lists) if self.recursive is True.
106
+ This method does nothing if the parameter passed to it is not a dictionary.
107
+ """
108
+ if not isinstance(d, dict):
109
+ return
110
+
111
+ for k, v in d.items():
112
+ # The cast is needed because mypy is not smart enough to figure out that k must be a
113
+ # string after the isinstance check.
114
+ if isinstance(k, str) and k.lower() in self.denylist:
115
+ d[k] = AnnotatedValue.substituted_because_contains_sensitive_data()
116
+ elif self.recursive:
117
+ self.scrub_dict(v) # no-op unless v is a dict
118
+ self.scrub_list(v) # no-op unless v is a list
119
+
120
+ def scrub_request(self, event):
121
+ # type: (Event) -> None
122
+ with capture_internal_exceptions():
123
+ if "request" in event:
124
+ if "headers" in event["request"]:
125
+ self.scrub_dict(event["request"]["headers"])
126
+ if "cookies" in event["request"]:
127
+ self.scrub_dict(event["request"]["cookies"])
128
+ if "data" in event["request"]:
129
+ self.scrub_dict(event["request"]["data"])
130
+
131
+ def scrub_extra(self, event):
132
+ # type: (Event) -> None
133
+ with capture_internal_exceptions():
134
+ if "extra" in event:
135
+ self.scrub_dict(event["extra"])
136
+
137
+ def scrub_user(self, event):
138
+ # type: (Event) -> None
139
+ with capture_internal_exceptions():
140
+ if "user" in event:
141
+ self.scrub_dict(event["user"])
142
+
143
+ def scrub_breadcrumbs(self, event):
144
+ # type: (Event) -> None
145
+ with capture_internal_exceptions():
146
+ if "breadcrumbs" in event:
147
+ if (
148
+ not isinstance(event["breadcrumbs"], AnnotatedValue)
149
+ and "values" in event["breadcrumbs"]
150
+ ):
151
+ for value in event["breadcrumbs"]["values"]:
152
+ if "data" in value:
153
+ self.scrub_dict(value["data"])
154
+
155
+ def scrub_frames(self, event):
156
+ # type: (Event) -> None
157
+ with capture_internal_exceptions():
158
+ for frame in iter_event_frames(event):
159
+ if "vars" in frame:
160
+ self.scrub_dict(frame["vars"])
161
+
162
+ def scrub_spans(self, event):
163
+ # type: (Event) -> None
164
+ with capture_internal_exceptions():
165
+ if "spans" in event:
166
+ for span in cast(List[Dict[str, object]], event["spans"]):
167
+ if "data" in span:
168
+ self.scrub_dict(span["data"])
169
+
170
+ def scrub_event(self, event):
171
+ # type: (Event) -> None
172
+ self.scrub_request(event)
173
+ self.scrub_extra(event)
174
+ self.scrub_user(event)
175
+ self.scrub_breadcrumbs(event)
176
+ self.scrub_frames(event)
177
+ self.scrub_spans(event)