sentry-sdk 3.0.0a1__py2.py3-none-any.whl → 3.0.0a3__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.
Potentially problematic release.
This version of sentry-sdk might be problematic. Click here for more details.
- sentry_sdk/__init__.py +2 -0
- sentry_sdk/_compat.py +5 -12
- sentry_sdk/_init_implementation.py +7 -7
- sentry_sdk/_log_batcher.py +17 -29
- sentry_sdk/_lru_cache.py +7 -9
- sentry_sdk/_queue.py +2 -4
- sentry_sdk/_types.py +11 -18
- sentry_sdk/_werkzeug.py +5 -7
- sentry_sdk/ai/monitoring.py +44 -31
- sentry_sdk/ai/utils.py +3 -4
- sentry_sdk/api.py +75 -87
- sentry_sdk/attachments.py +10 -12
- sentry_sdk/client.py +137 -155
- sentry_sdk/consts.py +430 -174
- sentry_sdk/crons/api.py +16 -17
- sentry_sdk/crons/decorator.py +25 -27
- sentry_sdk/debug.py +4 -6
- sentry_sdk/envelope.py +46 -112
- sentry_sdk/feature_flags.py +9 -15
- sentry_sdk/integrations/__init__.py +24 -19
- sentry_sdk/integrations/_asgi_common.py +15 -18
- sentry_sdk/integrations/_wsgi_common.py +22 -33
- sentry_sdk/integrations/aiohttp.py +32 -30
- sentry_sdk/integrations/anthropic.py +42 -37
- sentry_sdk/integrations/argv.py +3 -4
- sentry_sdk/integrations/ariadne.py +16 -18
- sentry_sdk/integrations/arq.py +21 -29
- sentry_sdk/integrations/asgi.py +63 -37
- sentry_sdk/integrations/asyncio.py +14 -16
- sentry_sdk/integrations/atexit.py +6 -10
- sentry_sdk/integrations/aws_lambda.py +26 -36
- sentry_sdk/integrations/beam.py +10 -18
- sentry_sdk/integrations/boto3.py +18 -16
- sentry_sdk/integrations/bottle.py +25 -34
- sentry_sdk/integrations/celery/__init__.py +41 -61
- sentry_sdk/integrations/celery/beat.py +23 -27
- sentry_sdk/integrations/celery/utils.py +15 -17
- sentry_sdk/integrations/chalice.py +8 -10
- sentry_sdk/integrations/clickhouse_driver.py +21 -31
- sentry_sdk/integrations/cloud_resource_context.py +9 -16
- sentry_sdk/integrations/cohere.py +27 -33
- sentry_sdk/integrations/dedupe.py +5 -8
- sentry_sdk/integrations/django/__init__.py +57 -72
- sentry_sdk/integrations/django/asgi.py +26 -34
- sentry_sdk/integrations/django/caching.py +23 -19
- sentry_sdk/integrations/django/middleware.py +17 -20
- sentry_sdk/integrations/django/signals_handlers.py +11 -10
- sentry_sdk/integrations/django/templates.py +19 -16
- sentry_sdk/integrations/django/transactions.py +16 -11
- sentry_sdk/integrations/django/views.py +6 -10
- sentry_sdk/integrations/dramatiq.py +21 -21
- sentry_sdk/integrations/excepthook.py +10 -10
- sentry_sdk/integrations/executing.py +3 -4
- sentry_sdk/integrations/falcon.py +27 -42
- sentry_sdk/integrations/fastapi.py +13 -16
- sentry_sdk/integrations/flask.py +31 -38
- sentry_sdk/integrations/gcp.py +13 -16
- sentry_sdk/integrations/gnu_backtrace.py +4 -6
- sentry_sdk/integrations/gql.py +16 -17
- sentry_sdk/integrations/graphene.py +13 -12
- sentry_sdk/integrations/grpc/__init__.py +19 -1
- sentry_sdk/integrations/grpc/aio/server.py +15 -14
- sentry_sdk/integrations/grpc/client.py +19 -9
- sentry_sdk/integrations/grpc/consts.py +2 -0
- sentry_sdk/integrations/grpc/server.py +12 -8
- sentry_sdk/integrations/httpx.py +9 -12
- sentry_sdk/integrations/huey.py +13 -20
- sentry_sdk/integrations/huggingface_hub.py +18 -18
- sentry_sdk/integrations/langchain.py +203 -113
- sentry_sdk/integrations/launchdarkly.py +13 -10
- sentry_sdk/integrations/litestar.py +37 -35
- sentry_sdk/integrations/logging.py +52 -65
- sentry_sdk/integrations/loguru.py +127 -57
- sentry_sdk/integrations/modules.py +3 -4
- sentry_sdk/integrations/openai.py +100 -88
- sentry_sdk/integrations/openai_agents/__init__.py +49 -0
- sentry_sdk/integrations/openai_agents/consts.py +1 -0
- sentry_sdk/integrations/openai_agents/patches/__init__.py +4 -0
- sentry_sdk/integrations/openai_agents/patches/agent_run.py +152 -0
- sentry_sdk/integrations/openai_agents/patches/models.py +52 -0
- sentry_sdk/integrations/openai_agents/patches/runner.py +42 -0
- sentry_sdk/integrations/openai_agents/patches/tools.py +84 -0
- sentry_sdk/integrations/openai_agents/spans/__init__.py +5 -0
- sentry_sdk/integrations/openai_agents/spans/agent_workflow.py +20 -0
- sentry_sdk/integrations/openai_agents/spans/ai_client.py +46 -0
- sentry_sdk/integrations/openai_agents/spans/execute_tool.py +47 -0
- sentry_sdk/integrations/openai_agents/spans/handoff.py +24 -0
- sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +41 -0
- sentry_sdk/integrations/openai_agents/utils.py +201 -0
- sentry_sdk/integrations/openfeature.py +11 -6
- sentry_sdk/integrations/pure_eval.py +6 -10
- sentry_sdk/integrations/pymongo.py +13 -17
- sentry_sdk/integrations/pyramid.py +31 -36
- sentry_sdk/integrations/quart.py +23 -28
- sentry_sdk/integrations/ray.py +73 -64
- sentry_sdk/integrations/redis/__init__.py +7 -4
- sentry_sdk/integrations/redis/_async_common.py +25 -12
- sentry_sdk/integrations/redis/_sync_common.py +19 -13
- sentry_sdk/integrations/redis/modules/caches.py +17 -8
- sentry_sdk/integrations/redis/modules/queries.py +9 -8
- sentry_sdk/integrations/redis/rb.py +3 -2
- sentry_sdk/integrations/redis/redis.py +4 -4
- sentry_sdk/integrations/redis/redis_cluster.py +21 -13
- sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +3 -2
- sentry_sdk/integrations/redis/utils.py +23 -24
- sentry_sdk/integrations/rq.py +13 -16
- sentry_sdk/integrations/rust_tracing.py +9 -6
- sentry_sdk/integrations/sanic.py +34 -46
- sentry_sdk/integrations/serverless.py +22 -27
- sentry_sdk/integrations/socket.py +27 -15
- sentry_sdk/integrations/spark/__init__.py +1 -0
- sentry_sdk/integrations/spark/spark_driver.py +45 -83
- sentry_sdk/integrations/spark/spark_worker.py +7 -11
- sentry_sdk/integrations/sqlalchemy.py +22 -19
- sentry_sdk/integrations/starlette.py +86 -90
- sentry_sdk/integrations/starlite.py +28 -34
- sentry_sdk/integrations/statsig.py +5 -4
- sentry_sdk/integrations/stdlib.py +28 -24
- sentry_sdk/integrations/strawberry.py +62 -49
- sentry_sdk/integrations/sys_exit.py +7 -11
- sentry_sdk/integrations/threading.py +12 -14
- sentry_sdk/integrations/tornado.py +28 -32
- sentry_sdk/integrations/trytond.py +4 -3
- sentry_sdk/integrations/typer.py +8 -6
- sentry_sdk/integrations/unleash.py +5 -4
- sentry_sdk/integrations/wsgi.py +47 -46
- sentry_sdk/logger.py +41 -10
- sentry_sdk/monitor.py +16 -28
- sentry_sdk/opentelemetry/consts.py +11 -4
- sentry_sdk/opentelemetry/contextvars_context.py +26 -16
- sentry_sdk/opentelemetry/propagator.py +38 -21
- sentry_sdk/opentelemetry/sampler.py +51 -34
- sentry_sdk/opentelemetry/scope.py +36 -37
- sentry_sdk/opentelemetry/span_processor.py +48 -58
- sentry_sdk/opentelemetry/tracing.py +58 -14
- sentry_sdk/opentelemetry/utils.py +186 -194
- sentry_sdk/profiler/continuous_profiler.py +108 -97
- sentry_sdk/profiler/transaction_profiler.py +70 -97
- sentry_sdk/profiler/utils.py +11 -15
- sentry_sdk/scope.py +251 -273
- sentry_sdk/scrubber.py +22 -26
- sentry_sdk/serializer.py +40 -54
- sentry_sdk/session.py +44 -61
- sentry_sdk/sessions.py +35 -49
- sentry_sdk/spotlight.py +15 -21
- sentry_sdk/tracing.py +121 -187
- sentry_sdk/tracing_utils.py +104 -122
- sentry_sdk/transport.py +131 -157
- sentry_sdk/utils.py +232 -309
- sentry_sdk/worker.py +16 -28
- {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/METADATA +3 -3
- sentry_sdk-3.0.0a3.dist-info/RECORD +168 -0
- {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/WHEEL +1 -1
- sentry_sdk-3.0.0a1.dist-info/RECORD +0 -154
- {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/entry_points.txt +0 -0
- {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/licenses/LICENSE +0 -0
- {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/top_level.txt +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import asyncio
|
|
2
3
|
import functools
|
|
3
4
|
from collections.abc import Set
|
|
@@ -82,12 +83,11 @@ class StarletteIntegration(Integration):
|
|
|
82
83
|
|
|
83
84
|
def __init__(
|
|
84
85
|
self,
|
|
85
|
-
transaction_style="url",
|
|
86
|
-
failed_request_status_codes
|
|
87
|
-
middleware_spans=True,
|
|
88
|
-
http_methods_to_capture
|
|
89
|
-
):
|
|
90
|
-
# type: (...) -> None
|
|
86
|
+
transaction_style: str = "url",
|
|
87
|
+
failed_request_status_codes: Set[int] = _DEFAULT_FAILED_REQUEST_STATUS_CODES,
|
|
88
|
+
middleware_spans: bool = True,
|
|
89
|
+
http_methods_to_capture: tuple[str, ...] = DEFAULT_HTTP_METHODS_TO_CAPTURE,
|
|
90
|
+
) -> None:
|
|
91
91
|
if transaction_style not in TRANSACTION_STYLE_VALUES:
|
|
92
92
|
raise ValueError(
|
|
93
93
|
"Invalid value for transaction_style: %s (must be in %s)"
|
|
@@ -100,8 +100,7 @@ class StarletteIntegration(Integration):
|
|
|
100
100
|
self.failed_request_status_codes = failed_request_status_codes
|
|
101
101
|
|
|
102
102
|
@staticmethod
|
|
103
|
-
def setup_once():
|
|
104
|
-
# type: () -> None
|
|
103
|
+
def setup_once() -> None:
|
|
105
104
|
version = parse_version(STARLETTE_VERSION)
|
|
106
105
|
|
|
107
106
|
if version is None:
|
|
@@ -117,12 +116,16 @@ class StarletteIntegration(Integration):
|
|
|
117
116
|
patch_templates()
|
|
118
117
|
|
|
119
118
|
|
|
120
|
-
def _enable_span_for_middleware(middleware_class):
|
|
121
|
-
# type: (Any) -> type
|
|
119
|
+
def _enable_span_for_middleware(middleware_class: Any) -> type:
|
|
122
120
|
old_call = middleware_class.__call__
|
|
123
121
|
|
|
124
|
-
async def _create_span_call(
|
|
125
|
-
|
|
122
|
+
async def _create_span_call(
|
|
123
|
+
app: Any,
|
|
124
|
+
scope: Dict[str, Any],
|
|
125
|
+
receive: Callable[[], Awaitable[Dict[str, Any]]],
|
|
126
|
+
send: Callable[[Dict[str, Any]], Awaitable[None]],
|
|
127
|
+
**kwargs: Any,
|
|
128
|
+
) -> None:
|
|
126
129
|
integration = sentry_sdk.get_client().get_integration(StarletteIntegration)
|
|
127
130
|
if integration is None or not integration.middleware_spans:
|
|
128
131
|
return await old_call(app, scope, receive, send, **kwargs)
|
|
@@ -146,8 +149,7 @@ def _enable_span_for_middleware(middleware_class):
|
|
|
146
149
|
middleware_span.set_tag("starlette.middleware_name", middleware_name)
|
|
147
150
|
|
|
148
151
|
# Creating spans for the "receive" callback
|
|
149
|
-
async def _sentry_receive(*args, **kwargs):
|
|
150
|
-
# type: (*Any, **Any) -> Any
|
|
152
|
+
async def _sentry_receive(*args: Any, **kwargs: Any) -> Any:
|
|
151
153
|
with sentry_sdk.start_span(
|
|
152
154
|
op=OP.MIDDLEWARE_STARLETTE_RECEIVE,
|
|
153
155
|
name=getattr(receive, "__qualname__", str(receive)),
|
|
@@ -162,8 +164,7 @@ def _enable_span_for_middleware(middleware_class):
|
|
|
162
164
|
new_receive = _sentry_receive if not receive_patched else receive
|
|
163
165
|
|
|
164
166
|
# Creating spans for the "send" callback
|
|
165
|
-
async def _sentry_send(*args, **kwargs):
|
|
166
|
-
# type: (*Any, **Any) -> Any
|
|
167
|
+
async def _sentry_send(*args: Any, **kwargs: Any) -> Any:
|
|
167
168
|
with sentry_sdk.start_span(
|
|
168
169
|
op=OP.MIDDLEWARE_STARLETTE_SEND,
|
|
169
170
|
name=getattr(send, "__qualname__", str(send)),
|
|
@@ -192,8 +193,7 @@ def _enable_span_for_middleware(middleware_class):
|
|
|
192
193
|
|
|
193
194
|
|
|
194
195
|
@ensure_integration_enabled(StarletteIntegration)
|
|
195
|
-
def _capture_exception(exception, handled=False):
|
|
196
|
-
# type: (BaseException, **Any) -> None
|
|
196
|
+
def _capture_exception(exception: BaseException, handled: Any = False) -> None:
|
|
197
197
|
event, hint = event_from_exception(
|
|
198
198
|
exception,
|
|
199
199
|
client_options=sentry_sdk.get_client().options,
|
|
@@ -203,8 +203,7 @@ def _capture_exception(exception, handled=False):
|
|
|
203
203
|
sentry_sdk.capture_event(event, hint=hint)
|
|
204
204
|
|
|
205
205
|
|
|
206
|
-
def patch_exception_middleware(middleware_class):
|
|
207
|
-
# type: (Any) -> None
|
|
206
|
+
def patch_exception_middleware(middleware_class: Any) -> None:
|
|
208
207
|
"""
|
|
209
208
|
Capture all exceptions in Starlette app and
|
|
210
209
|
also extract user information.
|
|
@@ -215,15 +214,15 @@ def patch_exception_middleware(middleware_class):
|
|
|
215
214
|
|
|
216
215
|
if not_yet_patched:
|
|
217
216
|
|
|
218
|
-
def _sentry_middleware_init(self, *args, **kwargs):
|
|
219
|
-
# type: (Any, Any, Any) -> None
|
|
217
|
+
def _sentry_middleware_init(self: Any, *args: Any, **kwargs: Any) -> None:
|
|
220
218
|
old_middleware_init(self, *args, **kwargs)
|
|
221
219
|
|
|
222
220
|
# Patch existing exception handlers
|
|
223
221
|
old_handlers = self._exception_handlers.copy()
|
|
224
222
|
|
|
225
|
-
async def _sentry_patched_exception_handler(
|
|
226
|
-
|
|
223
|
+
async def _sentry_patched_exception_handler(
|
|
224
|
+
self: Any, *args: Any, **kwargs: Any
|
|
225
|
+
) -> None:
|
|
227
226
|
integration = sentry_sdk.get_client().get_integration(
|
|
228
227
|
StarletteIntegration
|
|
229
228
|
)
|
|
@@ -261,8 +260,12 @@ def patch_exception_middleware(middleware_class):
|
|
|
261
260
|
|
|
262
261
|
old_call = middleware_class.__call__
|
|
263
262
|
|
|
264
|
-
async def _sentry_exceptionmiddleware_call(
|
|
265
|
-
|
|
263
|
+
async def _sentry_exceptionmiddleware_call(
|
|
264
|
+
self: Dict[str, Any],
|
|
265
|
+
scope: Dict[str, Any],
|
|
266
|
+
receive: Callable[[], Awaitable[Dict[str, Any]]],
|
|
267
|
+
send: Callable[[Dict[str, Any]], Awaitable[None]],
|
|
268
|
+
) -> None:
|
|
266
269
|
# Also add the user (that was eventually set by be Authentication middle
|
|
267
270
|
# that was called before this middleware). This is done because the authentication
|
|
268
271
|
# middleware sets the user in the scope and then (in the same function)
|
|
@@ -281,8 +284,7 @@ def patch_exception_middleware(middleware_class):
|
|
|
281
284
|
|
|
282
285
|
|
|
283
286
|
@ensure_integration_enabled(StarletteIntegration)
|
|
284
|
-
def _add_user_to_sentry_scope(scope):
|
|
285
|
-
# type: (Dict[str, Any]) -> None
|
|
287
|
+
def _add_user_to_sentry_scope(scope: Dict[str, Any]) -> None:
|
|
286
288
|
"""
|
|
287
289
|
Extracts user information from the ASGI scope and
|
|
288
290
|
adds it to Sentry's scope.
|
|
@@ -293,7 +295,7 @@ def _add_user_to_sentry_scope(scope):
|
|
|
293
295
|
if not should_send_default_pii():
|
|
294
296
|
return
|
|
295
297
|
|
|
296
|
-
user_info
|
|
298
|
+
user_info: Dict[str, Any] = {}
|
|
297
299
|
starlette_user = scope["user"]
|
|
298
300
|
|
|
299
301
|
username = getattr(starlette_user, "username", None)
|
|
@@ -312,8 +314,7 @@ def _add_user_to_sentry_scope(scope):
|
|
|
312
314
|
sentry_scope.set_user(user_info)
|
|
313
315
|
|
|
314
316
|
|
|
315
|
-
def patch_authentication_middleware(middleware_class):
|
|
316
|
-
# type: (Any) -> None
|
|
317
|
+
def patch_authentication_middleware(middleware_class: Any) -> None:
|
|
317
318
|
"""
|
|
318
319
|
Add user information to Sentry scope.
|
|
319
320
|
"""
|
|
@@ -323,16 +324,19 @@ def patch_authentication_middleware(middleware_class):
|
|
|
323
324
|
|
|
324
325
|
if not_yet_patched:
|
|
325
326
|
|
|
326
|
-
async def _sentry_authenticationmiddleware_call(
|
|
327
|
-
|
|
327
|
+
async def _sentry_authenticationmiddleware_call(
|
|
328
|
+
self: Dict[str, Any],
|
|
329
|
+
scope: Dict[str, Any],
|
|
330
|
+
receive: Callable[[], Awaitable[Dict[str, Any]]],
|
|
331
|
+
send: Callable[[Dict[str, Any]], Awaitable[None]],
|
|
332
|
+
) -> None:
|
|
328
333
|
await old_call(self, scope, receive, send)
|
|
329
334
|
_add_user_to_sentry_scope(scope)
|
|
330
335
|
|
|
331
336
|
middleware_class.__call__ = _sentry_authenticationmiddleware_call
|
|
332
337
|
|
|
333
338
|
|
|
334
|
-
def patch_middlewares():
|
|
335
|
-
# type: () -> None
|
|
339
|
+
def patch_middlewares() -> None:
|
|
336
340
|
"""
|
|
337
341
|
Patches Starlettes `Middleware` class to record
|
|
338
342
|
spans for every middleware invoked.
|
|
@@ -343,8 +347,9 @@ def patch_middlewares():
|
|
|
343
347
|
|
|
344
348
|
if not_yet_patched:
|
|
345
349
|
|
|
346
|
-
def _sentry_middleware_init(
|
|
347
|
-
|
|
350
|
+
def _sentry_middleware_init(
|
|
351
|
+
self: Any, cls: Any, *args: Any, **kwargs: Any
|
|
352
|
+
) -> None:
|
|
348
353
|
if cls == SentryAsgiMiddleware:
|
|
349
354
|
return old_middleware_init(self, cls, *args, **kwargs)
|
|
350
355
|
|
|
@@ -360,15 +365,15 @@ def patch_middlewares():
|
|
|
360
365
|
Middleware.__init__ = _sentry_middleware_init
|
|
361
366
|
|
|
362
367
|
|
|
363
|
-
def patch_asgi_app():
|
|
364
|
-
# type: () -> None
|
|
368
|
+
def patch_asgi_app() -> None:
|
|
365
369
|
"""
|
|
366
370
|
Instrument Starlette ASGI app using the SentryAsgiMiddleware.
|
|
367
371
|
"""
|
|
368
372
|
old_app = Starlette.__call__
|
|
369
373
|
|
|
370
|
-
async def _sentry_patched_asgi_app(
|
|
371
|
-
|
|
374
|
+
async def _sentry_patched_asgi_app(
|
|
375
|
+
self: Starlette, scope: StarletteScope, receive: Receive, send: Send
|
|
376
|
+
) -> None:
|
|
372
377
|
integration = sentry_sdk.get_client().get_integration(StarletteIntegration)
|
|
373
378
|
if integration is None:
|
|
374
379
|
return await old_app(self, scope, receive, send)
|
|
@@ -393,8 +398,7 @@ def patch_asgi_app():
|
|
|
393
398
|
|
|
394
399
|
# This was vendored in from Starlette to support Starlette 0.19.1 because
|
|
395
400
|
# this function was only introduced in 0.20.x
|
|
396
|
-
def _is_async_callable(obj):
|
|
397
|
-
# type: (Any) -> bool
|
|
401
|
+
def _is_async_callable(obj: Any) -> bool:
|
|
398
402
|
while isinstance(obj, functools.partial):
|
|
399
403
|
obj = obj.func
|
|
400
404
|
|
|
@@ -403,19 +407,16 @@ def _is_async_callable(obj):
|
|
|
403
407
|
)
|
|
404
408
|
|
|
405
409
|
|
|
406
|
-
def patch_request_response():
|
|
407
|
-
# type: () -> None
|
|
410
|
+
def patch_request_response() -> None:
|
|
408
411
|
old_request_response = starlette.routing.request_response
|
|
409
412
|
|
|
410
|
-
def _sentry_request_response(func):
|
|
411
|
-
# type: (Callable[[Any], Any]) -> ASGIApp
|
|
413
|
+
def _sentry_request_response(func: Callable[[Any], Any]) -> ASGIApp:
|
|
412
414
|
old_func = func
|
|
413
415
|
|
|
414
416
|
is_coroutine = _is_async_callable(old_func)
|
|
415
417
|
if is_coroutine:
|
|
416
418
|
|
|
417
|
-
async def _sentry_async_func(*args, **kwargs):
|
|
418
|
-
# type: (*Any, **Any) -> Any
|
|
419
|
+
async def _sentry_async_func(*args: Any, **kwargs: Any) -> Any:
|
|
419
420
|
integration = sentry_sdk.get_client().get_integration(
|
|
420
421
|
StarletteIntegration
|
|
421
422
|
)
|
|
@@ -434,10 +435,10 @@ def patch_request_response():
|
|
|
434
435
|
extractor = StarletteRequestExtractor(request)
|
|
435
436
|
info = await extractor.extract_request_info()
|
|
436
437
|
|
|
437
|
-
def _make_request_event_processor(
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
438
|
+
def _make_request_event_processor(
|
|
439
|
+
req: Any, integration: Any
|
|
440
|
+
) -> Callable[[Event, dict[str, Any]], Event]:
|
|
441
|
+
def event_processor(event: Event, hint: Dict[str, Any]) -> Event:
|
|
441
442
|
|
|
442
443
|
# Add info from request to event
|
|
443
444
|
request_info = event.get("request", {})
|
|
@@ -464,8 +465,7 @@ def patch_request_response():
|
|
|
464
465
|
else:
|
|
465
466
|
|
|
466
467
|
@functools.wraps(old_func)
|
|
467
|
-
def _sentry_sync_func(*args, **kwargs):
|
|
468
|
-
# type: (*Any, **Any) -> Any
|
|
468
|
+
def _sentry_sync_func(*args: Any, **kwargs: Any) -> Any:
|
|
469
469
|
integration = sentry_sdk.get_client().get_integration(
|
|
470
470
|
StarletteIntegration
|
|
471
471
|
)
|
|
@@ -489,10 +489,10 @@ def patch_request_response():
|
|
|
489
489
|
extractor = StarletteRequestExtractor(request)
|
|
490
490
|
cookies = extractor.extract_cookies_from_request()
|
|
491
491
|
|
|
492
|
-
def _make_request_event_processor(
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
492
|
+
def _make_request_event_processor(
|
|
493
|
+
req: Any, integration: Any
|
|
494
|
+
) -> Callable[[Event, dict[str, Any]], Event]:
|
|
495
|
+
def event_processor(event: Event, hint: dict[str, Any]) -> Event:
|
|
496
496
|
|
|
497
497
|
# Extract information from request
|
|
498
498
|
request_info = event.get("request", {})
|
|
@@ -519,8 +519,7 @@ def patch_request_response():
|
|
|
519
519
|
starlette.routing.request_response = _sentry_request_response
|
|
520
520
|
|
|
521
521
|
|
|
522
|
-
def patch_templates():
|
|
523
|
-
# type: () -> None
|
|
522
|
+
def patch_templates() -> None:
|
|
524
523
|
|
|
525
524
|
# If markupsafe is not installed, then Jinja2 is not installed
|
|
526
525
|
# (markupsafe is a dependency of Jinja2)
|
|
@@ -540,10 +539,10 @@ def patch_templates():
|
|
|
540
539
|
|
|
541
540
|
if not_yet_patched:
|
|
542
541
|
|
|
543
|
-
def _sentry_jinja2templates_init(
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
542
|
+
def _sentry_jinja2templates_init(
|
|
543
|
+
self: Jinja2Templates, *args: Any, **kwargs: Any
|
|
544
|
+
) -> None:
|
|
545
|
+
def add_sentry_trace_meta(request: Request) -> Dict[str, Any]:
|
|
547
546
|
trace_meta = Markup(
|
|
548
547
|
sentry_sdk.get_current_scope().trace_propagation_meta()
|
|
549
548
|
)
|
|
@@ -567,25 +566,26 @@ class StarletteRequestExtractor:
|
|
|
567
566
|
(like form data or cookies) and adds it to the Sentry event.
|
|
568
567
|
"""
|
|
569
568
|
|
|
570
|
-
request = None
|
|
569
|
+
request: Request = None
|
|
571
570
|
|
|
572
|
-
def __init__(self, request):
|
|
573
|
-
# type: (StarletteRequestExtractor, Request) -> None
|
|
571
|
+
def __init__(self: StarletteRequestExtractor, request: Request) -> None:
|
|
574
572
|
self.request = request
|
|
575
573
|
|
|
576
|
-
def extract_cookies_from_request(
|
|
577
|
-
|
|
578
|
-
|
|
574
|
+
def extract_cookies_from_request(
|
|
575
|
+
self: StarletteRequestExtractor,
|
|
576
|
+
) -> Optional[Dict[str, Any]]:
|
|
577
|
+
cookies: Optional[Dict[str, Any]] = None
|
|
579
578
|
if should_send_default_pii():
|
|
580
579
|
cookies = self.cookies()
|
|
581
580
|
|
|
582
581
|
return cookies
|
|
583
582
|
|
|
584
|
-
async def extract_request_info(
|
|
585
|
-
|
|
583
|
+
async def extract_request_info(
|
|
584
|
+
self: StarletteRequestExtractor,
|
|
585
|
+
) -> Optional[Dict[str, Any]]:
|
|
586
586
|
client = sentry_sdk.get_client()
|
|
587
587
|
|
|
588
|
-
request_info
|
|
588
|
+
request_info: Dict[str, Any] = {}
|
|
589
589
|
|
|
590
590
|
with capture_internal_exceptions():
|
|
591
591
|
# Add cookies
|
|
@@ -629,19 +629,16 @@ class StarletteRequestExtractor:
|
|
|
629
629
|
request_info["data"] = AnnotatedValue.removed_because_raw_data()
|
|
630
630
|
return request_info
|
|
631
631
|
|
|
632
|
-
async def content_length(self):
|
|
633
|
-
# type: (StarletteRequestExtractor) -> Optional[int]
|
|
632
|
+
async def content_length(self: StarletteRequestExtractor) -> Optional[int]:
|
|
634
633
|
if "content-length" in self.request.headers:
|
|
635
634
|
return int(self.request.headers["content-length"])
|
|
636
635
|
|
|
637
636
|
return None
|
|
638
637
|
|
|
639
|
-
def cookies(self):
|
|
640
|
-
# type: (StarletteRequestExtractor) -> Dict[str, Any]
|
|
638
|
+
def cookies(self: StarletteRequestExtractor) -> Dict[str, Any]:
|
|
641
639
|
return self.request.cookies
|
|
642
640
|
|
|
643
|
-
async def form(self):
|
|
644
|
-
# type: (StarletteRequestExtractor) -> Any
|
|
641
|
+
async def form(self: StarletteRequestExtractor) -> Any:
|
|
645
642
|
if multipart is None:
|
|
646
643
|
return None
|
|
647
644
|
|
|
@@ -653,12 +650,10 @@ class StarletteRequestExtractor:
|
|
|
653
650
|
|
|
654
651
|
return await self.request.form()
|
|
655
652
|
|
|
656
|
-
def is_json(self):
|
|
657
|
-
# type: (StarletteRequestExtractor) -> bool
|
|
653
|
+
def is_json(self: StarletteRequestExtractor) -> bool:
|
|
658
654
|
return _is_json_content_type(self.request.headers.get("content-type"))
|
|
659
655
|
|
|
660
|
-
async def json(self):
|
|
661
|
-
# type: (StarletteRequestExtractor) -> Optional[Dict[str, Any]]
|
|
656
|
+
async def json(self: StarletteRequestExtractor) -> Optional[Dict[str, Any]]:
|
|
662
657
|
if not self.is_json():
|
|
663
658
|
return None
|
|
664
659
|
try:
|
|
@@ -667,8 +662,7 @@ class StarletteRequestExtractor:
|
|
|
667
662
|
return None
|
|
668
663
|
|
|
669
664
|
|
|
670
|
-
def _transaction_name_from_router(scope):
|
|
671
|
-
# type: (StarletteScope) -> Optional[str]
|
|
665
|
+
def _transaction_name_from_router(scope: StarletteScope) -> Optional[str]:
|
|
672
666
|
router = scope.get("router")
|
|
673
667
|
if not router:
|
|
674
668
|
return None
|
|
@@ -685,8 +679,9 @@ def _transaction_name_from_router(scope):
|
|
|
685
679
|
return None
|
|
686
680
|
|
|
687
681
|
|
|
688
|
-
def _set_transaction_name_and_source(
|
|
689
|
-
|
|
682
|
+
def _set_transaction_name_and_source(
|
|
683
|
+
scope: sentry_sdk.Scope, transaction_style: str, request: Any
|
|
684
|
+
) -> None:
|
|
690
685
|
name = None
|
|
691
686
|
source = SOURCE_FOR_STYLE[transaction_style]
|
|
692
687
|
|
|
@@ -708,8 +703,9 @@ def _set_transaction_name_and_source(scope, transaction_style, request):
|
|
|
708
703
|
)
|
|
709
704
|
|
|
710
705
|
|
|
711
|
-
def _get_transaction_from_middleware(
|
|
712
|
-
|
|
706
|
+
def _get_transaction_from_middleware(
|
|
707
|
+
app: Any, asgi_scope: Dict[str, Any], integration: StarletteIntegration
|
|
708
|
+
) -> Tuple[Optional[str], Optional[str]]:
|
|
713
709
|
name = None
|
|
714
710
|
source = None
|
|
715
711
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import sentry_sdk
|
|
2
3
|
from sentry_sdk.consts import OP, SOURCE_FOR_STYLE, TransactionSource
|
|
3
4
|
from sentry_sdk.integrations import DidNotEnable, Integration
|
|
@@ -48,16 +49,16 @@ class StarliteIntegration(Integration):
|
|
|
48
49
|
origin = f"auto.http.{identifier}"
|
|
49
50
|
|
|
50
51
|
@staticmethod
|
|
51
|
-
def setup_once():
|
|
52
|
-
# type: () -> None
|
|
52
|
+
def setup_once() -> None:
|
|
53
53
|
patch_app_init()
|
|
54
54
|
patch_middlewares()
|
|
55
55
|
patch_http_route_handle()
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
class SentryStarliteASGIMiddleware(SentryAsgiMiddleware):
|
|
59
|
-
def __init__(
|
|
60
|
-
|
|
59
|
+
def __init__(
|
|
60
|
+
self, app: ASGIApp, span_origin: str = StarliteIntegration.origin
|
|
61
|
+
) -> None:
|
|
61
62
|
super().__init__(
|
|
62
63
|
app=app,
|
|
63
64
|
unsafe_context_data=False,
|
|
@@ -67,8 +68,7 @@ class SentryStarliteASGIMiddleware(SentryAsgiMiddleware):
|
|
|
67
68
|
)
|
|
68
69
|
|
|
69
70
|
|
|
70
|
-
def patch_app_init():
|
|
71
|
-
# type: () -> None
|
|
71
|
+
def patch_app_init() -> None:
|
|
72
72
|
"""
|
|
73
73
|
Replaces the Starlite class's `__init__` function in order to inject `after_exception` handlers and set the
|
|
74
74
|
`SentryStarliteASGIMiddleware` as the outmost middleware in the stack.
|
|
@@ -79,8 +79,7 @@ def patch_app_init():
|
|
|
79
79
|
old__init__ = Starlite.__init__
|
|
80
80
|
|
|
81
81
|
@ensure_integration_enabled(StarliteIntegration, old__init__)
|
|
82
|
-
def injection_wrapper(self, *args, **kwargs):
|
|
83
|
-
# type: (Starlite, *Any, **Any) -> None
|
|
82
|
+
def injection_wrapper(self: Starlite, *args: Any, **kwargs: Any) -> None:
|
|
84
83
|
after_exception = kwargs.pop("after_exception", [])
|
|
85
84
|
kwargs.update(
|
|
86
85
|
after_exception=[
|
|
@@ -101,13 +100,11 @@ def patch_app_init():
|
|
|
101
100
|
Starlite.__init__ = injection_wrapper
|
|
102
101
|
|
|
103
102
|
|
|
104
|
-
def patch_middlewares():
|
|
105
|
-
# type: () -> None
|
|
103
|
+
def patch_middlewares() -> None:
|
|
106
104
|
old_resolve_middleware_stack = BaseRouteHandler.resolve_middleware
|
|
107
105
|
|
|
108
106
|
@ensure_integration_enabled(StarliteIntegration, old_resolve_middleware_stack)
|
|
109
|
-
def resolve_middleware_wrapper(self):
|
|
110
|
-
# type: (BaseRouteHandler) -> list[Middleware]
|
|
107
|
+
def resolve_middleware_wrapper(self: BaseRouteHandler) -> list[Middleware]:
|
|
111
108
|
return [
|
|
112
109
|
enable_span_for_middleware(middleware)
|
|
113
110
|
for middleware in old_resolve_middleware_stack(self)
|
|
@@ -116,8 +113,7 @@ def patch_middlewares():
|
|
|
116
113
|
BaseRouteHandler.resolve_middleware = resolve_middleware_wrapper
|
|
117
114
|
|
|
118
115
|
|
|
119
|
-
def enable_span_for_middleware(middleware):
|
|
120
|
-
# type: (Middleware) -> Middleware
|
|
116
|
+
def enable_span_for_middleware(middleware: Middleware) -> Middleware:
|
|
121
117
|
if (
|
|
122
118
|
not hasattr(middleware, "__call__") # noqa: B004
|
|
123
119
|
or middleware is SentryStarliteASGIMiddleware
|
|
@@ -125,12 +121,13 @@ def enable_span_for_middleware(middleware):
|
|
|
125
121
|
return middleware
|
|
126
122
|
|
|
127
123
|
if isinstance(middleware, DefineMiddleware):
|
|
128
|
-
old_call = middleware.middleware.__call__
|
|
124
|
+
old_call: ASGIApp = middleware.middleware.__call__
|
|
129
125
|
else:
|
|
130
126
|
old_call = middleware.__call__
|
|
131
127
|
|
|
132
|
-
async def _create_span_call(
|
|
133
|
-
|
|
128
|
+
async def _create_span_call(
|
|
129
|
+
self: MiddlewareProtocol, scope: StarliteScope, receive: Receive, send: Send
|
|
130
|
+
) -> None:
|
|
134
131
|
if sentry_sdk.get_client().get_integration(StarliteIntegration) is None:
|
|
135
132
|
return await old_call(self, scope, receive, send)
|
|
136
133
|
|
|
@@ -144,8 +141,9 @@ def enable_span_for_middleware(middleware):
|
|
|
144
141
|
middleware_span.set_tag("starlite.middleware_name", middleware_name)
|
|
145
142
|
|
|
146
143
|
# Creating spans for the "receive" callback
|
|
147
|
-
async def _sentry_receive(
|
|
148
|
-
|
|
144
|
+
async def _sentry_receive(
|
|
145
|
+
*args: Any, **kwargs: Any
|
|
146
|
+
) -> Union[HTTPReceiveMessage, WebSocketReceiveMessage]:
|
|
149
147
|
if sentry_sdk.get_client().get_integration(StarliteIntegration) is None:
|
|
150
148
|
return await receive(*args, **kwargs)
|
|
151
149
|
with sentry_sdk.start_span(
|
|
@@ -162,8 +160,7 @@ def enable_span_for_middleware(middleware):
|
|
|
162
160
|
new_receive = _sentry_receive if not receive_patched else receive
|
|
163
161
|
|
|
164
162
|
# Creating spans for the "send" callback
|
|
165
|
-
async def _sentry_send(message):
|
|
166
|
-
# type: (Message) -> None
|
|
163
|
+
async def _sentry_send(message: Message) -> None:
|
|
167
164
|
if sentry_sdk.get_client().get_integration(StarliteIntegration) is None:
|
|
168
165
|
return await send(message)
|
|
169
166
|
with sentry_sdk.start_span(
|
|
@@ -192,19 +189,19 @@ def enable_span_for_middleware(middleware):
|
|
|
192
189
|
return middleware
|
|
193
190
|
|
|
194
191
|
|
|
195
|
-
def patch_http_route_handle():
|
|
196
|
-
# type: () -> None
|
|
192
|
+
def patch_http_route_handle() -> None:
|
|
197
193
|
old_handle = HTTPRoute.handle
|
|
198
194
|
|
|
199
|
-
async def handle_wrapper(
|
|
200
|
-
|
|
195
|
+
async def handle_wrapper(
|
|
196
|
+
self: HTTPRoute, scope: HTTPScope, receive: Receive, send: Send
|
|
197
|
+
) -> None:
|
|
201
198
|
if sentry_sdk.get_client().get_integration(StarliteIntegration) is None:
|
|
202
199
|
return await old_handle(self, scope, receive, send)
|
|
203
200
|
|
|
204
201
|
sentry_scope = sentry_sdk.get_isolation_scope()
|
|
205
|
-
request = scope["app"].request_class(
|
|
202
|
+
request: Request[Any, Any] = scope["app"].request_class(
|
|
206
203
|
scope=scope, receive=receive, send=send
|
|
207
|
-
)
|
|
204
|
+
)
|
|
208
205
|
extracted_request_data = ConnectionDataExtractor(
|
|
209
206
|
parse_body=True, parse_query=True
|
|
210
207
|
)(request)
|
|
@@ -212,8 +209,7 @@ def patch_http_route_handle():
|
|
|
212
209
|
|
|
213
210
|
request_data = await body
|
|
214
211
|
|
|
215
|
-
def event_processor(event, _):
|
|
216
|
-
# type: (Event, Hint) -> Event
|
|
212
|
+
def event_processor(event: Event, _: Hint) -> Event:
|
|
217
213
|
route_handler = scope.get("route_handler")
|
|
218
214
|
|
|
219
215
|
request_info = event.get("request", {})
|
|
@@ -256,8 +252,7 @@ def patch_http_route_handle():
|
|
|
256
252
|
HTTPRoute.handle = handle_wrapper
|
|
257
253
|
|
|
258
254
|
|
|
259
|
-
def retrieve_user_from_scope(scope):
|
|
260
|
-
# type: (StarliteScope) -> Optional[dict[str, Any]]
|
|
255
|
+
def retrieve_user_from_scope(scope: StarliteScope) -> Optional[dict[str, Any]]:
|
|
261
256
|
scope_user = scope.get("user")
|
|
262
257
|
if not scope_user:
|
|
263
258
|
return None
|
|
@@ -276,9 +271,8 @@ def retrieve_user_from_scope(scope):
|
|
|
276
271
|
|
|
277
272
|
|
|
278
273
|
@ensure_integration_enabled(StarliteIntegration)
|
|
279
|
-
def exception_handler(exc, scope, _):
|
|
280
|
-
|
|
281
|
-
user_info = None # type: Optional[dict[str, Any]]
|
|
274
|
+
def exception_handler(exc: Exception, scope: StarliteScope, _: State) -> None:
|
|
275
|
+
user_info: Optional[dict[str, Any]] = None
|
|
282
276
|
if should_send_default_pii():
|
|
283
277
|
user_info = retrieve_user_from_scope(scope)
|
|
284
278
|
if user_info and isinstance(user_info, dict):
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
from functools import wraps
|
|
2
3
|
from typing import Any, TYPE_CHECKING
|
|
3
4
|
|
|
@@ -19,8 +20,7 @@ class StatsigIntegration(Integration):
|
|
|
19
20
|
identifier = "statsig"
|
|
20
21
|
|
|
21
22
|
@staticmethod
|
|
22
|
-
def setup_once():
|
|
23
|
-
# type: () -> None
|
|
23
|
+
def setup_once() -> None:
|
|
24
24
|
version = parse_version(STATSIG_VERSION)
|
|
25
25
|
_check_minimum_version(StatsigIntegration, version, "statsig")
|
|
26
26
|
|
|
@@ -28,8 +28,9 @@ class StatsigIntegration(Integration):
|
|
|
28
28
|
old_check_gate = statsig_module.check_gate
|
|
29
29
|
|
|
30
30
|
@wraps(old_check_gate)
|
|
31
|
-
def sentry_check_gate(
|
|
32
|
-
|
|
31
|
+
def sentry_check_gate(
|
|
32
|
+
user: StatsigUser, gate: str, *args: Any, **kwargs: Any
|
|
33
|
+
) -> Any:
|
|
33
34
|
enabled = old_check_gate(user, gate, *args, **kwargs)
|
|
34
35
|
add_feature_flag(gate, enabled)
|
|
35
36
|
return enabled
|