sentry-sdk 3.0.0a1__tar.gz → 3.0.0a3__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-3.0.0a1/sentry_sdk.egg-info → sentry_sdk-3.0.0a3}/PKG-INFO +3 -3
  2. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/README.md +2 -2
  3. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/pyproject.toml +7 -0
  4. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/__init__.py +2 -0
  5. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/_compat.py +5 -12
  6. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/_init_implementation.py +7 -7
  7. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/_log_batcher.py +17 -29
  8. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/_lru_cache.py +7 -9
  9. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/_queue.py +2 -4
  10. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/_types.py +11 -18
  11. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/_werkzeug.py +5 -7
  12. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/ai/monitoring.py +44 -31
  13. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/ai/utils.py +3 -4
  14. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/api.py +75 -87
  15. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/attachments.py +10 -12
  16. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/client.py +137 -155
  17. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/consts.py +430 -174
  18. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/crons/api.py +16 -17
  19. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/crons/decorator.py +25 -27
  20. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/debug.py +4 -6
  21. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/envelope.py +46 -112
  22. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/feature_flags.py +9 -15
  23. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/__init__.py +24 -19
  24. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/_asgi_common.py +15 -18
  25. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/_wsgi_common.py +22 -33
  26. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/aiohttp.py +32 -30
  27. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/anthropic.py +42 -37
  28. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/argv.py +3 -4
  29. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/ariadne.py +16 -18
  30. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/arq.py +21 -29
  31. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/asgi.py +63 -37
  32. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/asyncio.py +14 -16
  33. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/atexit.py +6 -10
  34. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/aws_lambda.py +26 -36
  35. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/beam.py +10 -18
  36. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/boto3.py +18 -16
  37. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/bottle.py +25 -34
  38. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/celery/__init__.py +41 -61
  39. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/celery/beat.py +23 -27
  40. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/celery/utils.py +15 -17
  41. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/chalice.py +8 -10
  42. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/clickhouse_driver.py +21 -31
  43. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/cloud_resource_context.py +9 -16
  44. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/cohere.py +27 -33
  45. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/dedupe.py +5 -8
  46. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/django/__init__.py +57 -72
  47. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/django/asgi.py +26 -34
  48. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/django/caching.py +23 -19
  49. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/django/middleware.py +17 -20
  50. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/django/signals_handlers.py +11 -10
  51. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/django/templates.py +19 -16
  52. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/django/transactions.py +16 -11
  53. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/django/views.py +6 -10
  54. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/dramatiq.py +21 -21
  55. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/excepthook.py +10 -10
  56. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/executing.py +3 -4
  57. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/falcon.py +27 -42
  58. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/fastapi.py +13 -16
  59. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/flask.py +31 -38
  60. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/gcp.py +13 -16
  61. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/gnu_backtrace.py +4 -6
  62. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/gql.py +16 -17
  63. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/graphene.py +13 -12
  64. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/grpc/__init__.py +19 -1
  65. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/grpc/aio/server.py +15 -14
  66. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/grpc/client.py +19 -9
  67. sentry_sdk-3.0.0a3/sentry_sdk/integrations/grpc/consts.py +3 -0
  68. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/grpc/server.py +12 -8
  69. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/httpx.py +9 -12
  70. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/huey.py +13 -20
  71. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/huggingface_hub.py +18 -18
  72. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/langchain.py +203 -113
  73. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/launchdarkly.py +13 -10
  74. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/litestar.py +37 -35
  75. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/logging.py +52 -65
  76. sentry_sdk-3.0.0a3/sentry_sdk/integrations/loguru.py +200 -0
  77. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/modules.py +3 -4
  78. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/openai.py +100 -88
  79. sentry_sdk-3.0.0a3/sentry_sdk/integrations/openai_agents/__init__.py +49 -0
  80. sentry_sdk-3.0.0a3/sentry_sdk/integrations/openai_agents/consts.py +1 -0
  81. sentry_sdk-3.0.0a3/sentry_sdk/integrations/openai_agents/patches/__init__.py +4 -0
  82. sentry_sdk-3.0.0a3/sentry_sdk/integrations/openai_agents/patches/agent_run.py +152 -0
  83. sentry_sdk-3.0.0a3/sentry_sdk/integrations/openai_agents/patches/models.py +52 -0
  84. sentry_sdk-3.0.0a3/sentry_sdk/integrations/openai_agents/patches/runner.py +42 -0
  85. sentry_sdk-3.0.0a3/sentry_sdk/integrations/openai_agents/patches/tools.py +84 -0
  86. sentry_sdk-3.0.0a3/sentry_sdk/integrations/openai_agents/spans/__init__.py +5 -0
  87. sentry_sdk-3.0.0a3/sentry_sdk/integrations/openai_agents/spans/agent_workflow.py +20 -0
  88. sentry_sdk-3.0.0a3/sentry_sdk/integrations/openai_agents/spans/ai_client.py +46 -0
  89. sentry_sdk-3.0.0a3/sentry_sdk/integrations/openai_agents/spans/execute_tool.py +47 -0
  90. sentry_sdk-3.0.0a3/sentry_sdk/integrations/openai_agents/spans/handoff.py +24 -0
  91. sentry_sdk-3.0.0a3/sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +41 -0
  92. sentry_sdk-3.0.0a3/sentry_sdk/integrations/openai_agents/utils.py +201 -0
  93. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/openfeature.py +11 -6
  94. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/pure_eval.py +6 -10
  95. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/pymongo.py +13 -17
  96. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/pyramid.py +31 -36
  97. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/quart.py +23 -28
  98. sentry_sdk-3.0.0a3/sentry_sdk/integrations/ray.py +156 -0
  99. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/redis/__init__.py +7 -4
  100. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/redis/_async_common.py +25 -12
  101. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/redis/_sync_common.py +19 -13
  102. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/redis/modules/caches.py +17 -8
  103. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/redis/modules/queries.py +9 -8
  104. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/redis/rb.py +3 -2
  105. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/redis/redis.py +4 -4
  106. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/redis/redis_cluster.py +21 -13
  107. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +3 -2
  108. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/redis/utils.py +23 -24
  109. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/rq.py +13 -16
  110. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/rust_tracing.py +9 -6
  111. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/sanic.py +34 -46
  112. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/serverless.py +22 -27
  113. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/socket.py +27 -15
  114. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/spark/__init__.py +1 -0
  115. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/spark/spark_driver.py +45 -83
  116. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/spark/spark_worker.py +7 -11
  117. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/sqlalchemy.py +22 -19
  118. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/starlette.py +86 -90
  119. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/starlite.py +28 -34
  120. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/statsig.py +5 -4
  121. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/stdlib.py +28 -24
  122. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/strawberry.py +62 -49
  123. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/sys_exit.py +7 -11
  124. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/threading.py +12 -14
  125. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/tornado.py +28 -32
  126. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/trytond.py +4 -3
  127. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/typer.py +8 -6
  128. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/unleash.py +5 -4
  129. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/wsgi.py +47 -46
  130. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/logger.py +41 -10
  131. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/monitor.py +16 -28
  132. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/opentelemetry/consts.py +11 -4
  133. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/opentelemetry/contextvars_context.py +26 -16
  134. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/opentelemetry/propagator.py +38 -21
  135. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/opentelemetry/sampler.py +51 -34
  136. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/opentelemetry/scope.py +36 -37
  137. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/opentelemetry/span_processor.py +48 -58
  138. sentry_sdk-3.0.0a3/sentry_sdk/opentelemetry/tracing.py +79 -0
  139. sentry_sdk-3.0.0a3/sentry_sdk/opentelemetry/utils.py +468 -0
  140. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/profiler/continuous_profiler.py +108 -97
  141. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/profiler/transaction_profiler.py +70 -97
  142. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/profiler/utils.py +11 -15
  143. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/scope.py +251 -273
  144. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/scrubber.py +22 -26
  145. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/serializer.py +40 -54
  146. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/session.py +44 -61
  147. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/sessions.py +35 -49
  148. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/spotlight.py +15 -21
  149. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/tracing.py +121 -187
  150. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/tracing_utils.py +104 -122
  151. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/transport.py +131 -157
  152. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/utils.py +232 -309
  153. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/worker.py +16 -28
  154. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3/sentry_sdk.egg-info}/PKG-INFO +3 -3
  155. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk.egg-info/SOURCES.txt +15 -0
  156. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/setup.py +1 -1
  157. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_ai_monitoring.py +41 -0
  158. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_api.py +52 -32
  159. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_basics.py +84 -20
  160. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_client.py +66 -1
  161. sentry_sdk-3.0.0a3/tests/test_gevent.py +118 -0
  162. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_logs.py +30 -136
  163. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_scope.py +113 -4
  164. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_sessions.py +81 -0
  165. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_transport.py +12 -66
  166. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_utils.py +137 -89
  167. sentry_sdk-3.0.0a1/sentry_sdk/integrations/grpc/consts.py +0 -1
  168. sentry_sdk-3.0.0a1/sentry_sdk/integrations/loguru.py +0 -130
  169. sentry_sdk-3.0.0a1/sentry_sdk/integrations/ray.py +0 -147
  170. sentry_sdk-3.0.0a1/sentry_sdk/opentelemetry/tracing.py +0 -35
  171. sentry_sdk-3.0.0a1/sentry_sdk/opentelemetry/utils.py +0 -476
  172. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/LICENSE +0 -0
  173. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/MANIFEST.in +0 -0
  174. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/ai/__init__.py +0 -0
  175. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/crons/__init__.py +0 -0
  176. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/crons/consts.py +0 -0
  177. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/asyncpg.py +0 -0
  178. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/grpc/aio/__init__.py +0 -0
  179. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/grpc/aio/client.py +0 -0
  180. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/redis/consts.py +0 -0
  181. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/integrations/redis/modules/__init__.py +0 -0
  182. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/opentelemetry/__init__.py +0 -0
  183. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/profiler/__init__.py +0 -0
  184. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/py.typed +0 -0
  185. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk/types.py +0 -0
  186. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk.egg-info/dependency_links.txt +0 -0
  187. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk.egg-info/entry_points.txt +0 -0
  188. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk.egg-info/not-zip-safe +0 -0
  189. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk.egg-info/requires.txt +0 -0
  190. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/sentry_sdk.egg-info/top_level.txt +0 -0
  191. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/setup.cfg +0 -0
  192. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_breadcrumbs.py +0 -0
  193. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_conftest.py +0 -0
  194. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_crons.py +0 -0
  195. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_dsc.py +0 -0
  196. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_envelope.py +0 -0
  197. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_exceptiongroup.py +0 -0
  198. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_feature_flags.py +0 -0
  199. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_full_stack_frames.py +0 -0
  200. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_import.py +0 -0
  201. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_lru_cache.py +0 -0
  202. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_monitor.py +0 -0
  203. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_propagationcontext.py +0 -0
  204. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_scrubber.py +0 -0
  205. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_serializer.py +0 -0
  206. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_spotlight.py +0 -0
  207. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_tracing_utils.py +0 -0
  208. {sentry_sdk-3.0.0a1 → sentry_sdk-3.0.0a3}/tests/test_types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry-sdk
3
- Version: 3.0.0a1
3
+ Version: 3.0.0a3
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
@@ -134,7 +134,7 @@ Dynamic: summary
134
134
  _Bad software is everywhere, and we're tired of it. Sentry is on a mission to help developers write better software faster, so we can get back to enjoying technology. If you want to join us
135
135
  [<kbd>**Check out our open positions**</kbd>](https://sentry.io/careers/)_.
136
136
 
137
- [![Discord](https://img.shields.io/discord/621778831602221064?logo=discord&labelColor=%20%235462eb&logoColor=%20%23f5f5f5&color=%20%235462eb)](https://discord.gg/wdNEHETs87)
137
+ [![Discord](https://img.shields.io/discord/621778831602221064?logo=discord&labelColor=%20%235462eb&logoColor=%20%23f5f5f5&color=%20%235462eb)](https://discord.com/invite/Ww9hbqr)
138
138
  [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=@getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry)
139
139
  [![PyPi page link -- version](https://img.shields.io/pypi/v/sentry-sdk.svg)](https://pypi.python.org/pypi/sentry-sdk)
140
140
  <img src="https://img.shields.io/badge/python-3.7 | 3.8 | 3.9 | 3.10 | 3.11 | 3.12 | 3.13-blue.svg" alt="python">
@@ -234,7 +234,7 @@ If you encounter issues or need help setting up or configuring the SDK, don't he
234
234
  Here are all resources to help you make the most of Sentry:
235
235
 
236
236
  - [Documentation](https://docs.sentry.io/platforms/python/) - Official documentation to get started.
237
- - [Discord](https://img.shields.io/discord/621778831602221064) - Join our Discord community.
237
+ - [Discord](https://discord.com/invite/Ww9hbqr) - Join our Discord community.
238
238
  - [X/Twitter](https://twitter.com/intent/follow?screen_name=getsentry) - Follow us on X (Twitter) for updates.
239
239
  - [Stack Overflow](https://stackoverflow.com/questions/tagged/sentry) - Questions and answers related to Sentry.
240
240
 
@@ -6,7 +6,7 @@
6
6
  _Bad software is everywhere, and we're tired of it. Sentry is on a mission to help developers write better software faster, so we can get back to enjoying technology. If you want to join us
7
7
  [<kbd>**Check out our open positions**</kbd>](https://sentry.io/careers/)_.
8
8
 
9
- [![Discord](https://img.shields.io/discord/621778831602221064?logo=discord&labelColor=%20%235462eb&logoColor=%20%23f5f5f5&color=%20%235462eb)](https://discord.gg/wdNEHETs87)
9
+ [![Discord](https://img.shields.io/discord/621778831602221064?logo=discord&labelColor=%20%235462eb&logoColor=%20%23f5f5f5&color=%20%235462eb)](https://discord.com/invite/Ww9hbqr)
10
10
  [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=@getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry)
11
11
  [![PyPi page link -- version](https://img.shields.io/pypi/v/sentry-sdk.svg)](https://pypi.python.org/pypi/sentry-sdk)
12
12
  <img src="https://img.shields.io/badge/python-3.7 | 3.8 | 3.9 | 3.10 | 3.11 | 3.12 | 3.13-blue.svg" alt="python">
@@ -106,7 +106,7 @@ If you encounter issues or need help setting up or configuring the SDK, don't he
106
106
  Here are all resources to help you make the most of Sentry:
107
107
 
108
108
  - [Documentation](https://docs.sentry.io/platforms/python/) - Official documentation to get started.
109
- - [Discord](https://img.shields.io/discord/621778831602221064) - Join our Discord community.
109
+ - [Discord](https://discord.com/invite/Ww9hbqr) - Join our Discord community.
110
110
  - [X/Twitter](https://twitter.com/intent/follow?screen_name=getsentry) - Follow us on X (Twitter) for updates.
111
111
  - [Stack Overflow](https://stackoverflow.com/questions/tagged/sentry) - Questions and answers related to Sentry.
112
112
 
@@ -183,6 +183,10 @@ ignore_missing_imports = true
183
183
  module = "grpc.*"
184
184
  ignore_missing_imports = true
185
185
 
186
+ [[tool.mypy.overrides]]
187
+ module = "agents.*"
188
+ ignore_missing_imports = true
189
+
186
190
  #
187
191
  # Tool: Flake8
188
192
  #
@@ -210,3 +214,6 @@ exclude = [
210
214
  "grpc_test_service_pb2.py",
211
215
  "grpc_test_service_pb2_grpc.py",
212
216
  ]
217
+ per-file-ignores = [
218
+ "sentry_sdk/integrations/spark/*:N802,N803",
219
+ ]
@@ -45,6 +45,8 @@ __all__ = [ # noqa
45
45
  "trace",
46
46
  "monitor",
47
47
  "logger",
48
+ "start_session",
49
+ "end_session",
48
50
  ]
49
51
 
50
52
  # Initialize the debug support after everything is loaded
@@ -1,12 +1,9 @@
1
+ from __future__ import annotations
1
2
  import sys
2
-
3
3
  from typing import TYPE_CHECKING
4
4
 
5
5
  if TYPE_CHECKING:
6
6
  from typing import Any
7
- from typing import TypeVar
8
-
9
- T = TypeVar("T")
10
7
 
11
8
 
12
9
  PY38 = sys.version_info[0] == 3 and sys.version_info[1] >= 8
@@ -14,18 +11,15 @@ PY310 = sys.version_info[0] == 3 and sys.version_info[1] >= 10
14
11
  PY311 = sys.version_info[0] == 3 and sys.version_info[1] >= 11
15
12
 
16
13
 
17
- def with_metaclass(meta, *bases):
18
- # type: (Any, *Any) -> Any
14
+ def with_metaclass(meta: Any, *bases: Any) -> Any:
19
15
  class MetaClass(type):
20
- def __new__(metacls, name, this_bases, d):
21
- # type: (Any, Any, Any, Any) -> Any
16
+ def __new__(metacls: Any, name: Any, this_bases: Any, d: Any) -> Any:
22
17
  return meta(name, bases, d)
23
18
 
24
19
  return type.__new__(MetaClass, "temporary_class", (), {})
25
20
 
26
21
 
27
- def check_uwsgi_thread_support():
28
- # type: () -> bool
22
+ def check_uwsgi_thread_support() -> bool:
29
23
  # We check two things here:
30
24
  #
31
25
  # 1. uWSGI doesn't run in threaded mode by default -- issue a warning if
@@ -45,8 +39,7 @@ def check_uwsgi_thread_support():
45
39
 
46
40
  from sentry_sdk.consts import FALSE_VALUES
47
41
 
48
- def enabled(option):
49
- # type: (str) -> bool
42
+ def enabled(option: str) -> bool:
50
43
  value = opt.get(option, False)
51
44
  if isinstance(value, bool):
52
45
  return value
@@ -1,23 +1,23 @@
1
+ from __future__ import annotations
2
+
1
3
  from typing import TYPE_CHECKING
2
4
 
5
+ if TYPE_CHECKING:
6
+ from typing import Optional, Any
7
+
3
8
  import sentry_sdk
4
9
  from sentry_sdk.consts import ClientConstructor
5
10
  from sentry_sdk.opentelemetry.scope import setup_scope_context_management
6
11
 
7
- if TYPE_CHECKING:
8
- from typing import Any, Optional
9
-
10
12
 
11
- def _check_python_deprecations():
12
- # type: () -> None
13
+ def _check_python_deprecations() -> None:
13
14
  # Since we're likely to deprecate Python versions in the future, I'm keeping
14
15
  # this handy function around. Use this to detect the Python version used and
15
16
  # to output logger.warning()s if it's deprecated.
16
17
  pass
17
18
 
18
19
 
19
- def _init(*args, **kwargs):
20
- # type: (*Optional[str], **Any) -> None
20
+ def _init(*args: Optional[str], **kwargs: Any) -> None:
21
21
  """Initializes the SDK and optionally integrations.
22
22
 
23
23
  This takes the same arguments as the client constructor.
@@ -1,37 +1,35 @@
1
+ from __future__ import annotations
1
2
  import os
2
3
  import random
3
4
  import threading
4
5
  from datetime import datetime, timezone
5
- from typing import Optional, List, Callable, TYPE_CHECKING, Any
6
6
 
7
7
  from sentry_sdk.utils import format_timestamp, safe_repr
8
8
  from sentry_sdk.envelope import Envelope, Item, PayloadRef
9
9
 
10
+ from typing import TYPE_CHECKING
11
+
10
12
  if TYPE_CHECKING:
11
13
  from sentry_sdk._types import Log
14
+ from typing import Optional, List, Callable, Any
12
15
 
13
16
 
14
17
  class LogBatcher:
15
18
  MAX_LOGS_BEFORE_FLUSH = 100
16
19
  FLUSH_WAIT_TIME = 5.0
17
20
 
18
- def __init__(
19
- self,
20
- capture_func, # type: Callable[[Envelope], None]
21
- ):
22
- # type: (...) -> None
23
- self._log_buffer = [] # type: List[Log]
21
+ def __init__(self, capture_func: Callable[[Envelope], None]) -> None:
22
+ self._log_buffer: List[Log] = []
24
23
  self._capture_func = capture_func
25
24
  self._running = True
26
25
  self._lock = threading.Lock()
27
26
 
28
- self._flush_event = threading.Event() # type: threading.Event
27
+ self._flush_event = threading.Event()
29
28
 
30
- self._flusher = None # type: Optional[threading.Thread]
31
- self._flusher_pid = None # type: Optional[int]
29
+ self._flusher: Optional[threading.Thread] = None
30
+ self._flusher_pid: Optional[int] = None
32
31
 
33
- def _ensure_thread(self):
34
- # type: (...) -> bool
32
+ def _ensure_thread(self) -> bool:
35
33
  """For forking processes we might need to restart this thread.
36
34
  This ensures that our process actually has that thread running.
37
35
  """
@@ -63,18 +61,13 @@ class LogBatcher:
63
61
 
64
62
  return True
65
63
 
66
- def _flush_loop(self):
67
- # type: (...) -> None
64
+ def _flush_loop(self) -> None:
68
65
  while self._running:
69
66
  self._flush_event.wait(self.FLUSH_WAIT_TIME + random.random())
70
67
  self._flush_event.clear()
71
68
  self._flush()
72
69
 
73
- def add(
74
- self,
75
- log, # type: Log
76
- ):
77
- # type: (...) -> None
70
+ def add(self, log: Log) -> None:
78
71
  if not self._ensure_thread() or self._flusher is None:
79
72
  return None
80
73
 
@@ -83,8 +76,7 @@ class LogBatcher:
83
76
  if len(self._log_buffer) >= self.MAX_LOGS_BEFORE_FLUSH:
84
77
  self._flush_event.set()
85
78
 
86
- def kill(self):
87
- # type: (...) -> None
79
+ def kill(self) -> None:
88
80
  if self._flusher is None:
89
81
  return
90
82
 
@@ -92,15 +84,12 @@ class LogBatcher:
92
84
  self._flush_event.set()
93
85
  self._flusher = None
94
86
 
95
- def flush(self):
96
- # type: (...) -> None
87
+ def flush(self) -> None:
97
88
  self._flush()
98
89
 
99
90
  @staticmethod
100
- def _log_to_transport_format(log):
101
- # type: (Log) -> Any
102
- def format_attribute(val):
103
- # type: (int | float | str | bool) -> Any
91
+ def _log_to_transport_format(log: Log) -> Any:
92
+ def format_attribute(val: int | float | str | bool) -> Any:
104
93
  if isinstance(val, bool):
105
94
  return {"value": val, "type": "boolean"}
106
95
  if isinstance(val, int):
@@ -128,8 +117,7 @@ class LogBatcher:
128
117
 
129
118
  return res
130
119
 
131
- def _flush(self):
132
- # type: (...) -> Optional[Envelope]
120
+ def _flush(self) -> Optional[Envelope]:
133
121
 
134
122
  envelope = Envelope(
135
123
  headers={"sent_at": format_timestamp(datetime.now(timezone.utc))}
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from typing import TYPE_CHECKING
2
4
 
3
5
  if TYPE_CHECKING:
@@ -8,17 +10,15 @@ _SENTINEL = object()
8
10
 
9
11
 
10
12
  class LRUCache:
11
- def __init__(self, max_size):
12
- # type: (int) -> None
13
+ def __init__(self, max_size: int) -> None:
13
14
  if max_size <= 0:
14
15
  raise AssertionError(f"invalid max_size: {max_size}")
15
16
  self.max_size = max_size
16
- self._data = {} # type: dict[Any, Any]
17
+ self._data: dict[Any, Any] = {}
17
18
  self.hits = self.misses = 0
18
19
  self.full = False
19
20
 
20
- def set(self, key, value):
21
- # type: (Any, Any) -> None
21
+ def set(self, key: Any, value: Any) -> None:
22
22
  current = self._data.pop(key, _SENTINEL)
23
23
  if current is not _SENTINEL:
24
24
  self._data[key] = value
@@ -29,8 +29,7 @@ class LRUCache:
29
29
  self._data[key] = value
30
30
  self.full = len(self._data) >= self.max_size
31
31
 
32
- def get(self, key, default=None):
33
- # type: (Any, Any) -> Any
32
+ def get(self, key: Any, default: Any = None) -> Any:
34
33
  try:
35
34
  ret = self._data.pop(key)
36
35
  except KeyError:
@@ -42,6 +41,5 @@ class LRUCache:
42
41
 
43
42
  return ret
44
43
 
45
- def get_all(self):
46
- # type: () -> list[tuple[Any, Any]]
44
+ def get_all(self) -> list[tuple[Any, Any]]:
47
45
  return list(self._data.items())
@@ -10,9 +10,6 @@ https://codewithoutrules.com/2017/08/16/concurrency-python/
10
10
  https://bugs.python.org/issue14976
11
11
  https://github.com/sqlalchemy/sqlalchemy/blob/4eb747b61f0c1b1c25bdee3856d7195d10a0c227/lib/sqlalchemy/queue.py#L1
12
12
 
13
- We also vendor the code to evade eventlet's broken monkeypatching, see
14
- https://github.com/getsentry/sentry-python/pull/484
15
-
16
13
 
17
14
  Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
18
15
  2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Python Software Foundation;
@@ -81,6 +78,7 @@ from typing import TYPE_CHECKING
81
78
  if TYPE_CHECKING:
82
79
  from typing import Any
83
80
 
81
+
84
82
  __all__ = ["EmptyError", "FullError", "Queue"]
85
83
 
86
84
 
@@ -275,7 +273,7 @@ class Queue:
275
273
 
276
274
  # Initialize the queue representation
277
275
  def _init(self, maxsize):
278
- self.queue = deque() # type: Any
276
+ self.queue: Any = deque()
279
277
 
280
278
  def _qsize(self):
281
279
  return len(self.queue)
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from typing import TYPE_CHECKING, TypeVar, Union
2
4
 
3
5
 
@@ -18,32 +20,27 @@ class AnnotatedValue:
18
20
 
19
21
  __slots__ = ("value", "metadata")
20
22
 
21
- def __init__(self, value, metadata):
22
- # type: (Optional[Any], Dict[str, Any]) -> None
23
+ def __init__(self, value: Optional[Any], metadata: Dict[str, Any]) -> None:
23
24
  self.value = value
24
25
  self.metadata = metadata
25
26
 
26
- def __eq__(self, other):
27
- # type: (Any) -> bool
27
+ def __eq__(self, other: Any) -> bool:
28
28
  if not isinstance(other, AnnotatedValue):
29
29
  return False
30
30
 
31
31
  return self.value == other.value and self.metadata == other.metadata
32
32
 
33
- def __str__(self):
34
- # type: (AnnotatedValue) -> str
33
+ def __str__(self) -> str:
35
34
  return str({"value": str(self.value), "metadata": str(self.metadata)})
36
35
 
37
- def __len__(self):
38
- # type: (AnnotatedValue) -> int
36
+ def __len__(self) -> int:
39
37
  if self.value is not None:
40
38
  return len(self.value)
41
39
  else:
42
40
  return 0
43
41
 
44
42
  @classmethod
45
- def removed_because_raw_data(cls):
46
- # type: () -> AnnotatedValue
43
+ def removed_because_raw_data(cls) -> AnnotatedValue:
47
44
  """The value was removed because it could not be parsed. This is done for request body values that are not json nor a form."""
48
45
  return AnnotatedValue(
49
46
  value="",
@@ -58,8 +55,7 @@ class AnnotatedValue:
58
55
  )
59
56
 
60
57
  @classmethod
61
- def removed_because_over_size_limit(cls, value=""):
62
- # type: (Any) -> AnnotatedValue
58
+ def removed_because_over_size_limit(cls, value: Any = "") -> AnnotatedValue:
63
59
  """
64
60
  The actual value was removed because the size of the field exceeded the configured maximum size,
65
61
  for example specified with the max_request_body_size sdk option.
@@ -77,8 +73,7 @@ class AnnotatedValue:
77
73
  )
78
74
 
79
75
  @classmethod
80
- def substituted_because_contains_sensitive_data(cls):
81
- # type: () -> AnnotatedValue
76
+ def substituted_because_contains_sensitive_data(cls) -> AnnotatedValue:
82
77
  """The actual value was removed because it contained sensitive information."""
83
78
  return AnnotatedValue(
84
79
  value=SENSITIVE_DATA_SUBSTITUTE,
@@ -129,7 +124,7 @@ if TYPE_CHECKING:
129
124
  "contexts": dict[str, dict[str, object]],
130
125
  "dist": str,
131
126
  "duration": Optional[float],
132
- "environment": str,
127
+ "environment": Optional[str],
133
128
  "errors": list[dict[str, Any]], # TODO: We can expand on this type
134
129
  "event_id": str,
135
130
  "exception": dict[
@@ -146,7 +141,7 @@ if TYPE_CHECKING:
146
141
  "monitor_slug": Optional[str],
147
142
  "platform": Literal["python"],
148
143
  "profile": object, # Should be sentry_sdk.profiler.Profile, but we can't import that here due to circular imports
149
- "release": str,
144
+ "release": Optional[str],
150
145
  "request": dict[str, object],
151
146
  "sdk": Mapping[str, object],
152
147
  "server_name": str,
@@ -267,5 +262,3 @@ if TYPE_CHECKING:
267
262
  )
268
263
 
269
264
  HttpStatusCodeRange = Union[int, Container[int]]
270
-
271
- OtelExtractedSpanData = tuple[str, str, Optional[str], Optional[int], Optional[str]]
@@ -32,12 +32,12 @@ THIS SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF
32
32
  SUCH DAMAGE.
33
33
  """
34
34
 
35
+ from __future__ import annotations
36
+
35
37
  from typing import TYPE_CHECKING
36
38
 
37
39
  if TYPE_CHECKING:
38
- from typing import Dict
39
- from typing import Iterator
40
- from typing import Tuple
40
+ from typing import Dict, Iterator, Tuple
41
41
 
42
42
 
43
43
  #
@@ -47,8 +47,7 @@ if TYPE_CHECKING:
47
47
  # We need this function because Django does not give us a "pure" http header
48
48
  # dict. So we might as well use it for all WSGI integrations.
49
49
  #
50
- def _get_headers(environ):
51
- # type: (Dict[str, str]) -> Iterator[Tuple[str, str]]
50
+ def _get_headers(environ: Dict[str, str]) -> Iterator[Tuple[str, str]]:
52
51
  """
53
52
  Returns only proper HTTP headers.
54
53
  """
@@ -67,8 +66,7 @@ def _get_headers(environ):
67
66
  # `get_host` comes from `werkzeug.wsgi.get_host`
68
67
  # https://github.com/pallets/werkzeug/blob/1.0.1/src/werkzeug/wsgi.py#L145
69
68
  #
70
- def get_host(environ, use_x_forwarded_for=False):
71
- # type: (Dict[str, str], bool) -> str
69
+ def get_host(environ: Dict[str, str], use_x_forwarded_for: bool = False) -> str:
72
70
  """
73
71
  Return the host for the given WSGI environment.
74
72
  """
@@ -1,6 +1,8 @@
1
+ from __future__ import annotations
1
2
  import inspect
2
3
  from functools import wraps
3
4
 
5
+ from sentry_sdk.consts import SPANDATA
4
6
  import sentry_sdk.utils
5
7
  from sentry_sdk import start_span
6
8
  from sentry_sdk.tracing import Span
@@ -14,24 +16,19 @@ if TYPE_CHECKING:
14
16
  _ai_pipeline_name = ContextVar("ai_pipeline_name", default=None)
15
17
 
16
18
 
17
- def set_ai_pipeline_name(name):
18
- # type: (Optional[str]) -> None
19
+ def set_ai_pipeline_name(name: Optional[str]) -> None:
19
20
  _ai_pipeline_name.set(name)
20
21
 
21
22
 
22
- def get_ai_pipeline_name():
23
- # type: () -> Optional[str]
23
+ def get_ai_pipeline_name() -> Optional[str]:
24
24
  return _ai_pipeline_name.get()
25
25
 
26
26
 
27
- def ai_track(description, **span_kwargs):
28
- # type: (str, Any) -> Callable[..., Any]
29
- def decorator(f):
30
- # type: (Callable[..., Any]) -> Callable[..., Any]
31
- def sync_wrapped(*args, **kwargs):
32
- # type: (Any, Any) -> Any
27
+ def ai_track(description: str, **span_kwargs: Any) -> Callable[..., Any]:
28
+ def decorator(f: Callable[..., Any]) -> Callable[..., Any]:
29
+ def sync_wrapped(*args: Any, **kwargs: Any) -> Any:
33
30
  curr_pipeline = _ai_pipeline_name.get()
34
- op = span_kwargs.get("op", "ai.run" if curr_pipeline else "ai.pipeline")
31
+ op = span_kwargs.pop("op", "ai.run" if curr_pipeline else "ai.pipeline")
35
32
 
36
33
  with start_span(
37
34
  name=description, op=op, only_if_parent=True, **span_kwargs
@@ -41,7 +38,7 @@ def ai_track(description, **span_kwargs):
41
38
  for k, v in kwargs.pop("sentry_data", {}).items():
42
39
  span.set_attribute(k, v)
43
40
  if curr_pipeline:
44
- span.set_attribute("ai.pipeline.name", curr_pipeline)
41
+ span.set_attribute(SPANDATA.AI_PIPELINE_NAME, curr_pipeline)
45
42
  return f(*args, **kwargs)
46
43
  else:
47
44
  _ai_pipeline_name.set(description)
@@ -59,10 +56,9 @@ def ai_track(description, **span_kwargs):
59
56
  _ai_pipeline_name.set(None)
60
57
  return res
61
58
 
62
- async def async_wrapped(*args, **kwargs):
63
- # type: (Any, Any) -> Any
59
+ async def async_wrapped(*args: Any, **kwargs: Any) -> Any:
64
60
  curr_pipeline = _ai_pipeline_name.get()
65
- op = span_kwargs.get("op", "ai.run" if curr_pipeline else "ai.pipeline")
61
+ op = span_kwargs.pop("op", "ai.run" if curr_pipeline else "ai.pipeline")
66
62
 
67
63
  with start_span(
68
64
  name=description, op=op, only_if_parent=True, **span_kwargs
@@ -72,7 +68,7 @@ def ai_track(description, **span_kwargs):
72
68
  for k, v in kwargs.pop("sentry_data", {}).items():
73
69
  span.set_attribute(k, v)
74
70
  if curr_pipeline:
75
- span.set_attribute("ai.pipeline.name", curr_pipeline)
71
+ span.set_attribute(SPANDATA.AI_PIPELINE_NAME, curr_pipeline)
76
72
  return await f(*args, **kwargs)
77
73
  else:
78
74
  _ai_pipeline_name.set(description)
@@ -99,21 +95,38 @@ def ai_track(description, **span_kwargs):
99
95
 
100
96
 
101
97
  def record_token_usage(
102
- span, prompt_tokens=None, completion_tokens=None, total_tokens=None
103
- ):
104
- # type: (Span, Optional[int], Optional[int], Optional[int]) -> None
98
+ span: Span,
99
+ input_tokens: Optional[int] = None,
100
+ input_tokens_cached: Optional[int] = None,
101
+ output_tokens: Optional[int] = None,
102
+ output_tokens_reasoning: Optional[int] = None,
103
+ total_tokens: Optional[int] = None,
104
+ ) -> None:
105
+ # TODO: move pipeline name elsewhere
105
106
  ai_pipeline_name = get_ai_pipeline_name()
106
107
  if ai_pipeline_name:
107
- span.set_attribute("ai.pipeline.name", ai_pipeline_name)
108
- if prompt_tokens is not None:
109
- span.set_attribute("ai.prompt_tokens.used", prompt_tokens)
110
- if completion_tokens is not None:
111
- span.set_attribute("ai.completion_tokens.used", completion_tokens)
112
- if (
113
- total_tokens is None
114
- and prompt_tokens is not None
115
- and completion_tokens is not None
116
- ):
117
- total_tokens = prompt_tokens + completion_tokens
108
+ span.set_attribute(SPANDATA.AI_PIPELINE_NAME, ai_pipeline_name)
109
+
110
+ if input_tokens is not None:
111
+ span.set_attribute(SPANDATA.GEN_AI_USAGE_INPUT_TOKENS, input_tokens)
112
+
113
+ if input_tokens_cached is not None:
114
+ span.set_attribute(
115
+ SPANDATA.GEN_AI_USAGE_INPUT_TOKENS_CACHED,
116
+ input_tokens_cached,
117
+ )
118
+
119
+ if output_tokens is not None:
120
+ span.set_data(SPANDATA.GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens)
121
+
122
+ if output_tokens_reasoning is not None:
123
+ span.set_data(
124
+ SPANDATA.GEN_AI_USAGE_OUTPUT_TOKENS_REASONING,
125
+ output_tokens_reasoning,
126
+ )
127
+
128
+ if total_tokens is None and input_tokens is not None and output_tokens is not None:
129
+ total_tokens = input_tokens + output_tokens
130
+
118
131
  if total_tokens is not None:
119
- span.set_attribute("ai.total_tokens.used", total_tokens)
132
+ span.set_attribute(SPANDATA.GEN_AI_USAGE_TOTAL_TOKENS, total_tokens)
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  from typing import TYPE_CHECKING
2
3
 
3
4
  if TYPE_CHECKING:
@@ -7,8 +8,7 @@ from sentry_sdk.tracing import Span
7
8
  from sentry_sdk.utils import logger
8
9
 
9
10
 
10
- def _normalize_data(data):
11
- # type: (Any) -> Any
11
+ def _normalize_data(data: Any) -> Any:
12
12
 
13
13
  # convert pydantic data (e.g. OpenAI v1+) to json compatible format
14
14
  if hasattr(data, "model_dump"):
@@ -26,7 +26,6 @@ def _normalize_data(data):
26
26
  return data
27
27
 
28
28
 
29
- def set_data_normalized(span, key, value):
30
- # type: (Span, str, Any) -> None
29
+ def set_data_normalized(span: Span, key: str, value: Any) -> None:
31
30
  normalized = _normalize_data(value)
32
31
  span.set_attribute(key, normalized)