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
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  import functools
2
3
  import inspect
3
4
  import sys
@@ -107,18 +108,17 @@ class DjangoIntegration(Integration):
107
108
  middleware_spans = None
108
109
  signals_spans = None
109
110
  cache_spans = None
110
- signals_denylist = [] # type: list[signals.Signal]
111
+ signals_denylist: list[signals.Signal] = []
111
112
 
112
113
  def __init__(
113
114
  self,
114
- transaction_style="url", # type: str
115
- middleware_spans=True, # type: bool
116
- signals_spans=True, # type: bool
117
- cache_spans=True, # type: bool
118
- signals_denylist=None, # type: Optional[list[signals.Signal]]
119
- http_methods_to_capture=DEFAULT_HTTP_METHODS_TO_CAPTURE, # type: tuple[str, ...]
120
- ):
121
- # type: (...) -> None
115
+ transaction_style: str = "url",
116
+ middleware_spans: bool = True,
117
+ signals_spans: bool = True,
118
+ cache_spans: bool = True,
119
+ signals_denylist: Optional[list[signals.Signal]] = None,
120
+ http_methods_to_capture: tuple[str, ...] = DEFAULT_HTTP_METHODS_TO_CAPTURE,
121
+ ) -> None:
122
122
  if transaction_style not in TRANSACTION_STYLE_VALUES:
123
123
  raise ValueError(
124
124
  "Invalid value for transaction_style: %s (must be in %s)"
@@ -135,8 +135,7 @@ class DjangoIntegration(Integration):
135
135
  self.http_methods_to_capture = tuple(map(str.upper, http_methods_to_capture))
136
136
 
137
137
  @staticmethod
138
- def setup_once():
139
- # type: () -> None
138
+ def setup_once() -> None:
140
139
  _check_minimum_version(DjangoIntegration, DJANGO_VERSION)
141
140
 
142
141
  install_sql_hook()
@@ -151,8 +150,9 @@ class DjangoIntegration(Integration):
151
150
  old_app = WSGIHandler.__call__
152
151
 
153
152
  @ensure_integration_enabled(DjangoIntegration, old_app)
154
- def sentry_patched_wsgi_handler(self, environ, start_response):
155
- # type: (Any, Dict[str, str], Callable[..., Any]) -> _ScopedResponse
153
+ def sentry_patched_wsgi_handler(
154
+ self: Any, environ: Dict[str, str], start_response: Callable[..., Any]
155
+ ) -> _ScopedResponse:
156
156
  bound_old_app = old_app.__get__(self, WSGIHandler)
157
157
 
158
158
  from django.conf import settings
@@ -182,8 +182,9 @@ class DjangoIntegration(Integration):
182
182
  signals.got_request_exception.connect(_got_request_exception)
183
183
 
184
184
  @add_global_event_processor
185
- def process_django_templates(event, hint):
186
- # type: (Event, Optional[Hint]) -> Optional[Event]
185
+ def process_django_templates(
186
+ event: Event, hint: Optional[Hint]
187
+ ) -> Optional[Event]:
187
188
  if hint is None:
188
189
  return event
189
190
 
@@ -225,8 +226,9 @@ class DjangoIntegration(Integration):
225
226
  return event
226
227
 
227
228
  @add_global_repr_processor
228
- def _django_queryset_repr(value, hint):
229
- # type: (Any, Dict[str, Any]) -> Union[NotImplementedType, str]
229
+ def _django_queryset_repr(
230
+ value: Any, hint: Dict[str, Any]
231
+ ) -> Union[NotImplementedType, str]:
230
232
  try:
231
233
  # Django 1.6 can fail to import `QuerySet` when Django settings
232
234
  # have not yet been initialized.
@@ -261,8 +263,7 @@ _DRF_PATCHED = False
261
263
  _DRF_PATCH_LOCK = threading.Lock()
262
264
 
263
265
 
264
- def _patch_drf():
265
- # type: () -> None
266
+ def _patch_drf() -> None:
266
267
  """
267
268
  Patch Django Rest Framework for more/better request data. DRF's request
268
269
  type is a wrapper around Django's request type. The attribute we're
@@ -305,8 +306,9 @@ def _patch_drf():
305
306
  old_drf_initial = APIView.initial
306
307
 
307
308
  @functools.wraps(old_drf_initial)
308
- def sentry_patched_drf_initial(self, request, *args, **kwargs):
309
- # type: (APIView, Any, *Any, **Any) -> Any
309
+ def sentry_patched_drf_initial(
310
+ self: APIView, request: Any, *args: Any, **kwargs: Any
311
+ ) -> Any:
310
312
  with capture_internal_exceptions():
311
313
  request._request._sentry_drf_request_backref = weakref.ref(
312
314
  request
@@ -317,8 +319,7 @@ def _patch_drf():
317
319
  APIView.initial = sentry_patched_drf_initial
318
320
 
319
321
 
320
- def _patch_channels():
321
- # type: () -> None
322
+ def _patch_channels() -> None:
322
323
  try:
323
324
  from channels.http import AsgiHandler # type: ignore
324
325
  except ImportError:
@@ -342,8 +343,7 @@ def _patch_channels():
342
343
  patch_channels_asgi_handler_impl(AsgiHandler)
343
344
 
344
345
 
345
- def _patch_django_asgi_handler():
346
- # type: () -> None
346
+ def _patch_django_asgi_handler() -> None:
347
347
  try:
348
348
  from django.core.handlers.asgi import ASGIHandler
349
349
  except ImportError:
@@ -364,8 +364,9 @@ def _patch_django_asgi_handler():
364
364
  patch_django_asgi_handler_impl(ASGIHandler)
365
365
 
366
366
 
367
- def _set_transaction_name_and_source(scope, transaction_style, request):
368
- # type: (sentry_sdk.Scope, str, WSGIRequest) -> None
367
+ def _set_transaction_name_and_source(
368
+ scope: sentry_sdk.Scope, transaction_style: str, request: WSGIRequest
369
+ ) -> None:
369
370
  try:
370
371
  transaction_name = None
371
372
  if transaction_style == "function_name":
@@ -408,8 +409,7 @@ def _set_transaction_name_and_source(scope, transaction_style, request):
408
409
  pass
409
410
 
410
411
 
411
- def _before_get_response(request):
412
- # type: (WSGIRequest) -> None
412
+ def _before_get_response(request: WSGIRequest) -> None:
413
413
  integration = sentry_sdk.get_client().get_integration(DjangoIntegration)
414
414
  if integration is None:
415
415
  return
@@ -425,8 +425,9 @@ def _before_get_response(request):
425
425
  )
426
426
 
427
427
 
428
- def _attempt_resolve_again(request, scope, transaction_style):
429
- # type: (WSGIRequest, sentry_sdk.Scope, str) -> None
428
+ def _attempt_resolve_again(
429
+ request: WSGIRequest, scope: sentry_sdk.Scope, transaction_style: str
430
+ ) -> None:
430
431
  """
431
432
  Some django middlewares overwrite request.urlconf
432
433
  so we need to respect that contract,
@@ -438,8 +439,7 @@ def _attempt_resolve_again(request, scope, transaction_style):
438
439
  _set_transaction_name_and_source(scope, transaction_style, request)
439
440
 
440
441
 
441
- def _after_get_response(request):
442
- # type: (WSGIRequest) -> None
442
+ def _after_get_response(request: WSGIRequest) -> None:
443
443
  integration = sentry_sdk.get_client().get_integration(DjangoIntegration)
444
444
  if integration is None or integration.transaction_style != "url":
445
445
  return
@@ -448,8 +448,7 @@ def _after_get_response(request):
448
448
  _attempt_resolve_again(request, scope, integration.transaction_style)
449
449
 
450
450
 
451
- def _patch_get_response():
452
- # type: () -> None
451
+ def _patch_get_response() -> None:
453
452
  """
454
453
  patch get_response, because at that point we have the Django request object
455
454
  """
@@ -458,8 +457,9 @@ def _patch_get_response():
458
457
  old_get_response = BaseHandler.get_response
459
458
 
460
459
  @functools.wraps(old_get_response)
461
- def sentry_patched_get_response(self, request):
462
- # type: (Any, WSGIRequest) -> Union[HttpResponse, BaseException]
460
+ def sentry_patched_get_response(
461
+ self: Any, request: WSGIRequest
462
+ ) -> Union[HttpResponse, BaseException]:
463
463
  _before_get_response(request)
464
464
  rv = old_get_response(self, request)
465
465
  _after_get_response(request)
@@ -473,10 +473,10 @@ def _patch_get_response():
473
473
  patch_get_response_async(BaseHandler, _before_get_response)
474
474
 
475
475
 
476
- def _make_wsgi_request_event_processor(weak_request, integration):
477
- # type: (Callable[[], WSGIRequest], DjangoIntegration) -> EventProcessor
478
- def wsgi_request_event_processor(event, hint):
479
- # type: (Event, dict[str, Any]) -> Event
476
+ def _make_wsgi_request_event_processor(
477
+ weak_request: Callable[[], WSGIRequest], integration: DjangoIntegration
478
+ ) -> EventProcessor:
479
+ def wsgi_request_event_processor(event: Event, hint: dict[str, Any]) -> Event:
480
480
  # if the request is gone we are fine not logging the data from
481
481
  # it. This might happen if the processor is pushed away to
482
482
  # another thread.
@@ -501,8 +501,7 @@ def _make_wsgi_request_event_processor(weak_request, integration):
501
501
  return wsgi_request_event_processor
502
502
 
503
503
 
504
- def _got_request_exception(request=None, **kwargs):
505
- # type: (WSGIRequest, **Any) -> None
504
+ def _got_request_exception(request: WSGIRequest = None, **kwargs: Any) -> None:
506
505
  client = sentry_sdk.get_client()
507
506
  integration = client.get_integration(DjangoIntegration)
508
507
  if integration is None:
@@ -521,8 +520,7 @@ def _got_request_exception(request=None, **kwargs):
521
520
 
522
521
 
523
522
  class DjangoRequestExtractor(RequestExtractor):
524
- def __init__(self, request):
525
- # type: (Union[WSGIRequest, ASGIRequest]) -> None
523
+ def __init__(self, request: Union[WSGIRequest, ASGIRequest]) -> None:
526
524
  try:
527
525
  drf_request = request._sentry_drf_request_backref()
528
526
  if drf_request is not None:
@@ -531,18 +529,16 @@ class DjangoRequestExtractor(RequestExtractor):
531
529
  pass
532
530
  self.request = request
533
531
 
534
- def env(self):
535
- # type: () -> Dict[str, str]
532
+ def env(self) -> Dict[str, str]:
536
533
  return self.request.META
537
534
 
538
- def cookies(self):
539
- # type: () -> Dict[str, Union[str, AnnotatedValue]]
535
+ def cookies(self) -> Dict[str, Union[str, AnnotatedValue]]:
540
536
  privacy_cookies = [
541
537
  django_settings.CSRF_COOKIE_NAME,
542
538
  django_settings.SESSION_COOKIE_NAME,
543
539
  ]
544
540
 
545
- clean_cookies = {} # type: Dict[str, Union[str, AnnotatedValue]]
541
+ clean_cookies: Dict[str, Union[str, AnnotatedValue]] = {}
546
542
  for key, val in self.request.COOKIES.items():
547
543
  if key in privacy_cookies:
548
544
  clean_cookies[key] = SENSITIVE_DATA_SUBSTITUTE
@@ -551,32 +547,26 @@ class DjangoRequestExtractor(RequestExtractor):
551
547
 
552
548
  return clean_cookies
553
549
 
554
- def raw_data(self):
555
- # type: () -> bytes
550
+ def raw_data(self) -> bytes:
556
551
  return self.request.body
557
552
 
558
- def form(self):
559
- # type: () -> QueryDict
553
+ def form(self) -> QueryDict:
560
554
  return self.request.POST
561
555
 
562
- def files(self):
563
- # type: () -> MultiValueDict
556
+ def files(self) -> MultiValueDict:
564
557
  return self.request.FILES
565
558
 
566
- def size_of_file(self, file):
567
- # type: (Any) -> int
559
+ def size_of_file(self, file: Any) -> int:
568
560
  return file.size
569
561
 
570
- def parsed_body(self):
571
- # type: () -> Optional[Dict[str, Any]]
562
+ def parsed_body(self) -> Optional[Dict[str, Any]]:
572
563
  try:
573
564
  return self.request.data
574
565
  except Exception:
575
566
  return RequestExtractor.parsed_body(self)
576
567
 
577
568
 
578
- def _set_user_info(request, event):
579
- # type: (WSGIRequest, Event) -> None
569
+ def _set_user_info(request: WSGIRequest, event: Event) -> None:
580
570
  user_info = event.setdefault("user", {})
581
571
 
582
572
  user = getattr(request, "user", None)
@@ -600,8 +590,7 @@ def _set_user_info(request, event):
600
590
  pass
601
591
 
602
592
 
603
- def install_sql_hook():
604
- # type: () -> None
593
+ def install_sql_hook() -> None:
605
594
  """If installed this causes Django's queries to be captured."""
606
595
  try:
607
596
  from django.db.backends.utils import CursorWrapper
@@ -615,8 +604,7 @@ def install_sql_hook():
615
604
  real_connect = BaseDatabaseWrapper.connect
616
605
 
617
606
  @ensure_integration_enabled(DjangoIntegration, real_execute)
618
- def execute(self, sql, params=None):
619
- # type: (CursorWrapper, Any, Optional[Any]) -> Any
607
+ def execute(self: CursorWrapper, sql: Any, params: Optional[Any] = None) -> Any:
620
608
  with record_sql_queries(
621
609
  cursor=self.cursor,
622
610
  query=sql,
@@ -634,8 +622,7 @@ def install_sql_hook():
634
622
  return result
635
623
 
636
624
  @ensure_integration_enabled(DjangoIntegration, real_executemany)
637
- def executemany(self, sql, param_list):
638
- # type: (CursorWrapper, Any, List[Any]) -> Any
625
+ def executemany(self: CursorWrapper, sql: Any, param_list: List[Any]) -> Any:
639
626
  with record_sql_queries(
640
627
  cursor=self.cursor,
641
628
  query=sql,
@@ -654,8 +641,7 @@ def install_sql_hook():
654
641
  return result
655
642
 
656
643
  @ensure_integration_enabled(DjangoIntegration, real_connect)
657
- def connect(self):
658
- # type: (BaseDatabaseWrapper) -> None
644
+ def connect(self: BaseDatabaseWrapper) -> None:
659
645
  with capture_internal_exceptions():
660
646
  sentry_sdk.add_breadcrumb(message="connect", category="query")
661
647
 
@@ -674,8 +660,7 @@ def install_sql_hook():
674
660
  ignore_logger("django.db.backends")
675
661
 
676
662
 
677
- def _set_db_data(span, cursor_or_db):
678
- # type: (Span, Any) -> None
663
+ def _set_db_data(span: Span, cursor_or_db: Any) -> None:
679
664
  db = cursor_or_db.db if hasattr(cursor_or_db, "db") else cursor_or_db
680
665
  vendor = db.vendor
681
666
  span.set_attribute(SPANDATA.DB_SYSTEM, vendor)
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  """
2
4
  Instrumentation for Django 3.0
3
5
 
@@ -51,10 +53,8 @@ else:
51
53
  return func
52
54
 
53
55
 
54
- def _make_asgi_request_event_processor(request):
55
- # type: (ASGIRequest) -> EventProcessor
56
- def asgi_request_event_processor(event, hint):
57
- # type: (Event, dict[str, Any]) -> Event
56
+ def _make_asgi_request_event_processor(request: ASGIRequest) -> EventProcessor:
57
+ def asgi_request_event_processor(event: Event, hint: dict[str, Any]) -> Event:
58
58
  # if the request is gone we are fine not logging the data from
59
59
  # it. This might happen if the processor is pushed away to
60
60
  # another thread.
@@ -81,16 +81,16 @@ def _make_asgi_request_event_processor(request):
81
81
  return asgi_request_event_processor
82
82
 
83
83
 
84
- def patch_django_asgi_handler_impl(cls):
85
- # type: (Any) -> None
84
+ def patch_django_asgi_handler_impl(cls: Any) -> None:
86
85
 
87
86
  from sentry_sdk.integrations.django import DjangoIntegration
88
87
 
89
88
  old_app = cls.__call__
90
89
 
91
90
  @functools.wraps(old_app)
92
- async def sentry_patched_asgi_handler(self, scope, receive, send):
93
- # type: (Any, Any, Any, Any) -> Any
91
+ async def sentry_patched_asgi_handler(
92
+ self: Any, scope: Any, receive: Any, send: Any
93
+ ) -> Any:
94
94
  integration = sentry_sdk.get_client().get_integration(DjangoIntegration)
95
95
  if integration is None:
96
96
  return await old_app(self, scope, receive, send)
@@ -111,8 +111,7 @@ def patch_django_asgi_handler_impl(cls):
111
111
  old_create_request = cls.create_request
112
112
 
113
113
  @ensure_integration_enabled(DjangoIntegration, old_create_request)
114
- def sentry_patched_create_request(self, *args, **kwargs):
115
- # type: (Any, *Any, **Any) -> Any
114
+ def sentry_patched_create_request(self: Any, *args: Any, **kwargs: Any) -> Any:
116
115
  request, error_response = old_create_request(self, *args, **kwargs)
117
116
  scope = sentry_sdk.get_isolation_scope()
118
117
  scope.add_event_processor(_make_asgi_request_event_processor(request))
@@ -122,21 +121,20 @@ def patch_django_asgi_handler_impl(cls):
122
121
  cls.create_request = sentry_patched_create_request
123
122
 
124
123
 
125
- def patch_get_response_async(cls, _before_get_response):
126
- # type: (Any, Any) -> None
124
+ def patch_get_response_async(cls: Any, _before_get_response: Any) -> None:
127
125
  old_get_response_async = cls.get_response_async
128
126
 
129
127
  @functools.wraps(old_get_response_async)
130
- async def sentry_patched_get_response_async(self, request):
131
- # type: (Any, Any) -> Union[HttpResponse, BaseException]
128
+ async def sentry_patched_get_response_async(
129
+ self: Any, request: Any
130
+ ) -> Union[HttpResponse, BaseException]:
132
131
  _before_get_response(request)
133
132
  return await old_get_response_async(self, request)
134
133
 
135
134
  cls.get_response_async = sentry_patched_get_response_async
136
135
 
137
136
 
138
- def patch_channels_asgi_handler_impl(cls):
139
- # type: (Any) -> None
137
+ def patch_channels_asgi_handler_impl(cls: Any) -> None:
140
138
  import channels # type: ignore
141
139
 
142
140
  from sentry_sdk.integrations.django import DjangoIntegration
@@ -145,8 +143,9 @@ def patch_channels_asgi_handler_impl(cls):
145
143
  old_app = cls.__call__
146
144
 
147
145
  @functools.wraps(old_app)
148
- async def sentry_patched_asgi_handler(self, receive, send):
149
- # type: (Any, Any, Any) -> Any
146
+ async def sentry_patched_asgi_handler(
147
+ self: Any, receive: Any, send: Any
148
+ ) -> Any:
150
149
  integration = sentry_sdk.get_client().get_integration(DjangoIntegration)
151
150
  if integration is None:
152
151
  return await old_app(self, receive, send)
@@ -168,13 +167,11 @@ def patch_channels_asgi_handler_impl(cls):
168
167
  patch_django_asgi_handler_impl(cls)
169
168
 
170
169
 
171
- def wrap_async_view(callback):
172
- # type: (Any) -> Any
170
+ def wrap_async_view(callback: Any) -> Any:
173
171
  from sentry_sdk.integrations.django import DjangoIntegration
174
172
 
175
173
  @functools.wraps(callback)
176
- async def sentry_wrapped_callback(request, *args, **kwargs):
177
- # type: (Any, *Any, **Any) -> Any
174
+ async def sentry_wrapped_callback(request: Any, *args: Any, **kwargs: Any) -> Any:
178
175
  current_scope = sentry_sdk.get_current_scope()
179
176
  if current_scope.root_span is not None:
180
177
  current_scope.root_span.update_active_thread()
@@ -194,8 +191,7 @@ def wrap_async_view(callback):
194
191
  return sentry_wrapped_callback
195
192
 
196
193
 
197
- def _asgi_middleware_mixin_factory(_check_middleware_span):
198
- # type: (Callable[..., Any]) -> Any
194
+ def _asgi_middleware_mixin_factory(_check_middleware_span: Callable[..., Any]) -> Any:
199
195
  """
200
196
  Mixin class factory that generates a middleware mixin for handling requests
201
197
  in async mode.
@@ -205,14 +201,12 @@ def _asgi_middleware_mixin_factory(_check_middleware_span):
205
201
  if TYPE_CHECKING:
206
202
  _inner = None
207
203
 
208
- def __init__(self, get_response):
209
- # type: (Callable[..., Any]) -> None
204
+ def __init__(self, get_response: Callable[..., Any]) -> None:
210
205
  self.get_response = get_response
211
206
  self._acall_method = None
212
207
  self._async_check()
213
208
 
214
- def _async_check(self):
215
- # type: () -> None
209
+ def _async_check(self) -> None:
216
210
  """
217
211
  If get_response is a coroutine function, turns us into async mode so
218
212
  a thread is not consumed during a whole request.
@@ -221,16 +215,14 @@ def _asgi_middleware_mixin_factory(_check_middleware_span):
221
215
  if iscoroutinefunction(self.get_response):
222
216
  markcoroutinefunction(self)
223
217
 
224
- def async_route_check(self):
225
- # type: () -> bool
218
+ def async_route_check(self) -> bool:
226
219
  """
227
220
  Function that checks if we are in async mode,
228
221
  and if we are forwards the handling of requests to __acall__
229
222
  """
230
223
  return iscoroutinefunction(self.get_response)
231
224
 
232
- async def __acall__(self, *args, **kwargs):
233
- # type: (*Any, **Any) -> Any
225
+ async def __acall__(self, *args: Any, **kwargs: Any) -> Any:
234
226
  f = self._acall_method
235
227
  if f is None:
236
228
  if hasattr(self._inner, "__acall__"):
@@ -241,9 +233,9 @@ def _asgi_middleware_mixin_factory(_check_middleware_span):
241
233
  middleware_span = _check_middleware_span(old_method=f)
242
234
 
243
235
  if middleware_span is None:
244
- return await f(*args, **kwargs)
236
+ return await f(*args, **kwargs) # type: ignore
245
237
 
246
238
  with middleware_span:
247
- return await f(*args, **kwargs)
239
+ return await f(*args, **kwargs) # type: ignore
248
240
 
249
241
  return SentryASGIMixin
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  import functools
2
3
  from typing import TYPE_CHECKING
3
4
  from sentry_sdk.integrations.redis.utils import _get_safe_key, _key_as_string
@@ -28,22 +29,29 @@ METHODS_TO_INSTRUMENT = [
28
29
  ]
29
30
 
30
31
 
31
- def _get_span_description(method_name, args, kwargs):
32
- # type: (str, tuple[Any], dict[str, Any]) -> str
32
+ def _get_span_description(
33
+ method_name: str, args: tuple[Any], kwargs: dict[str, Any]
34
+ ) -> str:
33
35
  return _key_as_string(_get_safe_key(method_name, args, kwargs))
34
36
 
35
37
 
36
- def _patch_cache_method(cache, method_name, address, port):
37
- # type: (CacheHandler, str, Optional[str], Optional[int]) -> None
38
+ def _patch_cache_method(
39
+ cache: CacheHandler, method_name: str, address: Optional[str], port: Optional[int]
40
+ ) -> None:
38
41
  from sentry_sdk.integrations.django import DjangoIntegration
39
42
 
40
43
  original_method = getattr(cache, method_name)
41
44
 
42
45
  @ensure_integration_enabled(DjangoIntegration, original_method)
43
46
  def _instrument_call(
44
- cache, method_name, original_method, args, kwargs, address, port
45
- ):
46
- # type: (CacheHandler, str, Callable[..., Any], tuple[Any, ...], dict[str, Any], Optional[str], Optional[int]) -> Any
47
+ cache: CacheHandler,
48
+ method_name: str,
49
+ original_method: Callable[..., Any],
50
+ args: tuple[Any, ...],
51
+ kwargs: dict[str, Any],
52
+ address: Optional[str],
53
+ port: Optional[int],
54
+ ) -> Any:
47
55
  is_set_operation = method_name.startswith("set")
48
56
  is_get_operation = not is_set_operation
49
57
 
@@ -91,8 +99,7 @@ def _patch_cache_method(cache, method_name, address, port):
91
99
  return value
92
100
 
93
101
  @functools.wraps(original_method)
94
- def sentry_method(*args, **kwargs):
95
- # type: (*Any, **Any) -> Any
102
+ def sentry_method(*args: Any, **kwargs: Any) -> Any:
96
103
  return _instrument_call(
97
104
  cache, method_name, original_method, args, kwargs, address, port
98
105
  )
@@ -100,16 +107,16 @@ def _patch_cache_method(cache, method_name, address, port):
100
107
  setattr(cache, method_name, sentry_method)
101
108
 
102
109
 
103
- def _patch_cache(cache, address=None, port=None):
104
- # type: (CacheHandler, Optional[str], Optional[int]) -> None
110
+ def _patch_cache(
111
+ cache: CacheHandler, address: Optional[str] = None, port: Optional[int] = None
112
+ ) -> None:
105
113
  if not hasattr(cache, "_sentry_patched"):
106
114
  for method_name in METHODS_TO_INSTRUMENT:
107
115
  _patch_cache_method(cache, method_name, address, port)
108
116
  cache._sentry_patched = True
109
117
 
110
118
 
111
- def _get_address_port(settings):
112
- # type: (dict[str, Any]) -> tuple[Optional[str], Optional[int]]
119
+ def _get_address_port(settings: dict[str, Any]) -> tuple[Optional[str], Optional[int]]:
113
120
  location = settings.get("LOCATION")
114
121
 
115
122
  # TODO: location can also be an array of locations
@@ -134,8 +141,7 @@ def _get_address_port(settings):
134
141
  return address, int(port) if port is not None else None
135
142
 
136
143
 
137
- def patch_caching():
138
- # type: () -> None
144
+ def patch_caching() -> None:
139
145
  from sentry_sdk.integrations.django import DjangoIntegration
140
146
 
141
147
  if not hasattr(CacheHandler, "_sentry_patched"):
@@ -143,8 +149,7 @@ def patch_caching():
143
149
  original_get_item = CacheHandler.__getitem__
144
150
 
145
151
  @functools.wraps(original_get_item)
146
- def sentry_get_item(self, alias):
147
- # type: (CacheHandler, str) -> Any
152
+ def sentry_get_item(self: CacheHandler, alias: str) -> Any:
148
153
  cache = original_get_item(self, alias)
149
154
 
150
155
  integration = sentry_sdk.get_client().get_integration(DjangoIntegration)
@@ -166,8 +171,7 @@ def patch_caching():
166
171
  original_create_connection = CacheHandler.create_connection
167
172
 
168
173
  @functools.wraps(original_create_connection)
169
- def sentry_create_connection(self, alias):
170
- # type: (CacheHandler, str) -> Any
174
+ def sentry_create_connection(self: CacheHandler, alias: str) -> Any:
171
175
  cache = original_create_connection(self, alias)
172
176
 
173
177
  integration = sentry_sdk.get_client().get_integration(DjangoIntegration)
@@ -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
@@ -96,12 +93,10 @@ def _wrap_middleware(middleware, 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__(self, get_response=None, *args, **kwargs):
135
- # type: (Optional[Callable[..., Any]], *Any, **Any) -> None
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