sentry-sdk 2.39.0__tar.gz → 2.41.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 (208) hide show
  1. {sentry_sdk-2.39.0/sentry_sdk.egg-info → sentry_sdk-2.41.0}/PKG-INFO +3 -1
  2. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/pyproject.toml +45 -38
  3. sentry_sdk-2.41.0/sentry_sdk/_metrics.py +81 -0
  4. sentry_sdk-2.41.0/sentry_sdk/_metrics_batcher.py +156 -0
  5. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/_types.py +27 -22
  6. sentry_sdk-2.41.0/sentry_sdk/ai/__init__.py +7 -0
  7. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/ai/utils.py +48 -0
  8. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/client.py +87 -36
  9. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/consts.py +15 -9
  10. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/envelope.py +31 -17
  11. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/feature_flags.py +0 -1
  12. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/hub.py +17 -9
  13. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/__init__.py +1 -0
  14. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/anthropic.py +10 -2
  15. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/asgi.py +3 -2
  16. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/dramatiq.py +89 -31
  17. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/grpc/aio/client.py +2 -1
  18. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/grpc/client.py +3 -4
  19. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/langchain.py +29 -5
  20. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/langgraph.py +5 -3
  21. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/launchdarkly.py +0 -1
  22. sentry_sdk-2.41.0/sentry_sdk/integrations/litellm.py +251 -0
  23. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/litestar.py +4 -4
  24. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/logging.py +1 -1
  25. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/loguru.py +1 -1
  26. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/openai.py +3 -2
  27. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/openai_agents/spans/ai_client.py +4 -1
  28. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +10 -2
  29. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/openai_agents/utils.py +60 -19
  30. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/pure_eval.py +3 -1
  31. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/spark/spark_driver.py +2 -1
  32. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/sqlalchemy.py +2 -6
  33. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/starlette.py +1 -3
  34. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/starlite.py +4 -4
  35. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/threading.py +52 -8
  36. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/wsgi.py +3 -2
  37. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/logger.py +1 -1
  38. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/profiler/utils.py +2 -6
  39. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/scope.py +6 -3
  40. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/serializer.py +1 -3
  41. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/session.py +4 -2
  42. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/sessions.py +4 -2
  43. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/tracing.py +36 -33
  44. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/tracing_utils.py +1 -3
  45. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/transport.py +9 -26
  46. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/types.py +3 -0
  47. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/utils.py +22 -4
  48. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0/sentry_sdk.egg-info}/PKG-INFO +3 -1
  49. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk.egg-info/SOURCES.txt +3 -1
  50. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk.egg-info/requires.txt +3 -0
  51. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/setup.py +2 -1
  52. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_basics.py +3 -3
  53. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_client.py +4 -6
  54. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_conftest.py +6 -2
  55. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_envelope.py +0 -1
  56. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_gevent.py +2 -4
  57. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_logs.py +2 -1
  58. sentry_sdk-2.41.0/tests/test_metrics.py +208 -0
  59. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_propagationcontext.py +1 -2
  60. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_transport.py +2 -115
  61. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_utils.py +3 -3
  62. sentry_sdk-2.39.0/sentry_sdk/integrations/redis/modules/__init__.py +0 -0
  63. sentry_sdk-2.39.0/sentry_sdk/metrics.py +0 -965
  64. sentry_sdk-2.39.0/tests/test_metrics.py +0 -971
  65. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/LICENSE +0 -0
  66. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/MANIFEST.in +0 -0
  67. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/README.md +0 -0
  68. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/__init__.py +0 -0
  69. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/_compat.py +0 -0
  70. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/_init_implementation.py +0 -0
  71. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/_log_batcher.py +0 -0
  72. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/_lru_cache.py +0 -0
  73. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/_queue.py +0 -0
  74. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/_werkzeug.py +0 -0
  75. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/ai/monitoring.py +0 -0
  76. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/api.py +0 -0
  77. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/attachments.py +0 -0
  78. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/crons/__init__.py +0 -0
  79. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/crons/api.py +0 -0
  80. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/crons/consts.py +0 -0
  81. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/crons/decorator.py +0 -0
  82. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/debug.py +0 -0
  83. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/_asgi_common.py +0 -0
  84. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/_wsgi_common.py +0 -0
  85. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/aiohttp.py +0 -0
  86. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/argv.py +0 -0
  87. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/ariadne.py +0 -0
  88. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/arq.py +0 -0
  89. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/asyncio.py +0 -0
  90. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/asyncpg.py +0 -0
  91. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/atexit.py +0 -0
  92. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/aws_lambda.py +0 -0
  93. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/beam.py +0 -0
  94. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/boto3.py +0 -0
  95. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/bottle.py +0 -0
  96. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/celery/__init__.py +0 -0
  97. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/celery/beat.py +0 -0
  98. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/celery/utils.py +0 -0
  99. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/chalice.py +0 -0
  100. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/clickhouse_driver.py +0 -0
  101. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/cloud_resource_context.py +0 -0
  102. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/cohere.py +0 -0
  103. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/dedupe.py +0 -0
  104. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/django/__init__.py +0 -0
  105. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/django/asgi.py +0 -0
  106. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/django/caching.py +0 -0
  107. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/django/middleware.py +0 -0
  108. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/django/signals_handlers.py +0 -0
  109. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/django/templates.py +0 -0
  110. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/django/transactions.py +0 -0
  111. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/django/views.py +0 -0
  112. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/excepthook.py +0 -0
  113. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/executing.py +0 -0
  114. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/falcon.py +0 -0
  115. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/fastapi.py +0 -0
  116. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/flask.py +0 -0
  117. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/gcp.py +0 -0
  118. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/gnu_backtrace.py +0 -0
  119. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/gql.py +0 -0
  120. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/graphene.py +0 -0
  121. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/grpc/__init__.py +0 -0
  122. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/grpc/aio/__init__.py +0 -0
  123. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/grpc/aio/server.py +0 -0
  124. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/grpc/consts.py +0 -0
  125. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/grpc/server.py +0 -0
  126. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/httpx.py +0 -0
  127. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/huey.py +0 -0
  128. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/huggingface_hub.py +0 -0
  129. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/modules.py +0 -0
  130. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/openai_agents/__init__.py +0 -0
  131. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/openai_agents/consts.py +0 -0
  132. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/openai_agents/patches/__init__.py +0 -0
  133. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/openai_agents/patches/agent_run.py +0 -0
  134. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/openai_agents/patches/models.py +0 -0
  135. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/openai_agents/patches/runner.py +0 -0
  136. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/openai_agents/patches/tools.py +0 -0
  137. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/openai_agents/spans/__init__.py +0 -0
  138. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/openai_agents/spans/agent_workflow.py +0 -0
  139. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/openai_agents/spans/execute_tool.py +0 -0
  140. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/openai_agents/spans/handoff.py +0 -0
  141. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/openfeature.py +0 -0
  142. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/opentelemetry/__init__.py +0 -0
  143. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/opentelemetry/consts.py +0 -0
  144. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/opentelemetry/integration.py +0 -0
  145. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/opentelemetry/propagator.py +0 -0
  146. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/opentelemetry/span_processor.py +0 -0
  147. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/pymongo.py +0 -0
  148. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/pyramid.py +0 -0
  149. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/quart.py +0 -0
  150. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/ray.py +0 -0
  151. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/redis/__init__.py +0 -0
  152. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/redis/_async_common.py +0 -0
  153. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/redis/_sync_common.py +0 -0
  154. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/redis/consts.py +0 -0
  155. {sentry_sdk-2.39.0/sentry_sdk/ai → sentry_sdk-2.41.0/sentry_sdk/integrations/redis/modules}/__init__.py +0 -0
  156. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/redis/modules/caches.py +0 -0
  157. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/redis/modules/queries.py +0 -0
  158. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/redis/rb.py +0 -0
  159. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/redis/redis.py +0 -0
  160. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/redis/redis_cluster.py +0 -0
  161. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +0 -0
  162. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/redis/utils.py +0 -0
  163. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/rq.py +0 -0
  164. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/rust_tracing.py +0 -0
  165. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/sanic.py +0 -0
  166. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/serverless.py +0 -0
  167. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/socket.py +0 -0
  168. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/spark/__init__.py +0 -0
  169. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/spark/spark_worker.py +0 -0
  170. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/statsig.py +0 -0
  171. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/stdlib.py +0 -0
  172. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/strawberry.py +0 -0
  173. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/sys_exit.py +0 -0
  174. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/tornado.py +0 -0
  175. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/trytond.py +0 -0
  176. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/typer.py +0 -0
  177. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/unleash.py +0 -0
  178. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/integrations/unraisablehook.py +0 -0
  179. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/monitor.py +0 -0
  180. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/profiler/__init__.py +0 -0
  181. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/profiler/continuous_profiler.py +0 -0
  182. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/profiler/transaction_profiler.py +0 -0
  183. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/py.typed +0 -0
  184. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/scrubber.py +0 -0
  185. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/spotlight.py +0 -0
  186. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk/worker.py +0 -0
  187. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk.egg-info/dependency_links.txt +0 -0
  188. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk.egg-info/entry_points.txt +0 -0
  189. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk.egg-info/not-zip-safe +0 -0
  190. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/sentry_sdk.egg-info/top_level.txt +0 -0
  191. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/setup.cfg +0 -0
  192. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_ai_monitoring.py +0 -0
  193. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_api.py +0 -0
  194. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_crons.py +0 -0
  195. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_dsc.py +0 -0
  196. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_exceptiongroup.py +0 -0
  197. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_feature_flags.py +0 -0
  198. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_full_stack_frames.py +0 -0
  199. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_import.py +0 -0
  200. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_lru_cache.py +0 -0
  201. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_monitor.py +0 -0
  202. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_scope.py +0 -0
  203. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_scrubber.py +0 -0
  204. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_serializer.py +0 -0
  205. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_sessions.py +0 -0
  206. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_spotlight.py +0 -0
  207. {sentry_sdk-2.39.0 → sentry_sdk-2.41.0}/tests/test_tracing_utils.py +0 -0
  208. {sentry_sdk-2.39.0 → sentry_sdk-2.41.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.41.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
@@ -0,0 +1,81 @@
1
+ """
2
+ NOTE: This file contains experimental code that may be changed or removed at any
3
+ time without prior notice.
4
+ """
5
+
6
+ import time
7
+ from typing import Any, Optional, TYPE_CHECKING, Union
8
+
9
+ import sentry_sdk
10
+ from sentry_sdk.utils import safe_repr
11
+
12
+ if TYPE_CHECKING:
13
+ from sentry_sdk._types import Metric, MetricType
14
+
15
+
16
+ def _capture_metric(
17
+ name, # type: str
18
+ metric_type, # type: MetricType
19
+ value, # type: float
20
+ unit=None, # type: Optional[str]
21
+ attributes=None, # type: Optional[dict[str, Any]]
22
+ ):
23
+ # type: (...) -> None
24
+ client = sentry_sdk.get_client()
25
+
26
+ attrs = {} # type: dict[str, Union[str, bool, float, int]]
27
+ if attributes:
28
+ for k, v in attributes.items():
29
+ attrs[k] = (
30
+ v
31
+ if (
32
+ isinstance(v, str)
33
+ or isinstance(v, int)
34
+ or isinstance(v, bool)
35
+ or isinstance(v, float)
36
+ )
37
+ else safe_repr(v)
38
+ )
39
+
40
+ metric = {
41
+ "timestamp": time.time(),
42
+ "trace_id": None,
43
+ "span_id": None,
44
+ "name": name,
45
+ "type": metric_type,
46
+ "value": float(value),
47
+ "unit": unit,
48
+ "attributes": attrs,
49
+ } # type: Metric
50
+
51
+ client._capture_metric(metric)
52
+
53
+
54
+ def count(
55
+ name, # type: str
56
+ value, # type: float
57
+ unit=None, # type: Optional[str]
58
+ attributes=None, # type: Optional[dict[str, Any]]
59
+ ):
60
+ # type: (...) -> None
61
+ _capture_metric(name, "counter", value, unit, attributes)
62
+
63
+
64
+ def gauge(
65
+ name, # type: str
66
+ value, # type: float
67
+ unit=None, # type: Optional[str]
68
+ attributes=None, # type: Optional[dict[str, Any]]
69
+ ):
70
+ # type: (...) -> None
71
+ _capture_metric(name, "gauge", value, unit, attributes)
72
+
73
+
74
+ def distribution(
75
+ name, # type: str
76
+ value, # type: float
77
+ unit=None, # type: Optional[str]
78
+ attributes=None, # type: Optional[dict[str, Any]]
79
+ ):
80
+ # type: (...) -> None
81
+ _capture_metric(name, "distribution", value, unit, attributes)
@@ -0,0 +1,156 @@
1
+ import os
2
+ import random
3
+ import threading
4
+ from datetime import datetime, timezone
5
+ from typing import Optional, List, Callable, TYPE_CHECKING, Any, Union
6
+
7
+ from sentry_sdk.utils import format_timestamp, safe_repr
8
+ from sentry_sdk.envelope import Envelope, Item, PayloadRef
9
+
10
+ if TYPE_CHECKING:
11
+ from sentry_sdk._types import Metric
12
+
13
+
14
+ class MetricsBatcher:
15
+ MAX_METRICS_BEFORE_FLUSH = 100
16
+ FLUSH_WAIT_TIME = 5.0
17
+
18
+ def __init__(
19
+ self,
20
+ capture_func, # type: Callable[[Envelope], None]
21
+ ):
22
+ # type: (...) -> None
23
+ self._metric_buffer = [] # type: List[Metric]
24
+ self._capture_func = capture_func
25
+ self._running = True
26
+ self._lock = threading.Lock()
27
+
28
+ self._flush_event = threading.Event() # type: threading.Event
29
+
30
+ self._flusher = None # type: Optional[threading.Thread]
31
+ self._flusher_pid = None # type: Optional[int]
32
+
33
+ def _ensure_thread(self):
34
+ # type: (...) -> bool
35
+ if not self._running:
36
+ return False
37
+
38
+ pid = os.getpid()
39
+ if self._flusher_pid == pid:
40
+ return True
41
+
42
+ with self._lock:
43
+ if self._flusher_pid == pid:
44
+ return True
45
+
46
+ self._flusher_pid = pid
47
+
48
+ self._flusher = threading.Thread(target=self._flush_loop)
49
+ self._flusher.daemon = True
50
+
51
+ try:
52
+ self._flusher.start()
53
+ except RuntimeError:
54
+ self._running = False
55
+ return False
56
+
57
+ return True
58
+
59
+ def _flush_loop(self):
60
+ # type: (...) -> None
61
+ while self._running:
62
+ self._flush_event.wait(self.FLUSH_WAIT_TIME + random.random())
63
+ self._flush_event.clear()
64
+ self._flush()
65
+
66
+ def add(
67
+ self,
68
+ metric, # type: Metric
69
+ ):
70
+ # type: (...) -> None
71
+ if not self._ensure_thread() or self._flusher is None:
72
+ return None
73
+
74
+ with self._lock:
75
+ self._metric_buffer.append(metric)
76
+ if len(self._metric_buffer) >= self.MAX_METRICS_BEFORE_FLUSH:
77
+ self._flush_event.set()
78
+
79
+ def kill(self):
80
+ # type: (...) -> None
81
+ if self._flusher is None:
82
+ return
83
+
84
+ self._running = False
85
+ self._flush_event.set()
86
+ self._flusher = None
87
+
88
+ def flush(self):
89
+ # type: (...) -> None
90
+ self._flush()
91
+
92
+ @staticmethod
93
+ def _metric_to_transport_format(metric):
94
+ # type: (Metric) -> Any
95
+ def format_attribute(val):
96
+ # type: (Union[int, float, str, bool]) -> Any
97
+ if isinstance(val, bool):
98
+ return {"value": val, "type": "boolean"}
99
+ if isinstance(val, int):
100
+ return {"value": val, "type": "integer"}
101
+ if isinstance(val, float):
102
+ return {"value": val, "type": "double"}
103
+ if isinstance(val, str):
104
+ return {"value": val, "type": "string"}
105
+ return {"value": safe_repr(val), "type": "string"}
106
+
107
+ res = {
108
+ "timestamp": metric["timestamp"],
109
+ "trace_id": metric["trace_id"],
110
+ "name": metric["name"],
111
+ "type": metric["type"],
112
+ "value": metric["value"],
113
+ "attributes": {
114
+ k: format_attribute(v) for (k, v) in metric["attributes"].items()
115
+ },
116
+ }
117
+
118
+ if metric.get("span_id") is not None:
119
+ res["span_id"] = metric["span_id"]
120
+
121
+ if metric.get("unit") is not None:
122
+ res["unit"] = metric["unit"]
123
+
124
+ return res
125
+
126
+ def _flush(self):
127
+ # type: (...) -> Optional[Envelope]
128
+
129
+ envelope = Envelope(
130
+ headers={"sent_at": format_timestamp(datetime.now(timezone.utc))}
131
+ )
132
+ with self._lock:
133
+ if len(self._metric_buffer) == 0:
134
+ return None
135
+
136
+ envelope.add_item(
137
+ Item(
138
+ type="trace_metric",
139
+ content_type="application/vnd.sentry.items.trace-metric+json",
140
+ headers={
141
+ "item_count": len(self._metric_buffer),
142
+ },
143
+ payload=PayloadRef(
144
+ json={
145
+ "items": [
146
+ self._metric_to_transport_format(metric)
147
+ for metric in self._metric_buffer
148
+ ]
149
+ }
150
+ ),
151
+ )
152
+ )
153
+ self._metric_buffer.clear()
154
+
155
+ self._capture_func(envelope)
156
+ return envelope
@@ -210,7 +210,6 @@ if TYPE_CHECKING:
210
210
  "type": Literal["check_in", "transaction"],
211
211
  "user": dict[str, object],
212
212
  "_dropped_spans": int,
213
- "_metrics_summary": dict[str, object],
214
213
  },
215
214
  total=False,
216
215
  )
@@ -235,6 +234,32 @@ if TYPE_CHECKING:
235
234
  },
236
235
  )
237
236
 
237
+ MetricType = Literal["counter", "gauge", "distribution"]
238
+
239
+ MetricAttributeValue = TypedDict(
240
+ "MetricAttributeValue",
241
+ {
242
+ "value": Union[str, bool, float, int],
243
+ "type": Literal["string", "boolean", "double", "integer"],
244
+ },
245
+ )
246
+
247
+ Metric = TypedDict(
248
+ "Metric",
249
+ {
250
+ "timestamp": float,
251
+ "trace_id": Optional[str],
252
+ "span_id": Optional[str],
253
+ "name": str,
254
+ "type": MetricType,
255
+ "value": float,
256
+ "unit": Optional[str],
257
+ "attributes": dict[str, str | bool | float | int],
258
+ },
259
+ )
260
+
261
+ MetricProcessor = Callable[[Metric, Hint], Optional[Metric]]
262
+
238
263
  # TODO: Make a proper type definition for this (PRs welcome!)
239
264
  Breadcrumb = Dict[str, Any]
240
265
 
@@ -266,36 +291,16 @@ if TYPE_CHECKING:
266
291
  "internal",
267
292
  "profile",
268
293
  "profile_chunk",
269
- "metric_bucket",
270
294
  "monitor",
271
295
  "span",
272
296
  "log_item",
297
+ "trace_metric",
273
298
  ]
274
299
  SessionStatus = Literal["ok", "exited", "crashed", "abnormal"]
275
300
 
276
301
  ContinuousProfilerMode = Literal["thread", "gevent", "unknown"]
277
302
  ProfilerMode = Union[ContinuousProfilerMode, Literal["sleep"]]
278
303
 
279
- # Type of the metric.
280
- MetricType = Literal["d", "s", "g", "c"]
281
-
282
- # Value of the metric.
283
- MetricValue = Union[int, float, str]
284
-
285
- # Internal representation of tags as a tuple of tuples (this is done in order to allow for the same key to exist
286
- # multiple times).
287
- MetricTagsInternal = Tuple[Tuple[str, str], ...]
288
-
289
- # External representation of tags as a dictionary.
290
- MetricTagValue = Union[str, int, float, None]
291
- MetricTags = Mapping[str, MetricTagValue]
292
-
293
- # Value inside the generator for the metric value.
294
- FlushedMetricValue = Union[int, float]
295
-
296
- BucketKey = Tuple[MetricType, str, MeasurementUnit, MetricTagsInternal]
297
- MetricMetaKey = Tuple[MetricType, str, MeasurementUnit]
298
-
299
304
  MonitorConfigScheduleType = Literal["crontab", "interval"]
300
305
  MonitorConfigScheduleUnit = Literal[
301
306
  "year",
@@ -0,0 +1,7 @@
1
+ from .utils import (
2
+ set_data_normalized,
3
+ GEN_AI_MESSAGE_ROLE_MAPPING,
4
+ GEN_AI_MESSAGE_ROLE_REVERSE_MAPPING,
5
+ normalize_message_role,
6
+ normalize_message_roles,
7
+ ) # noqa: F401
@@ -10,6 +10,26 @@ import sentry_sdk
10
10
  from sentry_sdk.utils import logger
11
11
 
12
12
 
13
+ class GEN_AI_ALLOWED_MESSAGE_ROLES:
14
+ SYSTEM = "system"
15
+ USER = "user"
16
+ ASSISTANT = "assistant"
17
+ TOOL = "tool"
18
+
19
+
20
+ GEN_AI_MESSAGE_ROLE_REVERSE_MAPPING = {
21
+ GEN_AI_ALLOWED_MESSAGE_ROLES.SYSTEM: ["system"],
22
+ GEN_AI_ALLOWED_MESSAGE_ROLES.USER: ["user", "human"],
23
+ GEN_AI_ALLOWED_MESSAGE_ROLES.ASSISTANT: ["assistant", "ai"],
24
+ GEN_AI_ALLOWED_MESSAGE_ROLES.TOOL: ["tool", "tool_call"],
25
+ }
26
+
27
+ GEN_AI_MESSAGE_ROLE_MAPPING = {}
28
+ for target_role, source_roles in GEN_AI_MESSAGE_ROLE_REVERSE_MAPPING.items():
29
+ for source_role in source_roles:
30
+ GEN_AI_MESSAGE_ROLE_MAPPING[source_role] = target_role
31
+
32
+
13
33
  def _normalize_data(data, unpack=True):
14
34
  # type: (Any, bool) -> Any
15
35
  # convert pydantic data (e.g. OpenAI v1+) to json compatible format
@@ -40,6 +60,34 @@ def set_data_normalized(span, key, value, unpack=True):
40
60
  span.set_data(key, json.dumps(normalized))
41
61
 
42
62
 
63
+ def normalize_message_role(role):
64
+ # type: (str) -> str
65
+ """
66
+ Normalize a message role to one of the 4 allowed gen_ai role values.
67
+ Maps "ai" -> "assistant" and keeps other standard roles unchanged.
68
+ """
69
+ return GEN_AI_MESSAGE_ROLE_MAPPING.get(role, role)
70
+
71
+
72
+ def normalize_message_roles(messages):
73
+ # type: (list[dict[str, Any]]) -> list[dict[str, Any]]
74
+ """
75
+ Normalize roles in a list of messages to use standard gen_ai role values.
76
+ Creates a deep copy to avoid modifying the original messages.
77
+ """
78
+ normalized_messages = []
79
+ for message in messages:
80
+ if not isinstance(message, dict):
81
+ normalized_messages.append(message)
82
+ continue
83
+ normalized_message = message.copy()
84
+ if "role" in message:
85
+ normalized_message["role"] = normalize_message_role(message["role"])
86
+ normalized_messages.append(normalized_message)
87
+
88
+ return normalized_messages
89
+
90
+
43
91
  def get_start_span_function():
44
92
  # type: () -> Callable[..., Any]
45
93
  current_span = sentry_sdk.get_current_span()