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.
- {sentry_sdk-2.39.0/sentry_sdk.egg-info → sentry_sdk-2.40.0}/PKG-INFO +3 -1
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/pyproject.toml +45 -38
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/client.py +6 -6
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/consts.py +12 -2
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/envelope.py +28 -14
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/feature_flags.py +0 -1
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/hub.py +17 -9
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/__init__.py +1 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/asgi.py +3 -2
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/dramatiq.py +89 -31
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/grpc/aio/client.py +2 -1
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/grpc/client.py +3 -4
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/langchain.py +0 -1
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/launchdarkly.py +0 -1
- sentry_sdk-2.40.0/sentry_sdk/integrations/litellm.py +251 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/litestar.py +4 -4
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/spans/ai_client.py +4 -1
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/utils.py +25 -1
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/pure_eval.py +3 -1
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/spark/spark_driver.py +2 -1
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/sqlalchemy.py +2 -6
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/starlette.py +1 -3
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/starlite.py +4 -4
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/wsgi.py +3 -2
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/metrics.py +17 -11
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/profiler/utils.py +2 -6
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/scope.py +6 -3
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/serializer.py +1 -3
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/session.py +4 -2
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/sessions.py +4 -2
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/tracing.py +36 -7
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/tracing_utils.py +1 -3
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/transport.py +8 -9
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/utils.py +5 -3
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0/sentry_sdk.egg-info}/PKG-INFO +3 -1
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk.egg-info/SOURCES.txt +1 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk.egg-info/requires.txt +3 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/setup.py +2 -1
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_basics.py +3 -3
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_client.py +4 -6
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_conftest.py +6 -2
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_gevent.py +2 -4
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_logs.py +2 -1
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_propagationcontext.py +1 -2
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_transport.py +2 -4
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_utils.py +3 -3
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/LICENSE +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/MANIFEST.in +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/README.md +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/__init__.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/_compat.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/_init_implementation.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/_log_batcher.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/_lru_cache.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/_queue.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/_types.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/_werkzeug.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/ai/__init__.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/ai/monitoring.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/ai/utils.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/api.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/attachments.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/crons/__init__.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/crons/api.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/crons/consts.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/crons/decorator.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/debug.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/_asgi_common.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/_wsgi_common.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/aiohttp.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/anthropic.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/argv.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/ariadne.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/arq.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/asyncio.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/asyncpg.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/atexit.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/aws_lambda.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/beam.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/boto3.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/bottle.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/celery/__init__.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/celery/beat.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/celery/utils.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/chalice.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/clickhouse_driver.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/cloud_resource_context.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/cohere.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/dedupe.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/django/__init__.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/django/asgi.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/django/caching.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/django/middleware.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/django/signals_handlers.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/django/templates.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/django/transactions.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/django/views.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/excepthook.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/executing.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/falcon.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/fastapi.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/flask.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/gcp.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/gnu_backtrace.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/gql.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/graphene.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/grpc/__init__.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/grpc/aio/__init__.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/grpc/aio/server.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/grpc/consts.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/grpc/server.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/httpx.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/huey.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/huggingface_hub.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/langgraph.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/logging.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/loguru.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/modules.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/__init__.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/consts.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/patches/__init__.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/patches/agent_run.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/patches/models.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/patches/runner.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/patches/tools.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/spans/__init__.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/spans/agent_workflow.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/spans/execute_tool.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/spans/handoff.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/openfeature.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/opentelemetry/__init__.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/opentelemetry/consts.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/opentelemetry/integration.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/opentelemetry/propagator.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/opentelemetry/span_processor.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/pymongo.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/pyramid.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/quart.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/ray.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/__init__.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/_async_common.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/_sync_common.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/consts.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/modules/__init__.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/modules/caches.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/modules/queries.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/rb.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/redis.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/redis_cluster.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/redis/utils.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/rq.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/rust_tracing.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/sanic.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/serverless.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/socket.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/spark/__init__.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/spark/spark_worker.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/statsig.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/stdlib.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/strawberry.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/sys_exit.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/threading.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/tornado.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/trytond.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/typer.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/unleash.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/integrations/unraisablehook.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/logger.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/monitor.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/profiler/__init__.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/profiler/continuous_profiler.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/profiler/transaction_profiler.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/py.typed +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/scrubber.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/spotlight.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/types.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk/worker.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk.egg-info/dependency_links.txt +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk.egg-info/entry_points.txt +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk.egg-info/not-zip-safe +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/sentry_sdk.egg-info/top_level.txt +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/setup.cfg +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_ai_monitoring.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_api.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_crons.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_dsc.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_envelope.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_exceptiongroup.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_feature_flags.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_full_stack_frames.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_import.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_lru_cache.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_metrics.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_monitor.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_scope.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_scrubber.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_serializer.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_sessions.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_spotlight.py +0 -0
- {sentry_sdk-2.39.0 → sentry_sdk-2.40.0}/tests/test_tracing_utils.py +0 -0
- {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.
|
|
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:
|
|
187
|
+
# Tool: Ruff (linting and formatting)
|
|
200
188
|
#
|
|
201
189
|
|
|
202
|
-
[tool.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
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
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
|
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,
|
|
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,
|
|
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.
|
|
1346
|
+
VERSION = "2.40.0"
|
|
@@ -57,25 +57,29 @@ class Envelope:
|
|
|
57
57
|
)
|
|
58
58
|
|
|
59
59
|
def add_event(
|
|
60
|
-
self,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
365
|
+
cls,
|
|
366
|
+
bytes, # type: bytes
|
|
353
367
|
):
|
|
354
368
|
# type: (...) -> Optional[Item]
|
|
355
369
|
return cls.deserialize_from(io.BytesIO(bytes))
|
|
@@ -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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
597
|
+
self,
|
|
598
|
+
session_mode="application", # type: str
|
|
591
599
|
):
|
|
592
600
|
# type: (...) -> None
|
|
593
601
|
"""
|
|
@@ -233,14 +233,15 @@ class SentryAsgiMiddleware:
|
|
|
233
233
|
if transaction:
|
|
234
234
|
transaction.set_tag("asgi.type", ty)
|
|
235
235
|
|
|
236
|
-
|
|
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.
|
|
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
|
-
|
|
13
|
-
from dramatiq.
|
|
14
|
-
from dramatiq.middleware import Middleware, default_middleware
|
|
15
|
-
from dramatiq.errors import Retry
|
|
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
|
-
|
|
89
|
-
|
|
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.
|
|
95
|
-
|
|
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
|
-
|
|
98
|
-
scope.
|
|
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,
|
|
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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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,
|
|
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,
|
|
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
|
|