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.
- sentry_sdk/__init__.py +48 -6
- sentry_sdk/_compat.py +64 -56
- sentry_sdk/_init_implementation.py +84 -0
- sentry_sdk/_log_batcher.py +172 -0
- sentry_sdk/_lru_cache.py +47 -0
- sentry_sdk/_metrics_batcher.py +167 -0
- sentry_sdk/_queue.py +81 -19
- sentry_sdk/_types.py +311 -11
- sentry_sdk/_werkzeug.py +98 -0
- sentry_sdk/ai/__init__.py +7 -0
- sentry_sdk/ai/monitoring.py +137 -0
- sentry_sdk/ai/utils.py +144 -0
- sentry_sdk/api.py +409 -67
- sentry_sdk/attachments.py +75 -0
- sentry_sdk/client.py +849 -103
- sentry_sdk/consts.py +1389 -34
- sentry_sdk/crons/__init__.py +10 -0
- sentry_sdk/crons/api.py +62 -0
- sentry_sdk/crons/consts.py +4 -0
- sentry_sdk/crons/decorator.py +135 -0
- sentry_sdk/debug.py +12 -15
- sentry_sdk/envelope.py +112 -61
- sentry_sdk/feature_flags.py +71 -0
- sentry_sdk/hub.py +442 -386
- sentry_sdk/integrations/__init__.py +228 -58
- sentry_sdk/integrations/_asgi_common.py +108 -0
- sentry_sdk/integrations/_wsgi_common.py +131 -40
- sentry_sdk/integrations/aiohttp.py +221 -72
- sentry_sdk/integrations/anthropic.py +439 -0
- sentry_sdk/integrations/argv.py +4 -6
- sentry_sdk/integrations/ariadne.py +161 -0
- sentry_sdk/integrations/arq.py +247 -0
- sentry_sdk/integrations/asgi.py +237 -135
- sentry_sdk/integrations/asyncio.py +144 -0
- sentry_sdk/integrations/asyncpg.py +208 -0
- sentry_sdk/integrations/atexit.py +13 -18
- sentry_sdk/integrations/aws_lambda.py +233 -80
- sentry_sdk/integrations/beam.py +27 -35
- sentry_sdk/integrations/boto3.py +137 -0
- sentry_sdk/integrations/bottle.py +91 -69
- sentry_sdk/integrations/celery/__init__.py +529 -0
- sentry_sdk/integrations/celery/beat.py +293 -0
- sentry_sdk/integrations/celery/utils.py +43 -0
- sentry_sdk/integrations/chalice.py +35 -28
- sentry_sdk/integrations/clickhouse_driver.py +177 -0
- sentry_sdk/integrations/cloud_resource_context.py +280 -0
- sentry_sdk/integrations/cohere.py +274 -0
- sentry_sdk/integrations/dedupe.py +32 -8
- sentry_sdk/integrations/django/__init__.py +343 -89
- sentry_sdk/integrations/django/asgi.py +201 -22
- sentry_sdk/integrations/django/caching.py +204 -0
- sentry_sdk/integrations/django/middleware.py +80 -32
- sentry_sdk/integrations/django/signals_handlers.py +91 -0
- sentry_sdk/integrations/django/templates.py +69 -2
- sentry_sdk/integrations/django/transactions.py +39 -14
- sentry_sdk/integrations/django/views.py +69 -16
- sentry_sdk/integrations/dramatiq.py +226 -0
- sentry_sdk/integrations/excepthook.py +19 -13
- sentry_sdk/integrations/executing.py +5 -6
- sentry_sdk/integrations/falcon.py +128 -65
- sentry_sdk/integrations/fastapi.py +141 -0
- sentry_sdk/integrations/flask.py +114 -75
- sentry_sdk/integrations/gcp.py +67 -36
- sentry_sdk/integrations/gnu_backtrace.py +14 -22
- sentry_sdk/integrations/google_genai/__init__.py +301 -0
- sentry_sdk/integrations/google_genai/consts.py +16 -0
- sentry_sdk/integrations/google_genai/streaming.py +155 -0
- sentry_sdk/integrations/google_genai/utils.py +576 -0
- sentry_sdk/integrations/gql.py +162 -0
- sentry_sdk/integrations/graphene.py +151 -0
- sentry_sdk/integrations/grpc/__init__.py +168 -0
- sentry_sdk/integrations/grpc/aio/__init__.py +7 -0
- sentry_sdk/integrations/grpc/aio/client.py +95 -0
- sentry_sdk/integrations/grpc/aio/server.py +100 -0
- sentry_sdk/integrations/grpc/client.py +91 -0
- sentry_sdk/integrations/grpc/consts.py +1 -0
- sentry_sdk/integrations/grpc/server.py +66 -0
- sentry_sdk/integrations/httpx.py +178 -0
- sentry_sdk/integrations/huey.py +174 -0
- sentry_sdk/integrations/huggingface_hub.py +378 -0
- sentry_sdk/integrations/langchain.py +1132 -0
- sentry_sdk/integrations/langgraph.py +337 -0
- sentry_sdk/integrations/launchdarkly.py +61 -0
- sentry_sdk/integrations/litellm.py +287 -0
- sentry_sdk/integrations/litestar.py +315 -0
- sentry_sdk/integrations/logging.py +261 -85
- sentry_sdk/integrations/loguru.py +213 -0
- sentry_sdk/integrations/mcp.py +566 -0
- sentry_sdk/integrations/modules.py +6 -33
- sentry_sdk/integrations/openai.py +725 -0
- sentry_sdk/integrations/openai_agents/__init__.py +61 -0
- sentry_sdk/integrations/openai_agents/consts.py +1 -0
- sentry_sdk/integrations/openai_agents/patches/__init__.py +5 -0
- sentry_sdk/integrations/openai_agents/patches/agent_run.py +140 -0
- sentry_sdk/integrations/openai_agents/patches/error_tracing.py +77 -0
- sentry_sdk/integrations/openai_agents/patches/models.py +50 -0
- sentry_sdk/integrations/openai_agents/patches/runner.py +45 -0
- sentry_sdk/integrations/openai_agents/patches/tools.py +77 -0
- sentry_sdk/integrations/openai_agents/spans/__init__.py +5 -0
- sentry_sdk/integrations/openai_agents/spans/agent_workflow.py +21 -0
- sentry_sdk/integrations/openai_agents/spans/ai_client.py +42 -0
- sentry_sdk/integrations/openai_agents/spans/execute_tool.py +48 -0
- sentry_sdk/integrations/openai_agents/spans/handoff.py +19 -0
- sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +86 -0
- sentry_sdk/integrations/openai_agents/utils.py +199 -0
- sentry_sdk/integrations/openfeature.py +35 -0
- sentry_sdk/integrations/opentelemetry/__init__.py +7 -0
- sentry_sdk/integrations/opentelemetry/consts.py +5 -0
- sentry_sdk/integrations/opentelemetry/integration.py +58 -0
- sentry_sdk/integrations/opentelemetry/propagator.py +117 -0
- sentry_sdk/integrations/opentelemetry/span_processor.py +391 -0
- sentry_sdk/integrations/otlp.py +82 -0
- sentry_sdk/integrations/pure_eval.py +20 -11
- sentry_sdk/integrations/pydantic_ai/__init__.py +47 -0
- sentry_sdk/integrations/pydantic_ai/consts.py +1 -0
- sentry_sdk/integrations/pydantic_ai/patches/__init__.py +4 -0
- sentry_sdk/integrations/pydantic_ai/patches/agent_run.py +215 -0
- sentry_sdk/integrations/pydantic_ai/patches/graph_nodes.py +110 -0
- sentry_sdk/integrations/pydantic_ai/patches/model_request.py +40 -0
- sentry_sdk/integrations/pydantic_ai/patches/tools.py +98 -0
- sentry_sdk/integrations/pydantic_ai/spans/__init__.py +3 -0
- sentry_sdk/integrations/pydantic_ai/spans/ai_client.py +246 -0
- sentry_sdk/integrations/pydantic_ai/spans/execute_tool.py +49 -0
- sentry_sdk/integrations/pydantic_ai/spans/invoke_agent.py +112 -0
- sentry_sdk/integrations/pydantic_ai/utils.py +223 -0
- sentry_sdk/integrations/pymongo.py +214 -0
- sentry_sdk/integrations/pyramid.py +71 -60
- sentry_sdk/integrations/quart.py +237 -0
- sentry_sdk/integrations/ray.py +165 -0
- sentry_sdk/integrations/redis/__init__.py +48 -0
- sentry_sdk/integrations/redis/_async_common.py +116 -0
- sentry_sdk/integrations/redis/_sync_common.py +119 -0
- sentry_sdk/integrations/redis/consts.py +19 -0
- sentry_sdk/integrations/redis/modules/__init__.py +0 -0
- sentry_sdk/integrations/redis/modules/caches.py +118 -0
- sentry_sdk/integrations/redis/modules/queries.py +65 -0
- sentry_sdk/integrations/redis/rb.py +32 -0
- sentry_sdk/integrations/redis/redis.py +69 -0
- sentry_sdk/integrations/redis/redis_cluster.py +107 -0
- sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +50 -0
- sentry_sdk/integrations/redis/utils.py +148 -0
- sentry_sdk/integrations/rq.py +62 -52
- sentry_sdk/integrations/rust_tracing.py +284 -0
- sentry_sdk/integrations/sanic.py +248 -114
- sentry_sdk/integrations/serverless.py +13 -22
- sentry_sdk/integrations/socket.py +96 -0
- sentry_sdk/integrations/spark/spark_driver.py +115 -62
- sentry_sdk/integrations/spark/spark_worker.py +42 -50
- sentry_sdk/integrations/sqlalchemy.py +82 -37
- sentry_sdk/integrations/starlette.py +737 -0
- sentry_sdk/integrations/starlite.py +292 -0
- sentry_sdk/integrations/statsig.py +37 -0
- sentry_sdk/integrations/stdlib.py +100 -58
- sentry_sdk/integrations/strawberry.py +394 -0
- sentry_sdk/integrations/sys_exit.py +70 -0
- sentry_sdk/integrations/threading.py +142 -38
- sentry_sdk/integrations/tornado.py +68 -53
- sentry_sdk/integrations/trytond.py +15 -20
- sentry_sdk/integrations/typer.py +60 -0
- sentry_sdk/integrations/unleash.py +33 -0
- sentry_sdk/integrations/unraisablehook.py +53 -0
- sentry_sdk/integrations/wsgi.py +126 -125
- sentry_sdk/logger.py +96 -0
- sentry_sdk/metrics.py +81 -0
- sentry_sdk/monitor.py +120 -0
- sentry_sdk/profiler/__init__.py +49 -0
- sentry_sdk/profiler/continuous_profiler.py +730 -0
- sentry_sdk/profiler/transaction_profiler.py +839 -0
- sentry_sdk/profiler/utils.py +195 -0
- sentry_sdk/scope.py +1542 -112
- sentry_sdk/scrubber.py +177 -0
- sentry_sdk/serializer.py +152 -210
- sentry_sdk/session.py +177 -0
- sentry_sdk/sessions.py +202 -179
- sentry_sdk/spotlight.py +242 -0
- sentry_sdk/tracing.py +1202 -294
- sentry_sdk/tracing_utils.py +1236 -0
- sentry_sdk/transport.py +693 -189
- sentry_sdk/types.py +52 -0
- sentry_sdk/utils.py +1395 -228
- sentry_sdk/worker.py +30 -17
- sentry_sdk-2.46.0.dist-info/METADATA +268 -0
- sentry_sdk-2.46.0.dist-info/RECORD +189 -0
- {sentry_sdk-0.18.0.dist-info → sentry_sdk-2.46.0.dist-info}/WHEEL +1 -1
- sentry_sdk-2.46.0.dist-info/entry_points.txt +2 -0
- sentry_sdk-2.46.0.dist-info/licenses/LICENSE +21 -0
- sentry_sdk/_functools.py +0 -66
- sentry_sdk/integrations/celery.py +0 -275
- sentry_sdk/integrations/redis.py +0 -103
- sentry_sdk-0.18.0.dist-info/LICENSE +0 -9
- sentry_sdk-0.18.0.dist-info/METADATA +0 -66
- sentry_sdk-0.18.0.dist-info/RECORD +0 -65
- {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)
|