sentry-sdk 2.39.0__tar.gz → 2.40.0__tar.gz

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 (204) hide show
  1. {sentry_sdk-2.39.0/sentry_sdk.egg-info → sentry_sdk-2.40.0}/PKG-INFO +3 -1
  2. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/pyproject.toml +45 -38
  3. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/client.py +6 -6
  4. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/consts.py +12 -2
  5. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/envelope.py +28 -14
  6. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/feature_flags.py +0 -1
  7. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/hub.py +17 -9
  8. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/__init__.py +1 -0
  9. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/asgi.py +3 -2
  10. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/dramatiq.py +89 -31
  11. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/grpc/aio/client.py +2 -1
  12. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/grpc/client.py +3 -4
  13. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/langchain.py +0 -1
  14. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/launchdarkly.py +0 -1
  15. sentry_sdk-2.40.0/sentry_sdk/integrations/litellm.py +251 -0
  16. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/litestar.py +4 -4
  17. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/spans/ai_client.py +4 -1
  18. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/utils.py +25 -1
  19. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/pure_eval.py +3 -1
  20. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/spark/spark_driver.py +2 -1
  21. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/sqlalchemy.py +2 -6
  22. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/starlette.py +1 -3
  23. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/starlite.py +4 -4
  24. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/wsgi.py +3 -2
  25. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/metrics.py +17 -11
  26. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/profiler/utils.py +2 -6
  27. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/scope.py +6 -3
  28. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/serializer.py +1 -3
  29. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/session.py +4 -2
  30. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/sessions.py +4 -2
  31. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/tracing.py +36 -7
  32. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/tracing_utils.py +1 -3
  33. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/transport.py +8 -9
  34. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/utils.py +5 -3
  35. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0/sentry_sdk.egg-info}/PKG-INFO +3 -1
  36. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk.egg-info/SOURCES.txt +1 -0
  37. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk.egg-info/requires.txt +3 -0
  38. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/setup.py +2 -1
  39. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_basics.py +3 -3
  40. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_client.py +4 -6
  41. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_conftest.py +6 -2
  42. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_gevent.py +2 -4
  43. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_logs.py +2 -1
  44. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_propagationcontext.py +1 -2
  45. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_transport.py +2 -4
  46. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_utils.py +3 -3
  47. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/LICENSE +0 -0
  48. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/MANIFEST.in +0 -0
  49. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/README.md +0 -0
  50. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/__init__.py +0 -0
  51. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/_compat.py +0 -0
  52. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/_init_implementation.py +0 -0
  53. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/_log_batcher.py +0 -0
  54. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/_lru_cache.py +0 -0
  55. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/_queue.py +0 -0
  56. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/_types.py +0 -0
  57. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/_werkzeug.py +0 -0
  58. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/ai/__init__.py +0 -0
  59. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/ai/monitoring.py +0 -0
  60. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/ai/utils.py +0 -0
  61. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/api.py +0 -0
  62. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/attachments.py +0 -0
  63. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/crons/__init__.py +0 -0
  64. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/crons/api.py +0 -0
  65. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/crons/consts.py +0 -0
  66. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/crons/decorator.py +0 -0
  67. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/debug.py +0 -0
  68. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/_asgi_common.py +0 -0
  69. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/_wsgi_common.py +0 -0
  70. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/aiohttp.py +0 -0
  71. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/anthropic.py +0 -0
  72. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/argv.py +0 -0
  73. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/ariadne.py +0 -0
  74. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/arq.py +0 -0
  75. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/asyncio.py +0 -0
  76. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/asyncpg.py +0 -0
  77. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/atexit.py +0 -0
  78. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/aws_lambda.py +0 -0
  79. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/beam.py +0 -0
  80. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/boto3.py +0 -0
  81. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/bottle.py +0 -0
  82. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/celery/__init__.py +0 -0
  83. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/celery/beat.py +0 -0
  84. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/celery/utils.py +0 -0
  85. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/chalice.py +0 -0
  86. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/clickhouse_driver.py +0 -0
  87. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/cloud_resource_context.py +0 -0
  88. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/cohere.py +0 -0
  89. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/dedupe.py +0 -0
  90. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/django/__init__.py +0 -0
  91. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/django/asgi.py +0 -0
  92. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/django/caching.py +0 -0
  93. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/django/middleware.py +0 -0
  94. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/django/signals_handlers.py +0 -0
  95. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/django/templates.py +0 -0
  96. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/django/transactions.py +0 -0
  97. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/django/views.py +0 -0
  98. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/excepthook.py +0 -0
  99. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/executing.py +0 -0
  100. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/falcon.py +0 -0
  101. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/fastapi.py +0 -0
  102. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/flask.py +0 -0
  103. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/gcp.py +0 -0
  104. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/gnu_backtrace.py +0 -0
  105. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/gql.py +0 -0
  106. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/graphene.py +0 -0
  107. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/grpc/__init__.py +0 -0
  108. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/grpc/aio/__init__.py +0 -0
  109. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/grpc/aio/server.py +0 -0
  110. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/grpc/consts.py +0 -0
  111. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/grpc/server.py +0 -0
  112. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/httpx.py +0 -0
  113. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/huey.py +0 -0
  114. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/huggingface_hub.py +0 -0
  115. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/langgraph.py +0 -0
  116. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/logging.py +0 -0
  117. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/loguru.py +0 -0
  118. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/modules.py +0 -0
  119. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai.py +0 -0
  120. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/__init__.py +0 -0
  121. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/consts.py +0 -0
  122. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/patches/__init__.py +0 -0
  123. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/patches/agent_run.py +0 -0
  124. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/patches/models.py +0 -0
  125. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/patches/runner.py +0 -0
  126. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/patches/tools.py +0 -0
  127. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/spans/__init__.py +0 -0
  128. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/spans/agent_workflow.py +0 -0
  129. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/spans/execute_tool.py +0 -0
  130. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/spans/handoff.py +0 -0
  131. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +0 -0
  132. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openfeature.py +0 -0
  133. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/opentelemetry/__init__.py +0 -0
  134. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/opentelemetry/consts.py +0 -0
  135. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/opentelemetry/integration.py +0 -0
  136. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/opentelemetry/propagator.py +0 -0
  137. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/opentelemetry/span_processor.py +0 -0
  138. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/pymongo.py +0 -0
  139. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/pyramid.py +0 -0
  140. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/quart.py +0 -0
  141. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/ray.py +0 -0
  142. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/__init__.py +0 -0
  143. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/_async_common.py +0 -0
  144. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/_sync_common.py +0 -0
  145. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/consts.py +0 -0
  146. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/modules/__init__.py +0 -0
  147. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/modules/caches.py +0 -0
  148. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/modules/queries.py +0 -0
  149. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/rb.py +0 -0
  150. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/redis.py +0 -0
  151. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/redis_cluster.py +0 -0
  152. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +0 -0
  153. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/utils.py +0 -0
  154. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/rq.py +0 -0
  155. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/rust_tracing.py +0 -0
  156. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/sanic.py +0 -0
  157. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/serverless.py +0 -0
  158. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/socket.py +0 -0
  159. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/spark/__init__.py +0 -0
  160. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/spark/spark_worker.py +0 -0
  161. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/statsig.py +0 -0
  162. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/stdlib.py +0 -0
  163. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/strawberry.py +0 -0
  164. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/sys_exit.py +0 -0
  165. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/threading.py +0 -0
  166. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/tornado.py +0 -0
  167. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/trytond.py +0 -0
  168. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/typer.py +0 -0
  169. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/unleash.py +0 -0
  170. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/unraisablehook.py +0 -0
  171. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/logger.py +0 -0
  172. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/monitor.py +0 -0
  173. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/profiler/__init__.py +0 -0
  174. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/profiler/continuous_profiler.py +0 -0
  175. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/profiler/transaction_profiler.py +0 -0
  176. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/py.typed +0 -0
  177. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/scrubber.py +0 -0
  178. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/spotlight.py +0 -0
  179. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/types.py +0 -0
  180. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/worker.py +0 -0
  181. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk.egg-info/dependency_links.txt +0 -0
  182. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk.egg-info/entry_points.txt +0 -0
  183. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk.egg-info/not-zip-safe +0 -0
  184. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk.egg-info/top_level.txt +0 -0
  185. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/setup.cfg +0 -0
  186. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_ai_monitoring.py +0 -0
  187. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_api.py +0 -0
  188. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_crons.py +0 -0
  189. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_dsc.py +0 -0
  190. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_envelope.py +0 -0
  191. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_exceptiongroup.py +0 -0
  192. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_feature_flags.py +0 -0
  193. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_full_stack_frames.py +0 -0
  194. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_import.py +0 -0
  195. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_lru_cache.py +0 -0
  196. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_metrics.py +0 -0
  197. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_monitor.py +0 -0
  198. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_scope.py +0 -0
  199. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_scrubber.py +0 -0
  200. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_serializer.py +0 -0
  201. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_sessions.py +0 -0
  202. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_spotlight.py +0 -0
  203. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_tracing_utils.py +0 -0
  204. {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry-sdk
3
- Version: 2.39.0
3
+ Version: 2.40.0
4
4
  Summary: Python client for Sentry (https://sentry.io)
5
5
  Home-page: https://github.com/getsentry/sentry-python
6
6
  Author: Sentry Team and Contributors
@@ -76,6 +76,8 @@ Provides-Extra: langgraph
76
76
  Requires-Dist: langgraph>=0.6.6; extra == "langgraph"
77
77
  Provides-Extra: launchdarkly
78
78
  Requires-Dist: launchdarkly-server-sdk>=9.8.0; extra == "launchdarkly"
79
+ Provides-Extra: litellm
80
+ Requires-Dist: litellm>=1.77.5; extra == "litellm"
79
81
  Provides-Extra: litestar
80
82
  Requires-Dist: litestar>=2.0.0; extra == "litestar"
81
83
  Provides-Extra: loguru
@@ -1,19 +1,3 @@
1
- #
2
- # Tool: Black
3
- #
4
-
5
- [tool.black]
6
- # 'extend-exclude' excludes files or directories in addition to the defaults
7
- extend-exclude = '''
8
- # A regex preceded with ^/ will apply only to files and directories
9
- # in the root of the project.
10
- (
11
- .*_pb2.py # exclude autogenerated Protocol Buffer files anywhere in the project
12
- | .*_pb2_grpc.py # exclude autogenerated Protocol Buffer files anywhere in the project
13
- )
14
- '''
15
-
16
-
17
1
  #
18
2
  # Tool: Coverage
19
3
  #
@@ -195,30 +179,53 @@ ignore_missing_imports = true
195
179
  module = "agents.*"
196
180
  ignore_missing_imports = true
197
181
 
182
+ [[tool.mypy.overrides]]
183
+ module = "dramatiq.*"
184
+ ignore_missing_imports = true
185
+
198
186
  #
199
- # Tool: Flake8
187
+ # Tool: Ruff (linting and formatting)
200
188
  #
201
189
 
202
- [tool.flake8]
203
- extend-ignore = [
204
- # Handled by black (Whitespace before ':' -- handled by black)
205
- "E203",
206
- # Handled by black (Line too long)
207
- "E501",
208
- # Sometimes not possible due to execution order (Module level import is not at top of file)
209
- "E402",
210
- # I don't care (Do not assign a lambda expression, use a def)
211
- "E731",
212
- # does not apply to Python 2 (redundant exception types by flake8-bugbear)
213
- "B014",
214
- # I don't care (Lowercase imported as non-lowercase by pep8-naming)
215
- "N812",
216
- # is a worse version of and conflicts with B902 (first argument of a classmethod should be named cls)
217
- "N804",
190
+ [tool.ruff]
191
+ # Target Python 3.7+ (minimum version supported by ruff)
192
+ target-version = "py37"
193
+
194
+ # Exclude files and directories
195
+ extend-exclude = [
196
+ "*_pb2.py", # Protocol Buffer files (covers all pb2 files including grpc_test_service_pb2.py)
197
+ "*_pb2_grpc.py", # Protocol Buffer files (covers all pb2_grpc files including grpc_test_service_pb2_grpc.py)
198
+ "checkouts", # From flake8
199
+ "lol*", # From flake8
200
+ ]
201
+
202
+ [tool.ruff.lint]
203
+ # Match flake8's default rule selection exactly
204
+ # Flake8 by default only enables E and W (pycodestyle) + F (pyflakes)
205
+ select = [
206
+ "E", # pycodestyle errors (same as flake8 default)
207
+ "W", # pycodestyle warnings (same as flake8 default)
208
+ "F", # Pyflakes (same as flake8 default)
209
+ # Note: B and N rules are NOT enabled by default in flake8
210
+ # They were only active through the plugins, which may not have been fully enabled
218
211
  ]
219
- extend-exclude = ["checkouts", "lol*"]
220
- exclude = [
221
- # gRCP generated files
222
- "grpc_test_service_pb2.py",
223
- "grpc_test_service_pb2_grpc.py",
212
+
213
+ # Use ONLY the same ignores as the original flake8 config + compatibility for this codebase
214
+ ignore = [
215
+ "E203", # Whitespace before ':'
216
+ "E501", # Line too long
217
+ "E402", # Module level import not at top of file
218
+ "E731", # Do not assign a lambda expression, use a def
219
+ "B014", # Redundant exception types
220
+ "N812", # Lowercase imported as non-lowercase
221
+ "N804", # First argument of classmethod should be named cls
222
+
223
+ # Additional ignores for codebase compatibility
224
+ "F401", # Unused imports - many in TYPE_CHECKING blocks used for type comments
225
+ "E721", # Use isinstance instead of type() == - existing pattern in this codebase
224
226
  ]
227
+
228
+ [tool.ruff.format]
229
+ # ruff format already excludes the same files as specified in extend-exclude
230
+ # Ensure Python 3.7 compatibility - avoid using Python 3.9+ syntax features
231
+ skip-magic-trailing-comma = false
@@ -178,9 +178,7 @@ class BaseClient:
178
178
 
179
179
  def __init__(self, options=None):
180
180
  # type: (Optional[Dict[str, Any]]) -> None
181
- self.options = (
182
- options if options is not None else DEFAULT_OPTIONS
183
- ) # type: Dict[str, Any]
181
+ self.options = options if options is not None else DEFAULT_OPTIONS # type: Dict[str, Any]
184
182
 
185
183
  self.transport = None # type: Optional[Transport]
186
184
  self.monitor = None # type: Optional[Monitor]
@@ -956,7 +954,7 @@ class _Client(BaseClient):
956
954
  debug = self.options.get("debug", False)
957
955
  if debug:
958
956
  logger.debug(
959
- f'[Sentry Logs] [{log.get("severity_text")}] {log.get("body")}'
957
+ f"[Sentry Logs] [{log.get('severity_text')}] {log.get('body')}"
960
958
  )
961
959
 
962
960
  before_send_log = get_before_send_log(self.options)
@@ -970,7 +968,8 @@ class _Client(BaseClient):
970
968
  self.log_batcher.add(log)
971
969
 
972
970
  def capture_session(
973
- self, session # type: Session
971
+ self,
972
+ session, # type: Session
974
973
  ):
975
974
  # type: (...) -> None
976
975
  if not session.release:
@@ -991,7 +990,8 @@ class _Client(BaseClient):
991
990
  ...
992
991
 
993
992
  def get_integration(
994
- self, name_or_class # type: Union[str, Type[Integration]]
993
+ self,
994
+ name_or_class, # type: Union[str, Type[Integration]]
995
995
  ):
996
996
  # type: (...) -> Optional[Integration]
997
997
  """Returns the integration for this client by name or class.
@@ -40,6 +40,7 @@ if TYPE_CHECKING:
40
40
  from typing import Any
41
41
  from typing import Sequence
42
42
  from typing import Tuple
43
+ from typing import AbstractSet
43
44
  from typing_extensions import Literal
44
45
  from typing_extensions import TypedDict
45
46
 
@@ -838,6 +839,7 @@ class OP:
838
839
  QUEUE_TASK_HUEY = "queue.task.huey"
839
840
  QUEUE_SUBMIT_RAY = "queue.submit.ray"
840
841
  QUEUE_TASK_RAY = "queue.task.ray"
842
+ QUEUE_TASK_DRAMATIQ = "queue.task.dramatiq"
841
843
  SUBPROCESS = "subprocess"
842
844
  SUBPROCESS_WAIT = "subprocess.wait"
843
845
  SUBPROCESS_COMMUNICATE = "subprocess.communicate"
@@ -852,7 +854,6 @@ class OP:
852
854
  # This type exists to trick mypy and PyCharm into thinking `init` and `Client`
853
855
  # take these arguments (even though they take opaque **kwargs)
854
856
  class ClientConstructor:
855
-
856
857
  def __init__(
857
858
  self,
858
859
  dsn=None, # type: Optional[str]
@@ -920,6 +921,7 @@ class ClientConstructor:
920
921
  max_stack_frames=DEFAULT_MAX_STACK_FRAMES, # type: Optional[int]
921
922
  enable_logs=False, # type: bool
922
923
  before_send_log=None, # type: Optional[Callable[[Log, Hint], Optional[Log]]]
924
+ trace_ignore_status_codes=frozenset(), # type: AbstractSet[int]
923
925
  ):
924
926
  # type: (...) -> None
925
927
  """Initialize the Sentry SDK with the given parameters. All parameters described here can be used in a call to `sentry_sdk.init()`.
@@ -1308,6 +1310,14 @@ class ClientConstructor:
1308
1310
  function will be retained. If the function returns None, the log will
1309
1311
  not be sent to Sentry.
1310
1312
 
1313
+ :param trace_ignore_status_codes: An optional property that disables tracing for
1314
+ HTTP requests with certain status codes.
1315
+
1316
+ Requests are not traced if the status code is contained in the provided set.
1317
+
1318
+ If `trace_ignore_status_codes` is not provided, requests with any status code
1319
+ may be traced.
1320
+
1311
1321
  :param _experiments:
1312
1322
  """
1313
1323
  pass
@@ -1333,4 +1343,4 @@ DEFAULT_OPTIONS = _get_default_options()
1333
1343
  del _get_default_options
1334
1344
 
1335
1345
 
1336
- VERSION = "2.39.0"
1346
+ VERSION = "2.40.0"
@@ -57,25 +57,29 @@ class Envelope:
57
57
  )
58
58
 
59
59
  def add_event(
60
- self, event # type: Event
60
+ self,
61
+ event, # type: Event
61
62
  ):
62
63
  # type: (...) -> None
63
64
  self.add_item(Item(payload=PayloadRef(json=event), type="event"))
64
65
 
65
66
  def add_transaction(
66
- self, transaction # type: Event
67
+ self,
68
+ transaction, # type: Event
67
69
  ):
68
70
  # type: (...) -> None
69
71
  self.add_item(Item(payload=PayloadRef(json=transaction), type="transaction"))
70
72
 
71
73
  def add_profile(
72
- self, profile # type: Any
74
+ self,
75
+ profile, # type: Any
73
76
  ):
74
77
  # type: (...) -> None
75
78
  self.add_item(Item(payload=PayloadRef(json=profile), type="profile"))
76
79
 
77
80
  def add_profile_chunk(
78
- self, profile_chunk # type: Any
81
+ self,
82
+ profile_chunk, # type: Any
79
83
  ):
80
84
  # type: (...) -> None
81
85
  self.add_item(
@@ -87,13 +91,15 @@ class Envelope:
87
91
  )
88
92
 
89
93
  def add_checkin(
90
- self, checkin # type: Any
94
+ self,
95
+ checkin, # type: Any
91
96
  ):
92
97
  # type: (...) -> None
93
98
  self.add_item(Item(payload=PayloadRef(json=checkin), type="check_in"))
94
99
 
95
100
  def add_session(
96
- self, session # type: Union[Session, Any]
101
+ self,
102
+ session, # type: Union[Session, Any]
97
103
  ):
98
104
  # type: (...) -> None
99
105
  if isinstance(session, Session):
@@ -101,13 +107,15 @@ class Envelope:
101
107
  self.add_item(Item(payload=PayloadRef(json=session), type="session"))
102
108
 
103
109
  def add_sessions(
104
- self, sessions # type: Any
110
+ self,
111
+ sessions, # type: Any
105
112
  ):
106
113
  # type: (...) -> None
107
114
  self.add_item(Item(payload=PayloadRef(json=sessions), type="sessions"))
108
115
 
109
116
  def add_item(
110
- self, item # type: Item
117
+ self,
118
+ item, # type: Item
111
119
  ):
112
120
  # type: (...) -> None
113
121
  self.items.append(item)
@@ -133,7 +141,8 @@ class Envelope:
133
141
  return iter(self.items)
134
142
 
135
143
  def serialize_into(
136
- self, f # type: Any
144
+ self,
145
+ f, # type: Any
137
146
  ):
138
147
  # type: (...) -> None
139
148
  f.write(json_dumps(self.headers))
@@ -149,7 +158,8 @@ class Envelope:
149
158
 
150
159
  @classmethod
151
160
  def deserialize_from(
152
- cls, f # type: Any
161
+ cls,
162
+ f, # type: Any
153
163
  ):
154
164
  # type: (...) -> Envelope
155
165
  headers = parse_json(f.readline())
@@ -163,7 +173,8 @@ class Envelope:
163
173
 
164
174
  @classmethod
165
175
  def deserialize(
166
- cls, bytes # type: bytes
176
+ cls,
177
+ bytes, # type: bytes
167
178
  ):
168
179
  # type: (...) -> Envelope
169
180
  return cls.deserialize_from(io.BytesIO(bytes))
@@ -307,7 +318,8 @@ class Item:
307
318
  return None
308
319
 
309
320
  def serialize_into(
310
- self, f # type: Any
321
+ self,
322
+ f, # type: Any
311
323
  ):
312
324
  # type: (...) -> None
313
325
  headers = dict(self.headers)
@@ -326,7 +338,8 @@ class Item:
326
338
 
327
339
  @classmethod
328
340
  def deserialize_from(
329
- cls, f # type: Any
341
+ cls,
342
+ f, # type: Any
330
343
  ):
331
344
  # type: (...) -> Optional[Item]
332
345
  line = f.readline().rstrip()
@@ -349,7 +362,8 @@ class Item:
349
362
 
350
363
  @classmethod
351
364
  def deserialize(
352
- cls, bytes # type: bytes
365
+ cls,
366
+ bytes, # type: bytes
353
367
  ):
354
368
  # type: (...) -> Optional[Item]
355
369
  return cls.deserialize_from(io.BytesIO(bytes))
@@ -15,7 +15,6 @@ DEFAULT_FLAG_CAPACITY = 100
15
15
 
16
16
 
17
17
  class FlagBuffer:
18
-
19
18
  def __init__(self, capacity):
20
19
  # type: (int) -> None
21
20
  self.capacity = capacity
@@ -205,7 +205,8 @@ class Hub(with_metaclass(HubMeta)): # type: ignore
205
205
  scope._isolation_scope.set(old_isolation_scope)
206
206
 
207
207
  def run(
208
- self, callback # type: Callable[[], T]
208
+ self,
209
+ callback, # type: Callable[[], T]
209
210
  ):
210
211
  # type: (...) -> T
211
212
  """
@@ -219,7 +220,8 @@ class Hub(with_metaclass(HubMeta)): # type: ignore
219
220
  return callback()
220
221
 
221
222
  def get_integration(
222
- self, name_or_class # type: Union[str, Type[Integration]]
223
+ self,
224
+ name_or_class, # type: Union[str, Type[Integration]]
223
225
  ):
224
226
  # type: (...) -> Any
225
227
  """
@@ -277,7 +279,8 @@ class Hub(with_metaclass(HubMeta)): # type: ignore
277
279
  return self._last_event_id
278
280
 
279
281
  def bind_client(
280
- self, new # type: Optional[BaseClient]
282
+ self,
283
+ new, # type: Optional[BaseClient]
281
284
  ):
282
285
  # type: (...) -> None
283
286
  """
@@ -430,7 +433,7 @@ class Hub(with_metaclass(HubMeta)): # type: ignore
430
433
  transaction=None,
431
434
  instrumenter=INSTRUMENTER.SENTRY,
432
435
  custom_sampling_context=None,
433
- **kwargs
436
+ **kwargs,
434
437
  ):
435
438
  # type: (Optional[Transaction], str, Optional[SamplingContext], Unpack[TransactionKwargs]) -> Union[Transaction, NoOpSpan]
436
439
  """
@@ -487,14 +490,16 @@ class Hub(with_metaclass(HubMeta)): # type: ignore
487
490
 
488
491
  @overload
489
492
  def push_scope(
490
- self, callback=None # type: Optional[None]
493
+ self,
494
+ callback=None, # type: Optional[None]
491
495
  ):
492
496
  # type: (...) -> ContextManager[Scope]
493
497
  pass
494
498
 
495
499
  @overload
496
500
  def push_scope( # noqa: F811
497
- self, callback # type: Callable[[Scope], None]
501
+ self,
502
+ callback, # type: Callable[[Scope], None]
498
503
  ):
499
504
  # type: (...) -> None
500
505
  pass
@@ -540,14 +545,16 @@ class Hub(with_metaclass(HubMeta)): # type: ignore
540
545
 
541
546
  @overload
542
547
  def configure_scope(
543
- self, callback=None # type: Optional[None]
548
+ self,
549
+ callback=None, # type: Optional[None]
544
550
  ):
545
551
  # type: (...) -> ContextManager[Scope]
546
552
  pass
547
553
 
548
554
  @overload
549
555
  def configure_scope( # noqa: F811
550
- self, callback # type: Callable[[Scope], None]
556
+ self,
557
+ callback, # type: Callable[[Scope], None]
551
558
  ):
552
559
  # type: (...) -> None
553
560
  pass
@@ -587,7 +594,8 @@ class Hub(with_metaclass(HubMeta)): # type: ignore
587
594
  return inner()
588
595
 
589
596
  def start_session(
590
- self, session_mode="application" # type: str
597
+ self,
598
+ session_mode="application", # type: str
591
599
  ):
592
600
  # type: (...) -> None
593
601
  """
@@ -146,6 +146,7 @@ _MIN_VERSIONS = {
146
146
  "langchain": (0, 1, 0),
147
147
  "langgraph": (0, 6, 6),
148
148
  "launchdarkly": (9, 8, 0),
149
+ "litellm": (1, 77, 5),
149
150
  "loguru": (0, 7, 0),
150
151
  "openai": (1, 0, 0),
151
152
  "openai_agents": (0, 0, 19),
@@ -233,14 +233,15 @@ class SentryAsgiMiddleware:
233
233
  if transaction:
234
234
  transaction.set_tag("asgi.type", ty)
235
235
 
236
- with (
236
+ transaction_context = (
237
237
  sentry_sdk.start_transaction(
238
238
  transaction,
239
239
  custom_sampling_context={"asgi_scope": scope},
240
240
  )
241
241
  if transaction is not None
242
242
  else nullcontext()
243
- ):
243
+ )
244
+ with transaction_context:
244
245
  try:
245
246
 
246
247
  async def _sentry_wrapped_send(event):
@@ -1,18 +1,31 @@
1
1
  import json
2
2
 
3
3
  import sentry_sdk
4
- from sentry_sdk.integrations import Integration
4
+ from sentry_sdk.consts import OP, SPANSTATUS
5
+ from sentry_sdk.api import continue_trace, get_baggage, get_traceparent
6
+ from sentry_sdk.integrations import Integration, DidNotEnable
5
7
  from sentry_sdk.integrations._wsgi_common import request_body_within_bounds
8
+ from sentry_sdk.tracing import (
9
+ BAGGAGE_HEADER_NAME,
10
+ SENTRY_TRACE_HEADER_NAME,
11
+ TransactionSource,
12
+ )
6
13
  from sentry_sdk.utils import (
7
14
  AnnotatedValue,
8
15
  capture_internal_exceptions,
9
16
  event_from_exception,
10
17
  )
18
+ from typing import TypeVar
19
+
20
+ R = TypeVar("R")
11
21
 
12
- from dramatiq.broker import Broker # type: ignore
13
- from dramatiq.message import Message # type: ignore
14
- from dramatiq.middleware import Middleware, default_middleware # type: ignore
15
- from dramatiq.errors import Retry # type: ignore
22
+ try:
23
+ from dramatiq.broker import Broker
24
+ from dramatiq.middleware import Middleware, default_middleware
25
+ from dramatiq.errors import Retry
26
+ from dramatiq.message import Message
27
+ except ImportError:
28
+ raise DidNotEnable("Dramatiq is not installed")
16
29
 
17
30
  from typing import TYPE_CHECKING
18
31
 
@@ -34,10 +47,12 @@ class DramatiqIntegration(Integration):
34
47
  """
35
48
 
36
49
  identifier = "dramatiq"
50
+ origin = f"auto.queue.{identifier}"
37
51
 
38
52
  @staticmethod
39
53
  def setup_once():
40
54
  # type: () -> None
55
+
41
56
  _patch_dramatiq_broker()
42
57
 
43
58
 
@@ -85,22 +100,54 @@ class SentryMiddleware(Middleware): # type: ignore[misc]
85
100
  DramatiqIntegration.
86
101
  """
87
102
 
88
- def before_process_message(self, broker, message):
89
- # type: (Broker, Message) -> None
103
+ SENTRY_HEADERS_NAME = "_sentry_headers"
104
+
105
+ def before_enqueue(self, broker, message, delay):
106
+ # type: (Broker, Message[R], int) -> None
90
107
  integration = sentry_sdk.get_client().get_integration(DramatiqIntegration)
91
108
  if integration is None:
92
109
  return
93
110
 
94
- message._scope_manager = sentry_sdk.new_scope()
95
- message._scope_manager.__enter__()
111
+ message.options[self.SENTRY_HEADERS_NAME] = {
112
+ BAGGAGE_HEADER_NAME: get_baggage(),
113
+ SENTRY_TRACE_HEADER_NAME: get_traceparent(),
114
+ }
115
+
116
+ def before_process_message(self, broker, message):
117
+ # type: (Broker, Message[R]) -> None
118
+ integration = sentry_sdk.get_client().get_integration(DramatiqIntegration)
119
+ if integration is None:
120
+ return
96
121
 
97
- scope = sentry_sdk.get_current_scope()
98
- scope.set_transaction_name(message.actor_name)
122
+ message._scope_manager = sentry_sdk.isolation_scope()
123
+ scope = message._scope_manager.__enter__()
124
+ scope.clear_breadcrumbs()
99
125
  scope.set_extra("dramatiq_message_id", message.message_id)
100
126
  scope.add_event_processor(_make_message_event_processor(message, integration))
101
127
 
128
+ sentry_headers = message.options.get(self.SENTRY_HEADERS_NAME) or {}
129
+ if "retries" in message.options:
130
+ # start new trace in case of retrying
131
+ sentry_headers = {}
132
+
133
+ transaction = continue_trace(
134
+ sentry_headers,
135
+ name=message.actor_name,
136
+ op=OP.QUEUE_TASK_DRAMATIQ,
137
+ source=TransactionSource.TASK,
138
+ origin=DramatiqIntegration.origin,
139
+ )
140
+ transaction.set_status(SPANSTATUS.OK)
141
+ sentry_sdk.start_transaction(
142
+ transaction,
143
+ name=message.actor_name,
144
+ op=OP.QUEUE_TASK_DRAMATIQ,
145
+ source=TransactionSource.TASK,
146
+ )
147
+ transaction.__enter__()
148
+
102
149
  def after_process_message(self, broker, message, *, result=None, exception=None):
103
- # type: (Broker, Message, Any, Optional[Any], Optional[Exception]) -> None
150
+ # type: (Broker, Message[R], Optional[Any], Optional[Exception]) -> None
104
151
  integration = sentry_sdk.get_client().get_integration(DramatiqIntegration)
105
152
  if integration is None:
106
153
  return
@@ -108,27 +155,38 @@ class SentryMiddleware(Middleware): # type: ignore[misc]
108
155
  actor = broker.get_actor(message.actor_name)
109
156
  throws = message.options.get("throws") or actor.options.get("throws")
110
157
 
111
- try:
112
- if (
113
- exception is not None
114
- and not (throws and isinstance(exception, throws))
115
- and not isinstance(exception, Retry)
116
- ):
117
- event, hint = event_from_exception(
118
- exception,
119
- client_options=sentry_sdk.get_client().options,
120
- mechanism={
121
- "type": DramatiqIntegration.identifier,
122
- "handled": False,
123
- },
124
- )
125
- sentry_sdk.capture_event(event, hint=hint)
126
- finally:
127
- message._scope_manager.__exit__(None, None, None)
158
+ scope_manager = message._scope_manager
159
+ transaction = sentry_sdk.get_current_scope().transaction
160
+ if not transaction:
161
+ return None
162
+
163
+ is_event_capture_required = (
164
+ exception is not None
165
+ and not (throws and isinstance(exception, throws))
166
+ and not isinstance(exception, Retry)
167
+ )
168
+ if not is_event_capture_required:
169
+ # normal transaction finish
170
+ transaction.__exit__(None, None, None)
171
+ scope_manager.__exit__(None, None, None)
172
+ return
173
+
174
+ event, hint = event_from_exception(
175
+ exception, # type: ignore[arg-type]
176
+ client_options=sentry_sdk.get_client().options,
177
+ mechanism={
178
+ "type": DramatiqIntegration.identifier,
179
+ "handled": False,
180
+ },
181
+ )
182
+ sentry_sdk.capture_event(event, hint=hint)
183
+ # transaction error
184
+ transaction.__exit__(type(exception), exception, None)
185
+ scope_manager.__exit__(type(exception), exception, None)
128
186
 
129
187
 
130
188
  def _make_message_event_processor(message, integration):
131
- # type: (Message, DramatiqIntegration) -> Callable[[Event, Hint], Optional[Event]]
189
+ # type: (Message[R], DramatiqIntegration) -> Callable[[Event, Hint], Optional[Event]]
132
190
 
133
191
  def inner(event, hint):
134
192
  # type: (Event, Hint) -> Optional[Event]
@@ -142,7 +200,7 @@ def _make_message_event_processor(message, integration):
142
200
 
143
201
  class DramatiqMessageExtractor:
144
202
  def __init__(self, message):
145
- # type: (Message) -> None
203
+ # type: (Message[R]) -> None
146
204
  self.message_data = dict(message.asdict())
147
205
 
148
206
  def content_length(self):
@@ -65,7 +65,8 @@ class SentryUnaryUnaryClientInterceptor(ClientInterceptor, UnaryUnaryClientInter
65
65
 
66
66
 
67
67
  class SentryUnaryStreamClientInterceptor(
68
- ClientInterceptor, UnaryStreamClientInterceptor # type: ignore
68
+ ClientInterceptor,
69
+ UnaryStreamClientInterceptor, # type: ignore
69
70
  ):
70
71
  async def intercept_unary_stream(
71
72
  self,
@@ -19,7 +19,8 @@ except ImportError:
19
19
 
20
20
 
21
21
  class ClientInterceptor(
22
- grpc.UnaryUnaryClientInterceptor, grpc.UnaryStreamClientInterceptor # type: ignore
22
+ grpc.UnaryUnaryClientInterceptor, # type: ignore
23
+ grpc.UnaryStreamClientInterceptor, # type: ignore
23
24
  ):
24
25
  _is_intercepted = False
25
26
 
@@ -60,9 +61,7 @@ class ClientInterceptor(
60
61
  client_call_details
61
62
  )
62
63
 
63
- response = continuation(
64
- client_call_details, request
65
- ) # type: UnaryStreamCall
64
+ response = continuation(client_call_details, request) # type: UnaryStreamCall
66
65
  # Setting code on unary-stream leads to execution getting stuck
67
66
  # span.set_data("code", response.code().name)
68
67
 
@@ -554,7 +554,6 @@ def _simplify_langchain_tools(tools):
554
554
  for tool in tools:
555
555
  try:
556
556
  if isinstance(tool, dict):
557
-
558
557
  if "function" in tool and isinstance(tool["function"], dict):
559
558
  func = tool["function"]
560
559
  simplified_tool = {