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.

Files changed (157) hide show
  1. sentry_sdk/__init__.py +2 -0
  2. sentry_sdk/_compat.py +5 -12
  3. sentry_sdk/_init_implementation.py +7 -7
  4. sentry_sdk/_log_batcher.py +17 -29
  5. sentry_sdk/_lru_cache.py +7 -9
  6. sentry_sdk/_queue.py +2 -4
  7. sentry_sdk/_types.py +11 -18
  8. sentry_sdk/_werkzeug.py +5 -7
  9. sentry_sdk/ai/monitoring.py +44 -31
  10. sentry_sdk/ai/utils.py +3 -4
  11. sentry_sdk/api.py +75 -87
  12. sentry_sdk/attachments.py +10 -12
  13. sentry_sdk/client.py +137 -155
  14. sentry_sdk/consts.py +430 -174
  15. sentry_sdk/crons/api.py +16 -17
  16. sentry_sdk/crons/decorator.py +25 -27
  17. sentry_sdk/debug.py +4 -6
  18. sentry_sdk/envelope.py +46 -112
  19. sentry_sdk/feature_flags.py +9 -15
  20. sentry_sdk/integrations/__init__.py +24 -19
  21. sentry_sdk/integrations/_asgi_common.py +15 -18
  22. sentry_sdk/integrations/_wsgi_common.py +22 -33
  23. sentry_sdk/integrations/aiohttp.py +32 -30
  24. sentry_sdk/integrations/anthropic.py +42 -37
  25. sentry_sdk/integrations/argv.py +3 -4
  26. sentry_sdk/integrations/ariadne.py +16 -18
  27. sentry_sdk/integrations/arq.py +21 -29
  28. sentry_sdk/integrations/asgi.py +63 -37
  29. sentry_sdk/integrations/asyncio.py +14 -16
  30. sentry_sdk/integrations/atexit.py +6 -10
  31. sentry_sdk/integrations/aws_lambda.py +26 -36
  32. sentry_sdk/integrations/beam.py +10 -18
  33. sentry_sdk/integrations/boto3.py +18 -16
  34. sentry_sdk/integrations/bottle.py +25 -34
  35. sentry_sdk/integrations/celery/__init__.py +41 -61
  36. sentry_sdk/integrations/celery/beat.py +23 -27
  37. sentry_sdk/integrations/celery/utils.py +15 -17
  38. sentry_sdk/integrations/chalice.py +8 -10
  39. sentry_sdk/integrations/clickhouse_driver.py +21 -31
  40. sentry_sdk/integrations/cloud_resource_context.py +9 -16
  41. sentry_sdk/integrations/cohere.py +27 -33
  42. sentry_sdk/integrations/dedupe.py +5 -8
  43. sentry_sdk/integrations/django/__init__.py +57 -72
  44. sentry_sdk/integrations/django/asgi.py +26 -34
  45. sentry_sdk/integrations/django/caching.py +23 -19
  46. sentry_sdk/integrations/django/middleware.py +17 -20
  47. sentry_sdk/integrations/django/signals_handlers.py +11 -10
  48. sentry_sdk/integrations/django/templates.py +19 -16
  49. sentry_sdk/integrations/django/transactions.py +16 -11
  50. sentry_sdk/integrations/django/views.py +6 -10
  51. sentry_sdk/integrations/dramatiq.py +21 -21
  52. sentry_sdk/integrations/excepthook.py +10 -10
  53. sentry_sdk/integrations/executing.py +3 -4
  54. sentry_sdk/integrations/falcon.py +27 -42
  55. sentry_sdk/integrations/fastapi.py +13 -16
  56. sentry_sdk/integrations/flask.py +31 -38
  57. sentry_sdk/integrations/gcp.py +13 -16
  58. sentry_sdk/integrations/gnu_backtrace.py +4 -6
  59. sentry_sdk/integrations/gql.py +16 -17
  60. sentry_sdk/integrations/graphene.py +13 -12
  61. sentry_sdk/integrations/grpc/__init__.py +19 -1
  62. sentry_sdk/integrations/grpc/aio/server.py +15 -14
  63. sentry_sdk/integrations/grpc/client.py +19 -9
  64. sentry_sdk/integrations/grpc/consts.py +2 -0
  65. sentry_sdk/integrations/grpc/server.py +12 -8
  66. sentry_sdk/integrations/httpx.py +9 -12
  67. sentry_sdk/integrations/huey.py +13 -20
  68. sentry_sdk/integrations/huggingface_hub.py +18 -18
  69. sentry_sdk/integrations/langchain.py +203 -113
  70. sentry_sdk/integrations/launchdarkly.py +13 -10
  71. sentry_sdk/integrations/litestar.py +37 -35
  72. sentry_sdk/integrations/logging.py +52 -65
  73. sentry_sdk/integrations/loguru.py +127 -57
  74. sentry_sdk/integrations/modules.py +3 -4
  75. sentry_sdk/integrations/openai.py +100 -88
  76. sentry_sdk/integrations/openai_agents/__init__.py +49 -0
  77. sentry_sdk/integrations/openai_agents/consts.py +1 -0
  78. sentry_sdk/integrations/openai_agents/patches/__init__.py +4 -0
  79. sentry_sdk/integrations/openai_agents/patches/agent_run.py +152 -0
  80. sentry_sdk/integrations/openai_agents/patches/models.py +52 -0
  81. sentry_sdk/integrations/openai_agents/patches/runner.py +42 -0
  82. sentry_sdk/integrations/openai_agents/patches/tools.py +84 -0
  83. sentry_sdk/integrations/openai_agents/spans/__init__.py +5 -0
  84. sentry_sdk/integrations/openai_agents/spans/agent_workflow.py +20 -0
  85. sentry_sdk/integrations/openai_agents/spans/ai_client.py +46 -0
  86. sentry_sdk/integrations/openai_agents/spans/execute_tool.py +47 -0
  87. sentry_sdk/integrations/openai_agents/spans/handoff.py +24 -0
  88. sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +41 -0
  89. sentry_sdk/integrations/openai_agents/utils.py +201 -0
  90. sentry_sdk/integrations/openfeature.py +11 -6
  91. sentry_sdk/integrations/pure_eval.py +6 -10
  92. sentry_sdk/integrations/pymongo.py +13 -17
  93. sentry_sdk/integrations/pyramid.py +31 -36
  94. sentry_sdk/integrations/quart.py +23 -28
  95. sentry_sdk/integrations/ray.py +73 -64
  96. sentry_sdk/integrations/redis/__init__.py +7 -4
  97. sentry_sdk/integrations/redis/_async_common.py +25 -12
  98. sentry_sdk/integrations/redis/_sync_common.py +19 -13
  99. sentry_sdk/integrations/redis/modules/caches.py +17 -8
  100. sentry_sdk/integrations/redis/modules/queries.py +9 -8
  101. sentry_sdk/integrations/redis/rb.py +3 -2
  102. sentry_sdk/integrations/redis/redis.py +4 -4
  103. sentry_sdk/integrations/redis/redis_cluster.py +21 -13
  104. sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +3 -2
  105. sentry_sdk/integrations/redis/utils.py +23 -24
  106. sentry_sdk/integrations/rq.py +13 -16
  107. sentry_sdk/integrations/rust_tracing.py +9 -6
  108. sentry_sdk/integrations/sanic.py +34 -46
  109. sentry_sdk/integrations/serverless.py +22 -27
  110. sentry_sdk/integrations/socket.py +27 -15
  111. sentry_sdk/integrations/spark/__init__.py +1 -0
  112. sentry_sdk/integrations/spark/spark_driver.py +45 -83
  113. sentry_sdk/integrations/spark/spark_worker.py +7 -11
  114. sentry_sdk/integrations/sqlalchemy.py +22 -19
  115. sentry_sdk/integrations/starlette.py +86 -90
  116. sentry_sdk/integrations/starlite.py +28 -34
  117. sentry_sdk/integrations/statsig.py +5 -4
  118. sentry_sdk/integrations/stdlib.py +28 -24
  119. sentry_sdk/integrations/strawberry.py +62 -49
  120. sentry_sdk/integrations/sys_exit.py +7 -11
  121. sentry_sdk/integrations/threading.py +12 -14
  122. sentry_sdk/integrations/tornado.py +28 -32
  123. sentry_sdk/integrations/trytond.py +4 -3
  124. sentry_sdk/integrations/typer.py +8 -6
  125. sentry_sdk/integrations/unleash.py +5 -4
  126. sentry_sdk/integrations/wsgi.py +47 -46
  127. sentry_sdk/logger.py +41 -10
  128. sentry_sdk/monitor.py +16 -28
  129. sentry_sdk/opentelemetry/consts.py +11 -4
  130. sentry_sdk/opentelemetry/contextvars_context.py +26 -16
  131. sentry_sdk/opentelemetry/propagator.py +38 -21
  132. sentry_sdk/opentelemetry/sampler.py +51 -34
  133. sentry_sdk/opentelemetry/scope.py +36 -37
  134. sentry_sdk/opentelemetry/span_processor.py +48 -58
  135. sentry_sdk/opentelemetry/tracing.py +58 -14
  136. sentry_sdk/opentelemetry/utils.py +186 -194
  137. sentry_sdk/profiler/continuous_profiler.py +108 -97
  138. sentry_sdk/profiler/transaction_profiler.py +70 -97
  139. sentry_sdk/profiler/utils.py +11 -15
  140. sentry_sdk/scope.py +251 -273
  141. sentry_sdk/scrubber.py +22 -26
  142. sentry_sdk/serializer.py +40 -54
  143. sentry_sdk/session.py +44 -61
  144. sentry_sdk/sessions.py +35 -49
  145. sentry_sdk/spotlight.py +15 -21
  146. sentry_sdk/tracing.py +121 -187
  147. sentry_sdk/tracing_utils.py +104 -122
  148. sentry_sdk/transport.py +131 -157
  149. sentry_sdk/utils.py +232 -309
  150. sentry_sdk/worker.py +16 -28
  151. {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/METADATA +3 -3
  152. sentry_sdk-3.0.0a3.dist-info/RECORD +168 -0
  153. {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/WHEEL +1 -1
  154. sentry_sdk-3.0.0a1.dist-info/RECORD +0 -154
  155. {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/entry_points.txt +0 -0
  156. {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/licenses/LICENSE +0 -0
  157. {sentry_sdk-3.0.0a1.dist-info → sentry_sdk-3.0.0a3.dist-info}/top_level.txt +0 -0
@@ -2,6 +2,7 @@
2
2
  Code used for the Caches module in Sentry
3
3
  """
4
4
 
5
+ from __future__ import annotations
5
6
  from sentry_sdk.consts import OP, SPANDATA
6
7
  from sentry_sdk.integrations.redis.utils import _get_safe_key, _key_as_string
7
8
  from sentry_sdk.utils import capture_internal_exceptions
@@ -16,8 +17,7 @@ if TYPE_CHECKING:
16
17
  from typing import Any, Optional
17
18
 
18
19
 
19
- def _get_op(name):
20
- # type: (str) -> Optional[str]
20
+ def _get_op(name: str) -> Optional[str]:
21
21
  op = None
22
22
  if name.lower() in GET_COMMANDS:
23
23
  op = OP.CACHE_GET
@@ -27,8 +27,12 @@ def _get_op(name):
27
27
  return op
28
28
 
29
29
 
30
- def _compile_cache_span_properties(redis_command, args, kwargs, integration):
31
- # type: (str, tuple[Any, ...], dict[str, Any], RedisIntegration) -> dict[str, Any]
30
+ def _compile_cache_span_properties(
31
+ redis_command: str,
32
+ args: tuple[Any, ...],
33
+ kwargs: dict[str, Any],
34
+ integration: RedisIntegration,
35
+ ) -> dict[str, Any]:
32
36
  key = _get_safe_key(redis_command, args, kwargs)
33
37
  key_as_string = _key_as_string(key)
34
38
  keys_as_string = key_as_string.split(", ")
@@ -61,8 +65,12 @@ def _compile_cache_span_properties(redis_command, args, kwargs, integration):
61
65
  return properties
62
66
 
63
67
 
64
- def _get_cache_span_description(redis_command, args, kwargs, integration):
65
- # type: (str, tuple[Any, ...], dict[str, Any], RedisIntegration) -> str
68
+ def _get_cache_span_description(
69
+ redis_command: str,
70
+ args: tuple[Any, ...],
71
+ kwargs: dict[str, Any],
72
+ integration: RedisIntegration,
73
+ ) -> str:
66
74
  description = _key_as_string(_get_safe_key(redis_command, args, kwargs))
67
75
 
68
76
  data_should_be_truncated = (
@@ -74,8 +82,9 @@ def _get_cache_span_description(redis_command, args, kwargs, integration):
74
82
  return description
75
83
 
76
84
 
77
- def _get_cache_data(redis_client, properties, return_value):
78
- # type: (Any, dict[str, Any], Optional[Any]) -> dict[str, Any]
85
+ def _get_cache_data(
86
+ redis_client: Any, properties: dict[str, Any], return_value: Optional[Any]
87
+ ) -> dict[str, Any]:
79
88
  data = {}
80
89
 
81
90
  with capture_internal_exceptions():
@@ -2,6 +2,7 @@
2
2
  Code used for the Queries module in Sentry
3
3
  """
4
4
 
5
+ from __future__ import annotations
5
6
  from sentry_sdk.consts import OP, SPANDATA
6
7
  from sentry_sdk.integrations.redis.utils import _get_safe_command
7
8
  from sentry_sdk.utils import capture_internal_exceptions
@@ -14,8 +15,9 @@ if TYPE_CHECKING:
14
15
  from typing import Any
15
16
 
16
17
 
17
- def _compile_db_span_properties(integration, redis_command, args):
18
- # type: (RedisIntegration, str, tuple[Any, ...]) -> dict[str, Any]
18
+ def _compile_db_span_properties(
19
+ integration: RedisIntegration, redis_command: str, args: tuple[Any, ...]
20
+ ) -> dict[str, Any]:
19
21
  description = _get_db_span_description(integration, redis_command, args)
20
22
 
21
23
  properties = {
@@ -26,8 +28,9 @@ def _compile_db_span_properties(integration, redis_command, args):
26
28
  return properties
27
29
 
28
30
 
29
- def _get_db_span_description(integration, command_name, args):
30
- # type: (RedisIntegration, str, tuple[Any, ...]) -> str
31
+ def _get_db_span_description(
32
+ integration: RedisIntegration, command_name: str, args: tuple[Any, ...]
33
+ ) -> str:
31
34
  description = command_name
32
35
 
33
36
  with capture_internal_exceptions():
@@ -42,8 +45,7 @@ def _get_db_span_description(integration, command_name, args):
42
45
  return description
43
46
 
44
47
 
45
- def _get_connection_data(connection_params):
46
- # type: (dict[str, Any]) -> dict[str, Any]
48
+ def _get_connection_data(connection_params: dict[str, Any]) -> dict[str, Any]:
47
49
  data = {
48
50
  SPANDATA.DB_SYSTEM: "redis",
49
51
  }
@@ -63,8 +65,7 @@ def _get_connection_data(connection_params):
63
65
  return data
64
66
 
65
67
 
66
- def _get_db_data(redis_instance):
67
- # type: (Redis[Any]) -> dict[str, Any]
68
+ def _get_db_data(redis_instance: Redis[Any]) -> dict[str, Any]:
68
69
  try:
69
70
  return _get_connection_data(redis_instance.connection_pool.connection_kwargs)
70
71
  except AttributeError:
@@ -4,12 +4,13 @@ Instrumentation for Redis Blaster (rb)
4
4
  https://github.com/getsentry/rb
5
5
  """
6
6
 
7
+ from __future__ import annotations
8
+
7
9
  from sentry_sdk.integrations.redis._sync_common import patch_redis_client
8
10
  from sentry_sdk.integrations.redis.modules.queries import _get_db_data
9
11
 
10
12
 
11
- def _patch_rb():
12
- # type: () -> None
13
+ def _patch_rb() -> None:
13
14
  try:
14
15
  import rb.clients # type: ignore
15
16
  except ImportError:
@@ -4,6 +4,8 @@ Instrumentation for Redis
4
4
  https://github.com/redis/redis-py
5
5
  """
6
6
 
7
+ from __future__ import annotations
8
+
7
9
  from sentry_sdk.integrations.redis._sync_common import (
8
10
  patch_redis_client,
9
11
  patch_redis_pipeline,
@@ -16,13 +18,11 @@ if TYPE_CHECKING:
16
18
  from typing import Any, Sequence
17
19
 
18
20
 
19
- def _get_redis_command_args(command):
20
- # type: (Any) -> Sequence[Any]
21
+ def _get_redis_command_args(command: Any) -> Sequence[Any]:
21
22
  return command[0]
22
23
 
23
24
 
24
- def _patch_redis(StrictRedis, client): # noqa: N803
25
- # type: (Any, Any) -> None
25
+ def _patch_redis(StrictRedis: Any, client: Any) -> None: # noqa: N803
26
26
  patch_redis_client(
27
27
  StrictRedis,
28
28
  is_cluster=False,
@@ -5,6 +5,8 @@ This is part of the main redis-py client.
5
5
  https://github.com/redis/redis-py/blob/master/redis/cluster.py
6
6
  """
7
7
 
8
+ from __future__ import annotations
9
+
8
10
  from sentry_sdk.integrations.redis._sync_common import (
9
11
  patch_redis_client,
10
12
  patch_redis_pipeline,
@@ -25,8 +27,9 @@ if TYPE_CHECKING:
25
27
  )
26
28
 
27
29
 
28
- def _get_async_cluster_db_data(async_redis_cluster_instance):
29
- # type: (AsyncRedisCluster[Any]) -> dict[str, Any]
30
+ def _get_async_cluster_db_data(
31
+ async_redis_cluster_instance: AsyncRedisCluster[Any],
32
+ ) -> dict[str, Any]:
30
33
  default_node = async_redis_cluster_instance.get_default_node()
31
34
  if default_node is not None and default_node.connection_kwargs is not None:
32
35
  return _get_connection_data(default_node.connection_kwargs)
@@ -34,18 +37,24 @@ def _get_async_cluster_db_data(async_redis_cluster_instance):
34
37
  return {}
35
38
 
36
39
 
37
- def _get_async_cluster_pipeline_db_data(async_redis_cluster_pipeline_instance):
38
- # type: (AsyncClusterPipeline[Any]) -> dict[str, Any]
40
+ def _get_async_cluster_pipeline_db_data(
41
+ async_redis_cluster_pipeline_instance: AsyncClusterPipeline[Any],
42
+ ) -> dict[str, Any]:
39
43
  with capture_internal_exceptions():
40
- return _get_async_cluster_db_data(
41
- # the AsyncClusterPipeline has always had a `_client` attr but it is private so potentially problematic and mypy
42
- # does not recognize it - see https://github.com/redis/redis-py/blame/v5.0.0/redis/asyncio/cluster.py#L1386
43
- async_redis_cluster_pipeline_instance._client, # type: ignore[attr-defined]
44
- )
44
+ client = getattr(async_redis_cluster_pipeline_instance, "cluster_client", None)
45
+ if client is None:
46
+ # In older redis-py versions, the AsyncClusterPipeline had a `_client`
47
+ # attr but it is private so potentially problematic and mypy does not
48
+ # recognize it - see
49
+ # https://github.com/redis/redis-py/blame/v5.0.0/redis/asyncio/cluster.py#L1386
50
+ client = (
51
+ async_redis_cluster_pipeline_instance._client # type: ignore[attr-defined]
52
+ )
53
+
54
+ return _get_async_cluster_db_data(client)
45
55
 
46
56
 
47
- def _get_cluster_db_data(redis_cluster_instance):
48
- # type: (RedisCluster[Any]) -> dict[str, Any]
57
+ def _get_cluster_db_data(redis_cluster_instance: RedisCluster[Any]) -> dict[str, Any]:
49
58
  default_node = redis_cluster_instance.get_default_node()
50
59
 
51
60
  if default_node is not None:
@@ -58,8 +67,7 @@ def _get_cluster_db_data(redis_cluster_instance):
58
67
  return {}
59
68
 
60
69
 
61
- def _patch_redis_cluster():
62
- # type: () -> None
70
+ def _patch_redis_cluster() -> None:
63
71
  """Patches the cluster module on redis SDK (as opposed to rediscluster library)"""
64
72
  try:
65
73
  from redis import RedisCluster, cluster
@@ -5,6 +5,8 @@ The project redis-py-cluster is EOL and was integrated into redis-py starting fr
5
5
  https://github.com/grokzen/redis-py-cluster
6
6
  """
7
7
 
8
+ from __future__ import annotations
9
+
8
10
  from sentry_sdk.integrations.redis._sync_common import (
9
11
  patch_redis_client,
10
12
  patch_redis_pipeline,
@@ -13,8 +15,7 @@ from sentry_sdk.integrations.redis.modules.queries import _get_db_data
13
15
  from sentry_sdk.integrations.redis.utils import _parse_rediscluster_command
14
16
 
15
17
 
16
- def _patch_rediscluster():
17
- # type: () -> None
18
+ def _patch_rediscluster() -> None:
18
19
  try:
19
20
  import rediscluster # type: ignore
20
21
  except ImportError:
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  import sentry_sdk
2
3
  from sentry_sdk.consts import SPANDATA
3
4
  from sentry_sdk.integrations.redis.consts import (
@@ -26,8 +27,7 @@ TAG_KEYS = [
26
27
  ]
27
28
 
28
29
 
29
- def _update_span(span, *data_bags):
30
- # type: (Span, *dict[str, Any]) -> None
30
+ def _update_span(span: Span, *data_bags: dict[str, Any]) -> None:
31
31
  """
32
32
  Set tags and data on the given span to data from the given data bags.
33
33
  """
@@ -39,8 +39,7 @@ def _update_span(span, *data_bags):
39
39
  span.set_attribute(key, value)
40
40
 
41
41
 
42
- def _create_breadcrumb(message, *data_bags):
43
- # type: (str, *dict[str, Any]) -> None
42
+ def _create_breadcrumb(message: str, *data_bags: dict[str, Any]) -> None:
44
43
  """
45
44
  Create a breadcrumb containing the tags data from the given data bags.
46
45
  """
@@ -58,8 +57,7 @@ def _create_breadcrumb(message, *data_bags):
58
57
  )
59
58
 
60
59
 
61
- def _get_safe_command(name, args):
62
- # type: (str, Sequence[Any]) -> str
60
+ def _get_safe_command(name: str, args: Sequence[Any]) -> str:
63
61
  command_parts = [name]
64
62
 
65
63
  for i, arg in enumerate(args):
@@ -86,8 +84,7 @@ def _get_safe_command(name, args):
86
84
  return command
87
85
 
88
86
 
89
- def _safe_decode(key):
90
- # type: (Any) -> str
87
+ def _safe_decode(key: Any) -> str:
91
88
  if isinstance(key, bytes):
92
89
  try:
93
90
  return key.decode()
@@ -97,8 +94,7 @@ def _safe_decode(key):
97
94
  return str(key)
98
95
 
99
96
 
100
- def _key_as_string(key):
101
- # type: (Any) -> str
97
+ def _key_as_string(key: Any) -> str:
102
98
  if isinstance(key, (dict, list, tuple)):
103
99
  key = ", ".join(_safe_decode(x) for x in key)
104
100
  elif isinstance(key, bytes):
@@ -111,8 +107,9 @@ def _key_as_string(key):
111
107
  return key
112
108
 
113
109
 
114
- def _get_safe_key(method_name, args, kwargs):
115
- # type: (str, Optional[tuple[Any, ...]], Optional[dict[str, Any]]) -> Optional[tuple[str, ...]]
110
+ def _get_safe_key(
111
+ method_name: str, args: Optional[tuple[Any, ...]], kwargs: Optional[dict[str, Any]]
112
+ ) -> Optional[tuple[str, ...]]:
116
113
  """
117
114
  Gets the key (or keys) from the given method_name.
118
115
  The method_name could be a redis command or a django caching command
@@ -142,37 +139,39 @@ def _get_safe_key(method_name, args, kwargs):
142
139
  return key
143
140
 
144
141
 
145
- def _parse_rediscluster_command(command):
146
- # type: (Any) -> Sequence[Any]
142
+ def _parse_rediscluster_command(command: Any) -> Sequence[Any]:
147
143
  return command.args
148
144
 
149
145
 
150
- def _get_pipeline_data(is_cluster, get_command_args_fn, is_transaction, command_stack):
151
- # type: (bool, Any, bool, Sequence[Any]) -> dict[str, Any]
152
- data = {
146
+ def _get_pipeline_data(
147
+ is_cluster: bool,
148
+ get_command_args_fn: Any,
149
+ is_transaction: bool,
150
+ command_seq: Sequence[Any],
151
+ ) -> dict[str, Any]:
152
+ data: dict[str, Any] = {
153
153
  "redis.is_cluster": is_cluster,
154
154
  "redis.transaction": is_transaction,
155
- } # type: dict[str, Any]
155
+ }
156
156
 
157
157
  commands = []
158
- for i, arg in enumerate(command_stack):
158
+ for i, arg in enumerate(command_seq):
159
159
  if i >= _MAX_NUM_COMMANDS:
160
160
  break
161
161
 
162
162
  command = get_command_args_fn(arg)
163
163
  commands.append(_get_safe_command(command[0], command[1:]))
164
164
 
165
- data["redis.commands.count"] = len(command_stack)
165
+ data["redis.commands.count"] = len(command_seq)
166
166
  data["redis.commands.first_ten"] = commands
167
167
 
168
168
  return data
169
169
 
170
170
 
171
- def _get_client_data(is_cluster, name, *args):
172
- # type: (bool, str, *Any) -> dict[str, Any]
173
- data = {
171
+ def _get_client_data(is_cluster: bool, name: str, *args: Any) -> dict[str, Any]:
172
+ data: dict[str, Any] = {
174
173
  "redis.is_cluster": is_cluster,
175
- } # type: dict[str, Any]
174
+ }
176
175
 
177
176
  if name:
178
177
  data["redis.command"] = name
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  import weakref
2
3
 
3
4
  import sentry_sdk
@@ -49,16 +50,16 @@ class RqIntegration(Integration):
49
50
  origin = f"auto.queue.{identifier}"
50
51
 
51
52
  @staticmethod
52
- def setup_once():
53
- # type: () -> None
53
+ def setup_once() -> None:
54
54
  version = parse_version(RQ_VERSION)
55
55
  _check_minimum_version(RqIntegration, version)
56
56
 
57
57
  old_perform_job = Worker.perform_job
58
58
 
59
59
  @ensure_integration_enabled(RqIntegration, old_perform_job)
60
- def sentry_patched_perform_job(self, job, queue, *args, **kwargs):
61
- # type: (Any, Job, Queue, *Any, **Any) -> bool
60
+ def sentry_patched_perform_job(
61
+ self: Any, job: Job, queue: Queue, *args: Any, **kwargs: Any
62
+ ) -> bool:
62
63
  with sentry_sdk.new_scope() as scope:
63
64
  try:
64
65
  transaction_name = job.func_name or DEFAULT_TRANSACTION_NAME
@@ -95,8 +96,9 @@ class RqIntegration(Integration):
95
96
 
96
97
  old_handle_exception = Worker.handle_exception
97
98
 
98
- def sentry_patched_handle_exception(self, job, *exc_info, **kwargs):
99
- # type: (Worker, Any, *Any, **Any) -> Any
99
+ def sentry_patched_handle_exception(
100
+ self: Worker, job: Any, *exc_info: Any, **kwargs: Any
101
+ ) -> Any:
100
102
  retry = (
101
103
  hasattr(job, "retries_left")
102
104
  and job.retries_left
@@ -113,8 +115,7 @@ class RqIntegration(Integration):
113
115
  old_enqueue_job = Queue.enqueue_job
114
116
 
115
117
  @ensure_integration_enabled(RqIntegration, old_enqueue_job)
116
- def sentry_patched_enqueue_job(self, job, **kwargs):
117
- # type: (Queue, Any, **Any) -> Any
118
+ def sentry_patched_enqueue_job(self: Queue, job: Any, **kwargs: Any) -> Any:
118
119
  job.meta["_sentry_trace_headers"] = dict(
119
120
  sentry_sdk.get_current_scope().iter_trace_propagation_headers()
120
121
  )
@@ -126,10 +127,8 @@ class RqIntegration(Integration):
126
127
  ignore_logger("rq.worker")
127
128
 
128
129
 
129
- def _make_event_processor(weak_job):
130
- # type: (Callable[[], Job]) -> EventProcessor
131
- def event_processor(event, hint):
132
- # type: (Event, dict[str, Any]) -> Event
130
+ def _make_event_processor(weak_job: Callable[[], Job]) -> EventProcessor:
131
+ def event_processor(event: Event, hint: dict[str, Any]) -> Event:
133
132
  job = weak_job()
134
133
  if job is not None:
135
134
  with capture_internal_exceptions():
@@ -159,8 +158,7 @@ def _make_event_processor(weak_job):
159
158
  return event_processor
160
159
 
161
160
 
162
- def _capture_exception(exc_info, **kwargs):
163
- # type: (ExcInfo, **Any) -> None
161
+ def _capture_exception(exc_info: ExcInfo, **kwargs: Any) -> None:
164
162
  client = sentry_sdk.get_client()
165
163
 
166
164
  event, hint = event_from_exception(
@@ -172,8 +170,7 @@ def _capture_exception(exc_info, **kwargs):
172
170
  sentry_sdk.capture_event(event, hint=hint)
173
171
 
174
172
 
175
- def _prepopulate_attributes(job, queue):
176
- # type: (Job, Queue) -> dict[str, Any]
173
+ def _prepopulate_attributes(job: Job, queue: Queue) -> dict[str, Any]:
177
174
  attributes = {
178
175
  "messaging.system": "rq",
179
176
  "rq.job.id": job.id,
@@ -30,9 +30,13 @@ sentry_sdk.init(
30
30
  Each native extension requires its own integration.
31
31
  """
32
32
 
33
+ from __future__ import annotations
33
34
  import json
34
35
  from enum import Enum, auto
35
- from typing import Any, Callable, Dict, Optional
36
+ from typing import TYPE_CHECKING
37
+
38
+ if TYPE_CHECKING:
39
+ from typing import Any, Callable, Dict, Optional
36
40
 
37
41
  import sentry_sdk
38
42
  from sentry_sdk.integrations import Integration
@@ -56,8 +60,7 @@ class EventTypeMapping(Enum):
56
60
  Event = auto()
57
61
 
58
62
 
59
- def tracing_level_to_sentry_level(level):
60
- # type: (str) -> sentry_sdk._types.LogLevelStr
63
+ def tracing_level_to_sentry_level(level: str) -> sentry_sdk._types.LogLevelStr:
61
64
  level = RustTracingLevel(level)
62
65
  if level in (RustTracingLevel.Trace, RustTracingLevel.Debug):
63
66
  return "debug"
@@ -97,15 +100,15 @@ def process_event(event: Dict[str, Any]) -> None:
97
100
 
98
101
  logger = metadata.get("target")
99
102
  level = tracing_level_to_sentry_level(metadata.get("level"))
100
- message = event.get("message") # type: sentry_sdk._types.Any
103
+ message: sentry_sdk._types.Any = event.get("message")
101
104
  contexts = extract_contexts(event)
102
105
 
103
- sentry_event = {
106
+ sentry_event: sentry_sdk._types.Event = {
104
107
  "logger": logger,
105
108
  "level": level,
106
109
  "message": message,
107
110
  "contexts": contexts,
108
- } # type: sentry_sdk._types.Event
111
+ }
109
112
 
110
113
  sentry_sdk.capture_event(sentry_event)
111
114
 
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  import sys
2
3
  import weakref
3
4
  from inspect import isawaitable
@@ -59,8 +60,9 @@ class SanicIntegration(Integration):
59
60
  origin = f"auto.http.{identifier}"
60
61
  version = None
61
62
 
62
- def __init__(self, unsampled_statuses=frozenset({404})):
63
- # type: (Optional[Container[int]]) -> None
63
+ def __init__(
64
+ self, unsampled_statuses: Optional[Container[int]] = frozenset({404})
65
+ ) -> None:
64
66
  """
65
67
  The unsampled_statuses parameter can be used to specify for which HTTP statuses the
66
68
  transactions should not be sent to Sentry. By default, transactions are sent for all
@@ -70,8 +72,7 @@ class SanicIntegration(Integration):
70
72
  self._unsampled_statuses = unsampled_statuses or set()
71
73
 
72
74
  @staticmethod
73
- def setup_once():
74
- # type: () -> None
75
+ def setup_once() -> None:
75
76
  SanicIntegration.version = parse_version(SANIC_VERSION)
76
77
  _check_minimum_version(SanicIntegration, SanicIntegration.version)
77
78
 
@@ -103,56 +104,45 @@ class SanicIntegration(Integration):
103
104
 
104
105
 
105
106
  class SanicRequestExtractor(RequestExtractor):
106
- def content_length(self):
107
- # type: () -> int
107
+ def content_length(self) -> int:
108
108
  if self.request.body is None:
109
109
  return 0
110
110
  return len(self.request.body)
111
111
 
112
- def cookies(self):
113
- # type: () -> Dict[str, str]
112
+ def cookies(self) -> Dict[str, str]:
114
113
  return dict(self.request.cookies)
115
114
 
116
- def raw_data(self):
117
- # type: () -> bytes
115
+ def raw_data(self) -> bytes:
118
116
  return self.request.body
119
117
 
120
- def form(self):
121
- # type: () -> RequestParameters
118
+ def form(self) -> RequestParameters:
122
119
  return self.request.form
123
120
 
124
- def is_json(self):
125
- # type: () -> bool
121
+ def is_json(self) -> bool:
126
122
  raise NotImplementedError()
127
123
 
128
- def json(self):
129
- # type: () -> Optional[Any]
124
+ def json(self) -> Optional[Any]:
130
125
  return self.request.json
131
126
 
132
- def files(self):
133
- # type: () -> RequestParameters
127
+ def files(self) -> RequestParameters:
134
128
  return self.request.files
135
129
 
136
- def size_of_file(self, file):
137
- # type: (Any) -> int
130
+ def size_of_file(self, file: Any) -> int:
138
131
  return len(file.body or ())
139
132
 
140
133
 
141
- def _setup_sanic():
142
- # type: () -> None
134
+ def _setup_sanic() -> None:
143
135
  Sanic._startup = _startup
144
136
  ErrorHandler.lookup = _sentry_error_handler_lookup
145
137
 
146
138
 
147
- def _setup_legacy_sanic():
148
- # type: () -> None
139
+ def _setup_legacy_sanic() -> None:
149
140
  Sanic.handle_request = _legacy_handle_request
150
141
  Router.get = _legacy_router_get
151
142
  ErrorHandler.lookup = _sentry_error_handler_lookup
152
143
 
153
144
 
154
- async def _startup(self):
155
- # type: (Sanic) -> None
145
+ async def _startup(self: Sanic) -> None:
156
146
  # This happens about as early in the lifecycle as possible, just after the
157
147
  # Request object is created. The body has not yet been consumed.
158
148
  self.signal("http.lifecycle.request")(_context_enter)
@@ -171,8 +161,7 @@ async def _startup(self):
171
161
  await old_startup(self)
172
162
 
173
163
 
174
- async def _context_enter(request):
175
- # type: (Request) -> None
164
+ async def _context_enter(request: Request) -> None:
176
165
  request.ctx._sentry_do_integration = (
177
166
  sentry_sdk.get_client().get_integration(SanicIntegration) is not None
178
167
  )
@@ -203,8 +192,9 @@ async def _context_enter(request):
203
192
  ).__enter__()
204
193
 
205
194
 
206
- async def _context_exit(request, response=None):
207
- # type: (Request, Optional[BaseHTTPResponse]) -> None
195
+ async def _context_exit(
196
+ request: Request, response: Optional[BaseHTTPResponse] = None
197
+ ) -> None:
208
198
  with capture_internal_exceptions():
209
199
  if not request.ctx._sentry_do_integration:
210
200
  return
@@ -233,8 +223,7 @@ async def _context_exit(request, response=None):
233
223
  request.ctx._sentry_scope_manager.__exit__(None, None, None)
234
224
 
235
225
 
236
- async def _set_transaction(request, route, **_):
237
- # type: (Request, Route, **Any) -> None
226
+ async def _set_transaction(request: Request, route: Route, **_: Any) -> None:
238
227
  if request.ctx._sentry_do_integration:
239
228
  with capture_internal_exceptions():
240
229
  scope = sentry_sdk.get_current_scope()
@@ -242,8 +231,9 @@ async def _set_transaction(request, route, **_):
242
231
  scope.set_transaction_name(route_name, source=TransactionSource.COMPONENT)
243
232
 
244
233
 
245
- def _sentry_error_handler_lookup(self, exception, *args, **kwargs):
246
- # type: (Any, Exception, *Any, **Any) -> Optional[object]
234
+ def _sentry_error_handler_lookup(
235
+ self: Any, exception: Exception, *args: Any, **kwargs: Any
236
+ ) -> Optional[object]:
247
237
  _capture_exception(exception)
248
238
  old_error_handler = old_error_handler_lookup(self, exception, *args, **kwargs)
249
239
 
@@ -253,8 +243,9 @@ def _sentry_error_handler_lookup(self, exception, *args, **kwargs):
253
243
  if sentry_sdk.get_client().get_integration(SanicIntegration) is None:
254
244
  return old_error_handler
255
245
 
256
- async def sentry_wrapped_error_handler(request, exception):
257
- # type: (Request, Exception) -> Any
246
+ async def sentry_wrapped_error_handler(
247
+ request: Request, exception: Exception
248
+ ) -> Any:
258
249
  try:
259
250
  response = old_error_handler(request, exception)
260
251
  if isawaitable(response):
@@ -276,8 +267,9 @@ def _sentry_error_handler_lookup(self, exception, *args, **kwargs):
276
267
  return sentry_wrapped_error_handler
277
268
 
278
269
 
279
- async def _legacy_handle_request(self, request, *args, **kwargs):
280
- # type: (Any, Request, *Any, **Any) -> Any
270
+ async def _legacy_handle_request(
271
+ self: Any, request: Request, *args: Any, **kwargs: Any
272
+ ) -> Any:
281
273
  if sentry_sdk.get_client().get_integration(SanicIntegration) is None:
282
274
  return await old_handle_request(self, request, *args, **kwargs)
283
275
 
@@ -294,8 +286,7 @@ async def _legacy_handle_request(self, request, *args, **kwargs):
294
286
  return response
295
287
 
296
288
 
297
- def _legacy_router_get(self, *args):
298
- # type: (Any, Union[Any, Request]) -> Any
289
+ def _legacy_router_get(self: Any, *args: Union[Any, Request]) -> Any:
299
290
  rv = old_router_get(self, *args)
300
291
  if sentry_sdk.get_client().get_integration(SanicIntegration) is not None:
301
292
  with capture_internal_exceptions():
@@ -325,8 +316,7 @@ def _legacy_router_get(self, *args):
325
316
 
326
317
 
327
318
  @ensure_integration_enabled(SanicIntegration)
328
- def _capture_exception(exception):
329
- # type: (Union[ExcInfo, BaseException]) -> None
319
+ def _capture_exception(exception: Union[ExcInfo, BaseException]) -> None:
330
320
  with capture_internal_exceptions():
331
321
  event, hint = event_from_exception(
332
322
  exception,
@@ -340,10 +330,8 @@ def _capture_exception(exception):
340
330
  sentry_sdk.capture_event(event, hint=hint)
341
331
 
342
332
 
343
- def _make_request_processor(weak_request):
344
- # type: (Callable[[], Request]) -> EventProcessor
345
- def sanic_processor(event, hint):
346
- # type: (Event, Optional[Hint]) -> Optional[Event]
333
+ def _make_request_processor(weak_request: Callable[[], Request]) -> EventProcessor:
334
+ def sanic_processor(event: Event, hint: Optional[Hint]) -> Optional[Event]:
347
335
 
348
336
  try:
349
337
  if hint and issubclass(hint["exc_info"][0], SanicException):