sentry-sdk 3.0.0a2__py2.py3-none-any.whl → 3.0.0a4__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 +4 -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 +9 -16
- sentry_sdk/_werkzeug.py +5 -7
- sentry_sdk/ai/monitoring.py +45 -33
- sentry_sdk/ai/utils.py +8 -5
- sentry_sdk/api.py +91 -87
- sentry_sdk/attachments.py +10 -12
- sentry_sdk/client.py +119 -159
- sentry_sdk/consts.py +432 -223
- 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 +16 -18
- sentry_sdk/integrations/_wsgi_common.py +22 -33
- sentry_sdk/integrations/aiohttp.py +33 -31
- sentry_sdk/integrations/anthropic.py +43 -38
- sentry_sdk/integrations/argv.py +3 -4
- sentry_sdk/integrations/ariadne.py +16 -18
- sentry_sdk/integrations/arq.py +20 -29
- sentry_sdk/integrations/asgi.py +63 -37
- sentry_sdk/integrations/asyncio.py +15 -17
- sentry_sdk/integrations/asyncpg.py +1 -1
- 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 +20 -18
- sentry_sdk/integrations/bottle.py +25 -34
- sentry_sdk/integrations/celery/__init__.py +40 -59
- sentry_sdk/integrations/celery/beat.py +22 -26
- sentry_sdk/integrations/celery/utils.py +15 -17
- sentry_sdk/integrations/chalice.py +8 -10
- sentry_sdk/integrations/clickhouse_driver.py +22 -32
- sentry_sdk/integrations/cloud_resource_context.py +9 -16
- sentry_sdk/integrations/cohere.py +19 -25
- sentry_sdk/integrations/dedupe.py +5 -8
- sentry_sdk/integrations/django/__init__.py +69 -74
- sentry_sdk/integrations/django/asgi.py +25 -33
- sentry_sdk/integrations/django/caching.py +24 -20
- sentry_sdk/integrations/django/middleware.py +18 -21
- sentry_sdk/integrations/django/signals_handlers.py +12 -11
- sentry_sdk/integrations/django/templates.py +21 -18
- sentry_sdk/integrations/django/transactions.py +16 -11
- sentry_sdk/integrations/django/views.py +8 -12
- 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 +7 -20
- sentry_sdk/integrations/gql.py +16 -17
- sentry_sdk/integrations/graphene.py +14 -13
- sentry_sdk/integrations/grpc/__init__.py +3 -2
- sentry_sdk/integrations/grpc/aio/client.py +2 -2
- sentry_sdk/integrations/grpc/aio/server.py +15 -14
- sentry_sdk/integrations/grpc/client.py +21 -11
- sentry_sdk/integrations/grpc/consts.py +2 -0
- sentry_sdk/integrations/grpc/server.py +12 -8
- sentry_sdk/integrations/httpx.py +11 -14
- sentry_sdk/integrations/huey.py +14 -21
- sentry_sdk/integrations/huggingface_hub.py +17 -17
- sentry_sdk/integrations/langchain.py +204 -114
- sentry_sdk/integrations/launchdarkly.py +13 -10
- sentry_sdk/integrations/litestar.py +40 -38
- sentry_sdk/integrations/logging.py +29 -36
- sentry_sdk/integrations/loguru.py +16 -20
- sentry_sdk/integrations/modules.py +3 -4
- sentry_sdk/integrations/openai.py +421 -204
- 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 +153 -0
- sentry_sdk/integrations/openfeature.py +12 -8
- sentry_sdk/integrations/pure_eval.py +6 -10
- sentry_sdk/integrations/pymongo.py +14 -18
- 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 +18 -12
- sentry_sdk/integrations/redis/_sync_common.py +16 -15
- 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 +10 -8
- sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +3 -2
- sentry_sdk/integrations/redis/utils.py +21 -22
- sentry_sdk/integrations/rq.py +13 -16
- sentry_sdk/integrations/rust_tracing.py +10 -7
- sentry_sdk/integrations/sanic.py +34 -46
- sentry_sdk/integrations/serverless.py +22 -27
- sentry_sdk/integrations/socket.py +29 -17
- 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 +89 -93
- sentry_sdk/integrations/starlite.py +31 -37
- sentry_sdk/integrations/statsig.py +5 -4
- sentry_sdk/integrations/stdlib.py +32 -28
- sentry_sdk/integrations/strawberry.py +63 -50
- sentry_sdk/integrations/sys_exit.py +7 -11
- sentry_sdk/integrations/threading.py +13 -15
- 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 +13 -9
- sentry_sdk/monitor.py +16 -28
- sentry_sdk/opentelemetry/consts.py +11 -4
- sentry_sdk/opentelemetry/contextvars_context.py +17 -15
- sentry_sdk/opentelemetry/propagator.py +38 -21
- sentry_sdk/opentelemetry/sampler.py +51 -34
- sentry_sdk/opentelemetry/scope.py +46 -37
- sentry_sdk/opentelemetry/span_processor.py +43 -59
- sentry_sdk/opentelemetry/tracing.py +32 -12
- sentry_sdk/opentelemetry/utils.py +180 -196
- 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 -264
- sentry_sdk/scrubber.py +22 -26
- sentry_sdk/serializer.py +48 -65
- sentry_sdk/session.py +44 -61
- sentry_sdk/sessions.py +35 -49
- sentry_sdk/spotlight.py +15 -21
- sentry_sdk/tracing.py +118 -184
- sentry_sdk/tracing_utils.py +103 -123
- sentry_sdk/transport.py +131 -157
- sentry_sdk/utils.py +278 -309
- sentry_sdk/worker.py +16 -28
- {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/METADATA +1 -1
- sentry_sdk-3.0.0a4.dist-info/RECORD +168 -0
- sentry_sdk-3.0.0a2.dist-info/RECORD +0 -154
- {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/WHEEL +0 -0
- {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/entry_points.txt +0 -0
- {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/licenses/LICENSE +0 -0
- {sentry_sdk-3.0.0a2.dist-info → sentry_sdk-3.0.0a4.dist-info}/top_level.txt +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
"""
|
|
2
4
|
Create spans from Django middleware invocations
|
|
3
5
|
"""
|
|
@@ -38,14 +40,12 @@ else:
|
|
|
38
40
|
from .asgi import _asgi_middleware_mixin_factory
|
|
39
41
|
|
|
40
42
|
|
|
41
|
-
def patch_django_middlewares():
|
|
42
|
-
# type: () -> None
|
|
43
|
+
def patch_django_middlewares() -> None:
|
|
43
44
|
from django.core.handlers import base
|
|
44
45
|
|
|
45
46
|
old_import_string = base.import_string
|
|
46
47
|
|
|
47
|
-
def sentry_patched_import_string(dotted_path):
|
|
48
|
-
# type: (str) -> Any
|
|
48
|
+
def sentry_patched_import_string(dotted_path: str) -> Any:
|
|
49
49
|
rv = old_import_string(dotted_path)
|
|
50
50
|
|
|
51
51
|
if _import_string_should_wrap_middleware.get(None):
|
|
@@ -57,8 +57,7 @@ def patch_django_middlewares():
|
|
|
57
57
|
|
|
58
58
|
old_load_middleware = base.BaseHandler.load_middleware
|
|
59
59
|
|
|
60
|
-
def sentry_patched_load_middleware(*args, **kwargs):
|
|
61
|
-
# type: (Any, Any) -> Any
|
|
60
|
+
def sentry_patched_load_middleware(*args: Any, **kwargs: Any) -> Any:
|
|
62
61
|
_import_string_should_wrap_middleware.set(True)
|
|
63
62
|
try:
|
|
64
63
|
return old_load_middleware(*args, **kwargs)
|
|
@@ -68,12 +67,10 @@ def patch_django_middlewares():
|
|
|
68
67
|
base.BaseHandler.load_middleware = sentry_patched_load_middleware
|
|
69
68
|
|
|
70
69
|
|
|
71
|
-
def _wrap_middleware(middleware, middleware_name):
|
|
72
|
-
# type: (Any, str) -> Any
|
|
70
|
+
def _wrap_middleware(middleware: Any, middleware_name: str) -> Any:
|
|
73
71
|
from sentry_sdk.integrations.django import DjangoIntegration
|
|
74
72
|
|
|
75
|
-
def _check_middleware_span(old_method):
|
|
76
|
-
# type: (Callable[..., Any]) -> Optional[Span]
|
|
73
|
+
def _check_middleware_span(old_method: Callable[..., Any]) -> Optional[Span]:
|
|
77
74
|
integration = sentry_sdk.get_client().get_integration(DjangoIntegration)
|
|
78
75
|
if integration is None or not integration.middleware_spans:
|
|
79
76
|
return None
|
|
@@ -89,19 +86,17 @@ def _wrap_middleware(middleware, middleware_name):
|
|
|
89
86
|
op=OP.MIDDLEWARE_DJANGO,
|
|
90
87
|
name=description,
|
|
91
88
|
origin=DjangoIntegration.origin,
|
|
92
|
-
|
|
89
|
+
only_as_child_span=True,
|
|
93
90
|
)
|
|
94
91
|
middleware_span.set_tag("django.function_name", function_name)
|
|
95
92
|
middleware_span.set_tag("django.middleware_name", middleware_name)
|
|
96
93
|
|
|
97
94
|
return middleware_span
|
|
98
95
|
|
|
99
|
-
def _get_wrapped_method(old_method):
|
|
100
|
-
# type: (F) -> F
|
|
96
|
+
def _get_wrapped_method(old_method: F) -> F:
|
|
101
97
|
with capture_internal_exceptions():
|
|
102
98
|
|
|
103
|
-
def sentry_wrapped_method(*args, **kwargs):
|
|
104
|
-
# type: (*Any, **Any) -> Any
|
|
99
|
+
def sentry_wrapped_method(*args: Any, **kwargs: Any) -> Any:
|
|
105
100
|
middleware_span = _check_middleware_span(old_method)
|
|
106
101
|
|
|
107
102
|
if middleware_span is None:
|
|
@@ -131,8 +126,12 @@ def _wrap_middleware(middleware, middleware_name):
|
|
|
131
126
|
middleware, "async_capable", False
|
|
132
127
|
)
|
|
133
128
|
|
|
134
|
-
def __init__(
|
|
135
|
-
|
|
129
|
+
def __init__(
|
|
130
|
+
self,
|
|
131
|
+
get_response: Optional[Callable[..., Any]] = None,
|
|
132
|
+
*args: Any,
|
|
133
|
+
**kwargs: Any,
|
|
134
|
+
) -> None:
|
|
136
135
|
if get_response:
|
|
137
136
|
self._inner = middleware(get_response, *args, **kwargs)
|
|
138
137
|
else:
|
|
@@ -144,8 +143,7 @@ def _wrap_middleware(middleware, middleware_name):
|
|
|
144
143
|
|
|
145
144
|
# We need correct behavior for `hasattr()`, which we can only determine
|
|
146
145
|
# when we have an instance of the middleware we're wrapping.
|
|
147
|
-
def __getattr__(self, method_name):
|
|
148
|
-
# type: (str) -> Any
|
|
146
|
+
def __getattr__(self, method_name: str) -> Any:
|
|
149
147
|
if method_name not in (
|
|
150
148
|
"process_request",
|
|
151
149
|
"process_view",
|
|
@@ -160,8 +158,7 @@ def _wrap_middleware(middleware, middleware_name):
|
|
|
160
158
|
self.__dict__[method_name] = rv
|
|
161
159
|
return rv
|
|
162
160
|
|
|
163
|
-
def __call__(self, *args, **kwargs):
|
|
164
|
-
# type: (*Any, **Any) -> Any
|
|
161
|
+
def __call__(self, *args: Any, **kwargs: Any) -> Any:
|
|
165
162
|
if hasattr(self, "async_route_check") and self.async_route_check():
|
|
166
163
|
return self.__acall__(*args, **kwargs)
|
|
167
164
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
from functools import wraps
|
|
2
3
|
|
|
3
4
|
from django.dispatch import Signal
|
|
@@ -13,8 +14,7 @@ if TYPE_CHECKING:
|
|
|
13
14
|
from typing import Any, Union
|
|
14
15
|
|
|
15
16
|
|
|
16
|
-
def _get_receiver_name(receiver):
|
|
17
|
-
# type: (Callable[..., Any]) -> str
|
|
17
|
+
def _get_receiver_name(receiver: Callable[..., Any]) -> str:
|
|
18
18
|
name = ""
|
|
19
19
|
|
|
20
20
|
if hasattr(receiver, "__qualname__"):
|
|
@@ -38,8 +38,7 @@ def _get_receiver_name(receiver):
|
|
|
38
38
|
return name
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
def patch_signals():
|
|
42
|
-
# type: () -> None
|
|
41
|
+
def patch_signals() -> None:
|
|
43
42
|
"""
|
|
44
43
|
Patch django signal receivers to create a span.
|
|
45
44
|
|
|
@@ -51,25 +50,27 @@ def patch_signals():
|
|
|
51
50
|
old_live_receivers = Signal._live_receivers
|
|
52
51
|
|
|
53
52
|
@wraps(old_live_receivers)
|
|
54
|
-
def _sentry_live_receivers(self, sender)
|
|
55
|
-
|
|
53
|
+
def _sentry_live_receivers(self: Signal, sender: Any) -> Union[
|
|
54
|
+
tuple[list[Callable[..., Any]], list[Callable[..., Any]]],
|
|
55
|
+
list[Callable[..., Any]],
|
|
56
|
+
]:
|
|
56
57
|
if DJANGO_VERSION >= (5, 0):
|
|
57
58
|
sync_receivers, async_receivers = old_live_receivers(self, sender)
|
|
58
59
|
else:
|
|
59
60
|
sync_receivers = old_live_receivers(self, sender)
|
|
60
61
|
async_receivers = []
|
|
61
62
|
|
|
62
|
-
def sentry_sync_receiver_wrapper(
|
|
63
|
-
|
|
63
|
+
def sentry_sync_receiver_wrapper(
|
|
64
|
+
receiver: Callable[..., Any],
|
|
65
|
+
) -> Callable[..., Any]:
|
|
64
66
|
@wraps(receiver)
|
|
65
|
-
def wrapper(*args, **kwargs):
|
|
66
|
-
# type: (Any, Any) -> Any
|
|
67
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
67
68
|
signal_name = _get_receiver_name(receiver)
|
|
68
69
|
with sentry_sdk.start_span(
|
|
69
70
|
op=OP.EVENT_DJANGO,
|
|
70
71
|
name=signal_name,
|
|
71
72
|
origin=DjangoIntegration.origin,
|
|
72
|
-
|
|
73
|
+
only_as_child_span=True,
|
|
73
74
|
) as span:
|
|
74
75
|
span.set_attribute("signal", signal_name)
|
|
75
76
|
return receiver(*args, **kwargs)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import functools
|
|
2
3
|
|
|
3
4
|
from django.template import TemplateSyntaxError
|
|
@@ -18,8 +19,9 @@ if TYPE_CHECKING:
|
|
|
18
19
|
from typing import Tuple
|
|
19
20
|
|
|
20
21
|
|
|
21
|
-
def get_template_frame_from_exception(
|
|
22
|
-
|
|
22
|
+
def get_template_frame_from_exception(
|
|
23
|
+
exc_value: Optional[BaseException],
|
|
24
|
+
) -> Optional[Dict[str, Any]]:
|
|
23
25
|
|
|
24
26
|
# As of Django 1.9 or so the new template debug thing showed up.
|
|
25
27
|
if hasattr(exc_value, "template_debug"):
|
|
@@ -41,8 +43,7 @@ def get_template_frame_from_exception(exc_value):
|
|
|
41
43
|
return None
|
|
42
44
|
|
|
43
45
|
|
|
44
|
-
def _get_template_name_description(template_name):
|
|
45
|
-
# type: (str) -> str
|
|
46
|
+
def _get_template_name_description(template_name: str) -> str:
|
|
46
47
|
if isinstance(template_name, (list, tuple)):
|
|
47
48
|
if template_name:
|
|
48
49
|
return "[{}, ...]".format(template_name[0])
|
|
@@ -50,8 +51,7 @@ def _get_template_name_description(template_name):
|
|
|
50
51
|
return template_name
|
|
51
52
|
|
|
52
53
|
|
|
53
|
-
def patch_templates():
|
|
54
|
-
# type: () -> None
|
|
54
|
+
def patch_templates() -> None:
|
|
55
55
|
from django.template.response import SimpleTemplateResponse
|
|
56
56
|
from sentry_sdk.integrations.django import DjangoIntegration
|
|
57
57
|
|
|
@@ -59,13 +59,12 @@ def patch_templates():
|
|
|
59
59
|
|
|
60
60
|
@property # type: ignore
|
|
61
61
|
@ensure_integration_enabled(DjangoIntegration, real_rendered_content.fget)
|
|
62
|
-
def rendered_content(self):
|
|
63
|
-
# type: (SimpleTemplateResponse) -> str
|
|
62
|
+
def rendered_content(self: SimpleTemplateResponse) -> str:
|
|
64
63
|
with sentry_sdk.start_span(
|
|
65
64
|
op=OP.TEMPLATE_RENDER,
|
|
66
65
|
name=_get_template_name_description(self.template_name),
|
|
67
66
|
origin=DjangoIntegration.origin,
|
|
68
|
-
|
|
67
|
+
only_as_child_span=True,
|
|
69
68
|
) as span:
|
|
70
69
|
if isinstance(self.context_data, dict):
|
|
71
70
|
for k, v in self.context_data.items():
|
|
@@ -80,8 +79,13 @@ def patch_templates():
|
|
|
80
79
|
|
|
81
80
|
@functools.wraps(real_render)
|
|
82
81
|
@ensure_integration_enabled(DjangoIntegration, real_render)
|
|
83
|
-
def render(
|
|
84
|
-
|
|
82
|
+
def render(
|
|
83
|
+
request: django.http.HttpRequest,
|
|
84
|
+
template_name: str,
|
|
85
|
+
context: Optional[Dict[str, Any]] = None,
|
|
86
|
+
*args: Any,
|
|
87
|
+
**kwargs: Any,
|
|
88
|
+
) -> django.http.HttpResponse:
|
|
85
89
|
|
|
86
90
|
# Inject trace meta tags into template context
|
|
87
91
|
context = context or {}
|
|
@@ -94,7 +98,7 @@ def patch_templates():
|
|
|
94
98
|
op=OP.TEMPLATE_RENDER,
|
|
95
99
|
name=_get_template_name_description(template_name),
|
|
96
100
|
origin=DjangoIntegration.origin,
|
|
97
|
-
|
|
101
|
+
only_as_child_span=True,
|
|
98
102
|
) as span:
|
|
99
103
|
for k, v in context.items():
|
|
100
104
|
span.set_attribute(f"context.{k}", v)
|
|
@@ -103,8 +107,7 @@ def patch_templates():
|
|
|
103
107
|
django.shortcuts.render = render
|
|
104
108
|
|
|
105
109
|
|
|
106
|
-
def _get_template_frame_from_debug(debug):
|
|
107
|
-
# type: (Dict[str, Any]) -> Dict[str, Any]
|
|
110
|
+
def _get_template_frame_from_debug(debug: Dict[str, Any]) -> Dict[str, Any]:
|
|
108
111
|
if debug is None:
|
|
109
112
|
return None
|
|
110
113
|
|
|
@@ -135,8 +138,7 @@ def _get_template_frame_from_debug(debug):
|
|
|
135
138
|
}
|
|
136
139
|
|
|
137
140
|
|
|
138
|
-
def _linebreak_iter(template_source):
|
|
139
|
-
# type: (str) -> Iterator[int]
|
|
141
|
+
def _linebreak_iter(template_source: str) -> Iterator[int]:
|
|
140
142
|
yield 0
|
|
141
143
|
p = template_source.find("\n")
|
|
142
144
|
while p >= 0:
|
|
@@ -144,8 +146,9 @@ def _linebreak_iter(template_source):
|
|
|
144
146
|
p = template_source.find("\n", p + 1)
|
|
145
147
|
|
|
146
148
|
|
|
147
|
-
def _get_template_frame_from_source(
|
|
148
|
-
|
|
149
|
+
def _get_template_frame_from_source(
|
|
150
|
+
source: Tuple[Origin, Tuple[int, int]],
|
|
151
|
+
) -> Optional[Dict[str, Any]]:
|
|
149
152
|
if not source:
|
|
150
153
|
return None
|
|
151
154
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
"""
|
|
2
4
|
Copied from raven-python.
|
|
3
5
|
|
|
@@ -27,8 +29,7 @@ except ImportError:
|
|
|
27
29
|
from django.core.urlresolvers import get_resolver
|
|
28
30
|
|
|
29
31
|
|
|
30
|
-
def get_regex(resolver_or_pattern):
|
|
31
|
-
# type: (Union[URLPattern, URLResolver]) -> Pattern[str]
|
|
32
|
+
def get_regex(resolver_or_pattern: Union[URLPattern, URLResolver]) -> Pattern[str]:
|
|
32
33
|
"""Utility method for django's deprecated resolver.regex"""
|
|
33
34
|
try:
|
|
34
35
|
regex = resolver_or_pattern.regex
|
|
@@ -48,10 +49,9 @@ class RavenResolver:
|
|
|
48
49
|
_either_option_matcher = re.compile(r"\[([^\]]+)\|([^\]]+)\]")
|
|
49
50
|
_camel_re = re.compile(r"([A-Z]+)([a-z])")
|
|
50
51
|
|
|
51
|
-
_cache
|
|
52
|
+
_cache: Dict[URLPattern, str] = {}
|
|
52
53
|
|
|
53
|
-
def _simplify(self, pattern):
|
|
54
|
-
# type: (Union[URLPattern, URLResolver]) -> str
|
|
54
|
+
def _simplify(self, pattern: Union[URLPattern, URLResolver]) -> str:
|
|
55
55
|
r"""
|
|
56
56
|
Clean up urlpattern regexes into something readable by humans:
|
|
57
57
|
|
|
@@ -102,8 +102,12 @@ class RavenResolver:
|
|
|
102
102
|
|
|
103
103
|
return result
|
|
104
104
|
|
|
105
|
-
def _resolve(
|
|
106
|
-
|
|
105
|
+
def _resolve(
|
|
106
|
+
self,
|
|
107
|
+
resolver: URLResolver,
|
|
108
|
+
path: str,
|
|
109
|
+
parents: Optional[List[URLResolver]] = None,
|
|
110
|
+
) -> Optional[str]:
|
|
107
111
|
|
|
108
112
|
match = get_regex(resolver).search(path) # Django < 2.0
|
|
109
113
|
|
|
@@ -142,10 +146,11 @@ class RavenResolver:
|
|
|
142
146
|
|
|
143
147
|
def resolve(
|
|
144
148
|
self,
|
|
145
|
-
path
|
|
146
|
-
urlconf
|
|
147
|
-
|
|
148
|
-
|
|
149
|
+
path: str,
|
|
150
|
+
urlconf: Union[
|
|
151
|
+
None, Tuple[URLPattern, URLPattern, URLResolver], Tuple[URLPattern]
|
|
152
|
+
] = None,
|
|
153
|
+
) -> Optional[str]:
|
|
149
154
|
resolver = get_resolver(urlconf)
|
|
150
155
|
match = self._resolve(resolver, path)
|
|
151
156
|
return match
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import functools
|
|
2
3
|
|
|
3
4
|
import sentry_sdk
|
|
@@ -21,8 +22,7 @@ except (ImportError, SyntaxError):
|
|
|
21
22
|
wrap_async_view = None # type: ignore
|
|
22
23
|
|
|
23
24
|
|
|
24
|
-
def patch_views():
|
|
25
|
-
# type: () -> None
|
|
25
|
+
def patch_views() -> None:
|
|
26
26
|
|
|
27
27
|
from django.core.handlers.base import BaseHandler
|
|
28
28
|
from django.template.response import SimpleTemplateResponse
|
|
@@ -32,19 +32,17 @@ def patch_views():
|
|
|
32
32
|
old_render = SimpleTemplateResponse.render
|
|
33
33
|
|
|
34
34
|
@functools.wraps(old_render)
|
|
35
|
-
def sentry_patched_render(self):
|
|
36
|
-
# type: (SimpleTemplateResponse) -> Any
|
|
35
|
+
def sentry_patched_render(self: SimpleTemplateResponse) -> Any:
|
|
37
36
|
with sentry_sdk.start_span(
|
|
38
37
|
op=OP.VIEW_RESPONSE_RENDER,
|
|
39
38
|
name="serialize response",
|
|
40
39
|
origin=DjangoIntegration.origin,
|
|
41
|
-
|
|
40
|
+
only_as_child_span=True,
|
|
42
41
|
):
|
|
43
42
|
return old_render(self)
|
|
44
43
|
|
|
45
44
|
@functools.wraps(old_make_view_atomic)
|
|
46
|
-
def sentry_patched_make_view_atomic(self, *args, **kwargs):
|
|
47
|
-
# type: (Any, *Any, **Any) -> Any
|
|
45
|
+
def sentry_patched_make_view_atomic(self: Any, *args: Any, **kwargs: Any) -> Any:
|
|
48
46
|
callback = old_make_view_atomic(self, *args, **kwargs)
|
|
49
47
|
|
|
50
48
|
# XXX: The wrapper function is created for every request. Find more
|
|
@@ -71,13 +69,11 @@ def patch_views():
|
|
|
71
69
|
BaseHandler.make_view_atomic = sentry_patched_make_view_atomic
|
|
72
70
|
|
|
73
71
|
|
|
74
|
-
def _wrap_sync_view(callback):
|
|
75
|
-
# type: (Any) -> Any
|
|
72
|
+
def _wrap_sync_view(callback: Any) -> Any:
|
|
76
73
|
from sentry_sdk.integrations.django import DjangoIntegration
|
|
77
74
|
|
|
78
75
|
@functools.wraps(callback)
|
|
79
|
-
def sentry_wrapped_callback(request, *args, **kwargs):
|
|
80
|
-
# type: (Any, *Any, **Any) -> Any
|
|
76
|
+
def sentry_wrapped_callback(request: Any, *args: Any, **kwargs: Any) -> Any:
|
|
81
77
|
current_scope = sentry_sdk.get_current_scope()
|
|
82
78
|
if current_scope.root_span is not None:
|
|
83
79
|
current_scope.root_span.update_active_thread()
|
|
@@ -92,7 +88,7 @@ def _wrap_sync_view(callback):
|
|
|
92
88
|
op=OP.VIEW_RENDER,
|
|
93
89
|
name=request.resolver_match.view_name,
|
|
94
90
|
origin=DjangoIntegration.origin,
|
|
95
|
-
|
|
91
|
+
only_as_child_span=True,
|
|
96
92
|
):
|
|
97
93
|
return callback(request, *args, **kwargs)
|
|
98
94
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import json
|
|
2
3
|
|
|
3
4
|
import sentry_sdk
|
|
@@ -36,17 +37,14 @@ class DramatiqIntegration(Integration):
|
|
|
36
37
|
identifier = "dramatiq"
|
|
37
38
|
|
|
38
39
|
@staticmethod
|
|
39
|
-
def setup_once():
|
|
40
|
-
# type: () -> None
|
|
40
|
+
def setup_once() -> None:
|
|
41
41
|
_patch_dramatiq_broker()
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
def _patch_dramatiq_broker():
|
|
45
|
-
# type: () -> None
|
|
44
|
+
def _patch_dramatiq_broker() -> None:
|
|
46
45
|
original_broker__init__ = Broker.__init__
|
|
47
46
|
|
|
48
|
-
def sentry_patched_broker__init__(self, *args, **kw):
|
|
49
|
-
# type: (Broker, *Any, **Any) -> None
|
|
47
|
+
def sentry_patched_broker__init__(self: Broker, *args: Any, **kw: Any) -> None:
|
|
50
48
|
integration = sentry_sdk.get_client().get_integration(DramatiqIntegration)
|
|
51
49
|
|
|
52
50
|
try:
|
|
@@ -85,8 +83,7 @@ class SentryMiddleware(Middleware): # type: ignore[misc]
|
|
|
85
83
|
DramatiqIntegration.
|
|
86
84
|
"""
|
|
87
85
|
|
|
88
|
-
def before_process_message(self, broker, message):
|
|
89
|
-
# type: (Broker, Message) -> None
|
|
86
|
+
def before_process_message(self, broker: Broker, message: Message) -> None:
|
|
90
87
|
integration = sentry_sdk.get_client().get_integration(DramatiqIntegration)
|
|
91
88
|
if integration is None:
|
|
92
89
|
return
|
|
@@ -99,8 +96,14 @@ class SentryMiddleware(Middleware): # type: ignore[misc]
|
|
|
99
96
|
scope.set_extra("dramatiq_message_id", message.message_id)
|
|
100
97
|
scope.add_event_processor(_make_message_event_processor(message, integration))
|
|
101
98
|
|
|
102
|
-
def after_process_message(
|
|
103
|
-
|
|
99
|
+
def after_process_message(
|
|
100
|
+
self: Broker,
|
|
101
|
+
broker: Message,
|
|
102
|
+
message: Any,
|
|
103
|
+
*,
|
|
104
|
+
result: Optional[Any] = None,
|
|
105
|
+
exception: Optional[Exception] = None,
|
|
106
|
+
) -> None:
|
|
104
107
|
integration = sentry_sdk.get_client().get_integration(DramatiqIntegration)
|
|
105
108
|
if integration is None:
|
|
106
109
|
return
|
|
@@ -127,11 +130,11 @@ class SentryMiddleware(Middleware): # type: ignore[misc]
|
|
|
127
130
|
message._scope_manager.__exit__(None, None, None)
|
|
128
131
|
|
|
129
132
|
|
|
130
|
-
def _make_message_event_processor(
|
|
131
|
-
|
|
133
|
+
def _make_message_event_processor(
|
|
134
|
+
message: Message, integration: DramatiqIntegration
|
|
135
|
+
) -> Callable[[Event, Hint], Optional[Event]]:
|
|
132
136
|
|
|
133
|
-
def inner(event, hint):
|
|
134
|
-
# type: (Event, Hint) -> Optional[Event]
|
|
137
|
+
def inner(event: Event, hint: Hint) -> Optional[Event]:
|
|
135
138
|
with capture_internal_exceptions():
|
|
136
139
|
DramatiqMessageExtractor(message).extract_into_event(event)
|
|
137
140
|
|
|
@@ -141,16 +144,13 @@ def _make_message_event_processor(message, integration):
|
|
|
141
144
|
|
|
142
145
|
|
|
143
146
|
class DramatiqMessageExtractor:
|
|
144
|
-
def __init__(self, message):
|
|
145
|
-
# type: (Message) -> None
|
|
147
|
+
def __init__(self, message: Message) -> None:
|
|
146
148
|
self.message_data = dict(message.asdict())
|
|
147
149
|
|
|
148
|
-
def content_length(self):
|
|
149
|
-
# type: () -> int
|
|
150
|
+
def content_length(self) -> int:
|
|
150
151
|
return len(json.dumps(self.message_data))
|
|
151
152
|
|
|
152
|
-
def extract_into_event(self, event):
|
|
153
|
-
# type: (Event) -> None
|
|
153
|
+
def extract_into_event(self, event: Event) -> None:
|
|
154
154
|
client = sentry_sdk.get_client()
|
|
155
155
|
if not client.is_active():
|
|
156
156
|
return
|
|
@@ -159,7 +159,7 @@ class DramatiqMessageExtractor:
|
|
|
159
159
|
request_info = contexts.setdefault("dramatiq", {})
|
|
160
160
|
request_info["type"] = "dramatiq"
|
|
161
161
|
|
|
162
|
-
data
|
|
162
|
+
data: Optional[Union[AnnotatedValue, Dict[str, Any]]] = None
|
|
163
163
|
if not request_body_within_bounds(client, self.content_length()):
|
|
164
164
|
data = AnnotatedValue.removed_because_over_size_limit()
|
|
165
165
|
else:
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import sys
|
|
2
3
|
|
|
3
4
|
import sentry_sdk
|
|
@@ -28,8 +29,7 @@ class ExcepthookIntegration(Integration):
|
|
|
28
29
|
|
|
29
30
|
always_run = False
|
|
30
31
|
|
|
31
|
-
def __init__(self, always_run=False):
|
|
32
|
-
# type: (bool) -> None
|
|
32
|
+
def __init__(self, always_run: bool = False) -> None:
|
|
33
33
|
|
|
34
34
|
if not isinstance(always_run, bool):
|
|
35
35
|
raise ValueError(
|
|
@@ -39,15 +39,16 @@ class ExcepthookIntegration(Integration):
|
|
|
39
39
|
self.always_run = always_run
|
|
40
40
|
|
|
41
41
|
@staticmethod
|
|
42
|
-
def setup_once():
|
|
43
|
-
# type: () -> None
|
|
42
|
+
def setup_once() -> None:
|
|
44
43
|
sys.excepthook = _make_excepthook(sys.excepthook)
|
|
45
44
|
|
|
46
45
|
|
|
47
|
-
def _make_excepthook(old_excepthook):
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
def _make_excepthook(old_excepthook: Excepthook) -> Excepthook:
|
|
47
|
+
def sentry_sdk_excepthook(
|
|
48
|
+
type_: Type[BaseException],
|
|
49
|
+
value: BaseException,
|
|
50
|
+
traceback: Optional[TracebackType],
|
|
51
|
+
) -> None:
|
|
51
52
|
integration = sentry_sdk.get_client().get_integration(ExcepthookIntegration)
|
|
52
53
|
|
|
53
54
|
# Note: If we replace this with ensure_integration_enabled then
|
|
@@ -70,8 +71,7 @@ def _make_excepthook(old_excepthook):
|
|
|
70
71
|
return sentry_sdk_excepthook
|
|
71
72
|
|
|
72
73
|
|
|
73
|
-
def _should_send(always_run=False):
|
|
74
|
-
# type: (bool) -> bool
|
|
74
|
+
def _should_send(always_run: bool = False) -> bool:
|
|
75
75
|
if always_run:
|
|
76
76
|
return True
|
|
77
77
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import sentry_sdk
|
|
2
3
|
from sentry_sdk.integrations import Integration, DidNotEnable
|
|
3
4
|
from sentry_sdk.scope import add_global_event_processor
|
|
@@ -20,12 +21,10 @@ class ExecutingIntegration(Integration):
|
|
|
20
21
|
identifier = "executing"
|
|
21
22
|
|
|
22
23
|
@staticmethod
|
|
23
|
-
def setup_once():
|
|
24
|
-
# type: () -> None
|
|
24
|
+
def setup_once() -> None:
|
|
25
25
|
|
|
26
26
|
@add_global_event_processor
|
|
27
|
-
def add_executing_info(event, hint):
|
|
28
|
-
# type: (Event, Optional[Hint]) -> Optional[Event]
|
|
27
|
+
def add_executing_info(event: Event, hint: Optional[Hint]) -> Optional[Event]:
|
|
29
28
|
if sentry_sdk.get_client().get_integration(ExecutingIntegration) is None:
|
|
30
29
|
return event
|
|
31
30
|
|