From e558f17098e7cfe5d1c19b3c9911acf24c7b4414 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 5 Oct 2022 13:04:00 +0200 Subject: [PATCH 1/6] Made SDK name dynamic --- sentry_sdk/consts.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index ceba6b512e..19981c81fd 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -104,9 +104,17 @@ def _get_default_options(): del _get_default_options +def _get_sdk_name(): + return "sentry.python" + + +SDK_NAME = _get_sdk_name() +del _get_sdk_name + + VERSION = "1.9.10" SDK_INFO = { - "name": "sentry.python", + "name": SDK_NAME, "version": VERSION, "packages": [{"name": "pypi:sentry-sdk", "version": VERSION}], } From cfcfc6141e8176794a38673acd5fb68e0b9a5527 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 5 Oct 2022 14:48:34 +0200 Subject: [PATCH 2/6] Include framework name in SDK name --- sentry_sdk/client.py | 12 +++++++- sentry_sdk/consts.py | 38 +++++++++++++++++++++---- tests/test_basics.py | 67 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 7 deletions(-) diff --git a/sentry_sdk/client.py b/sentry_sdk/client.py index 06923c501b..260a5eb7f2 100644 --- a/sentry_sdk/client.py +++ b/sentry_sdk/client.py @@ -17,7 +17,12 @@ ) from sentry_sdk.serializer import serialize from sentry_sdk.transport import make_transport -from sentry_sdk.consts import DEFAULT_OPTIONS, SDK_INFO, ClientConstructor +from sentry_sdk.consts import ( + DEFAULT_OPTIONS, + SDK_INFO, + ClientConstructor, + _get_sdk_name, +) from sentry_sdk.integrations import setup_integrations from sentry_sdk.utils import ContextVar from sentry_sdk.sessions import SessionFlusher @@ -128,6 +133,11 @@ def _capture_envelope(envelope): "auto_enabling_integrations" ], ) + + sdk_name = _get_sdk_name(list(self.integrations.keys())) + SDK_INFO["name"] = sdk_name + logger.debug("Setting SDK name to '%s'", sdk_name) + finally: _client_init_debug.set(old_debug) diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index 19981c81fd..5c6180e10a 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -104,17 +104,43 @@ def _get_default_options(): del _get_default_options -def _get_sdk_name(): - return "sentry.python" - +def _get_sdk_name(installed_integrations): + # type: (list[str]) -> str + """Return the SDK name including the name of the used web framework.""" + + # Note: I can not use for example sentry_sdk.integrations.django.DjangoIntegration.identifier + # here because if django is not installed the integration is not accessible. + framework_integrations = [ + "django", + "flask", + "fastapi", + "bottle", + "falcon", + "quart", + "sanic", + "starlette", + "chalice", + "serverless", + "pyramid", + "tornado", + "aiohttp", + "aws_lambda", + "gcp", + "beam", + "asgi", + "wsgi", + ] + + for integration in framework_integrations: + if integration in installed_integrations: + return "sentry.python.{}".format(integration) -SDK_NAME = _get_sdk_name() -del _get_sdk_name + return "sentry.python" VERSION = "1.9.10" SDK_INFO = { - "name": SDK_NAME, + "name": "sentry.python", # SDK name be overridden after integrations have been loaded with sentry_sdk.integrations.setup_integrations() "version": VERSION, "packages": [{"name": "pypi:sentry-sdk", "version": VERSION}], } diff --git a/tests/test_basics.py b/tests/test_basics.py index 1e2feaff14..74f955d373 100644 --- a/tests/test_basics.py +++ b/tests/test_basics.py @@ -18,6 +18,7 @@ ) from sentry_sdk._compat import reraise +from sentry_sdk.consts import _get_sdk_name from sentry_sdk.integrations import _AUTO_ENABLING_INTEGRATIONS from sentry_sdk.integrations.logging import LoggingIntegration from sentry_sdk.scope import ( # noqa: F401 @@ -437,3 +438,69 @@ def foo(event, hint): assert reports == [("event_processor", "error"), ("event_processor", "transaction")] global_event_processors.pop() + + +@pytest.mark.parametrize( + "installed_integrations, expected_name", + [ + # integrations with own name + (["django"], "sentry.python.django"), + (["flask"], "sentry.python.flask"), + (["fastapi"], "sentry.python.fastapi"), + (["bottle"], "sentry.python.bottle"), + (["falcon"], "sentry.python.falcon"), + (["quart"], "sentry.python.quart"), + (["sanic"], "sentry.python.sanic"), + (["starlette"], "sentry.python.starlette"), + (["chalice"], "sentry.python.chalice"), + (["serverless"], "sentry.python.serverless"), + (["pyramid"], "sentry.python.pyramid"), + (["tornado"], "sentry.python.tornado"), + (["aiohttp"], "sentry.python.aiohttp"), + (["aws_lambda"], "sentry.python.aws_lambda"), + (["gcp"], "sentry.python.gcp"), + (["beam"], "sentry.python.beam"), + (["asgi"], "sentry.python.asgi"), + (["wsgi"], "sentry.python.wsgi"), + # integrations without name + (["argv"], "sentry.python"), + (["atexit"], "sentry.python"), + (["boto3"], "sentry.python"), + (["celery"], "sentry.python"), + (["dedupe"], "sentry.python"), + (["excepthook"], "sentry.python"), + (["executing"], "sentry.python"), + (["modules"], "sentry.python"), + (["pure_eval"], "sentry.python"), + (["redis"], "sentry.python"), + (["rq"], "sentry.python"), + (["sqlalchemy"], "sentry.python"), + (["stdlib"], "sentry.python"), + (["threading"], "sentry.python"), + (["trytond"], "sentry.python"), + (["logging"], "sentry.python"), + (["gnu_backtrace"], "sentry.python"), + (["httpx"], "sentry.python"), + # precedence of frameworks + (["flask", "django", "celery"], "sentry.python.django"), + (["fastapi", "flask", "redis"], "sentry.python.flask"), + (["bottle", "fastapi", "httpx"], "sentry.python.fastapi"), + (["falcon", "bottle", "logging"], "sentry.python.bottle"), + (["quart", "falcon", "gnu_backtrace"], "sentry.python.falcon"), + (["sanic", "quart", "sqlalchemy"], "sentry.python.quart"), + (["starlette", "sanic", "rq"], "sentry.python.sanic"), + (["chalice", "starlette", "modules"], "sentry.python.starlette"), + (["serverless", "chalice", "pure_eval"], "sentry.python.chalice"), + (["pyramid", "serverless", "modules"], "sentry.python.serverless"), + (["tornado", "pyramid", "executing"], "sentry.python.pyramid"), + (["aiohttp", "tornado", "dedupe"], "sentry.python.tornado"), + (["aws_lambda", "aiohttp", "boto3"], "sentry.python.aiohttp"), + (["gcp", "aws_lambda", "atexit"], "sentry.python.aws_lambda"), + (["beam", "gcp", "argv"], "sentry.python.gcp"), + (["asgi", "beam", "stdtlib"], "sentry.python.beam"), + (["wsgi", "asgi", "boto3"], "sentry.python.asgi"), + (["wsgi", "celery", "redis"], "sentry.python.wsgi"), + ], +) +def test_get_sdk_name(installed_integrations, expected_name): + assert _get_sdk_name(installed_integrations) == expected_name From 93d8f8e3ac24e6d1ebb518b5ab63eb09ef34731b Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 5 Oct 2022 14:56:34 +0200 Subject: [PATCH 3/6] Fixed typing --- sentry_sdk/consts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index 5c6180e10a..f97ecc8a6a 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -105,7 +105,7 @@ def _get_default_options(): def _get_sdk_name(installed_integrations): - # type: (list[str]) -> str + # type: (List[str]) -> str """Return the SDK name including the name of the used web framework.""" # Note: I can not use for example sentry_sdk.integrations.django.DjangoIntegration.identifier From 946491c4ae338d670dbee4898c5114712b69d627 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Mon, 10 Oct 2022 09:21:05 +0200 Subject: [PATCH 4/6] Moved SDK_INFO to client.py because its not constant anymore --- sentry_sdk/client.py | 9 ++++++++- sentry_sdk/consts.py | 5 ----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/sentry_sdk/client.py b/sentry_sdk/client.py index 260a5eb7f2..d00fa83e9b 100644 --- a/sentry_sdk/client.py +++ b/sentry_sdk/client.py @@ -19,7 +19,7 @@ from sentry_sdk.transport import make_transport from sentry_sdk.consts import ( DEFAULT_OPTIONS, - SDK_INFO, + VERSION, ClientConstructor, _get_sdk_name, ) @@ -46,6 +46,13 @@ _client_init_debug = ContextVar("client_init_debug") +SDK_INFO = { + "name": "sentry.python", # SDK name be overridden after integrations have been loaded with sentry_sdk.integrations.setup_integrations() + "version": VERSION, + "packages": [{"name": "pypi:sentry-sdk", "version": VERSION}], +} + + def _get_options(*args, **kwargs): # type: (*Optional[str], **Any) -> Dict[str, Any] if args and (isinstance(args[0], (text_type, bytes, str)) or args[0] is None): diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index f97ecc8a6a..68ad48b484 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -139,8 +139,3 @@ def _get_sdk_name(installed_integrations): VERSION = "1.9.10" -SDK_INFO = { - "name": "sentry.python", # SDK name be overridden after integrations have been loaded with sentry_sdk.integrations.setup_integrations() - "version": VERSION, - "packages": [{"name": "pypi:sentry-sdk", "version": VERSION}], -} From f09ed0a61d411a8f7c54e93977ecc362bc2568d2 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Mon, 10 Oct 2022 14:04:41 +0200 Subject: [PATCH 5/6] Cleanup --- sentry_sdk/client.py | 38 ++++++++++++++++++++++++++++++++++++-- sentry_sdk/consts.py | 34 ---------------------------------- tests/test_basics.py | 2 +- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/sentry_sdk/client.py b/sentry_sdk/client.py index d00fa83e9b..1da52e83e2 100644 --- a/sentry_sdk/client.py +++ b/sentry_sdk/client.py @@ -21,7 +21,6 @@ DEFAULT_OPTIONS, VERSION, ClientConstructor, - _get_sdk_name, ) from sentry_sdk.integrations import setup_integrations from sentry_sdk.utils import ContextVar @@ -36,6 +35,7 @@ from typing import Any from typing import Callable from typing import Dict + from typing import List from typing import Optional from sentry_sdk.scope import Scope @@ -47,12 +47,46 @@ SDK_INFO = { - "name": "sentry.python", # SDK name be overridden after integrations have been loaded with sentry_sdk.integrations.setup_integrations() + "name": "sentry.python", # SDK name will be overridden after integrations have been loaded with sentry_sdk.integrations.setup_integrations() "version": VERSION, "packages": [{"name": "pypi:sentry-sdk", "version": VERSION}], } +def _get_sdk_name(installed_integrations): + # type: (List[str]) -> str + """Return the SDK name including the name of the used web framework.""" + + # Note: I can not use for example sentry_sdk.integrations.django.DjangoIntegration.identifier + # here because if django is not installed the integration is not accessible. + framework_integrations = [ + "django", + "flask", + "fastapi", + "bottle", + "falcon", + "quart", + "sanic", + "starlette", + "chalice", + "serverless", + "pyramid", + "tornado", + "aiohttp", + "aws_lambda", + "gcp", + "beam", + "asgi", + "wsgi", + ] + + for integration in framework_integrations: + if integration in installed_integrations: + return "sentry.python.{}".format(integration) + + return "sentry.python" + + def _get_options(*args, **kwargs): # type: (*Optional[str], **Any) -> Dict[str, Any] if args and (isinstance(args[0], (text_type, bytes, str)) or args[0] is None): diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index 68ad48b484..44837404b2 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -104,38 +104,4 @@ def _get_default_options(): del _get_default_options -def _get_sdk_name(installed_integrations): - # type: (List[str]) -> str - """Return the SDK name including the name of the used web framework.""" - - # Note: I can not use for example sentry_sdk.integrations.django.DjangoIntegration.identifier - # here because if django is not installed the integration is not accessible. - framework_integrations = [ - "django", - "flask", - "fastapi", - "bottle", - "falcon", - "quart", - "sanic", - "starlette", - "chalice", - "serverless", - "pyramid", - "tornado", - "aiohttp", - "aws_lambda", - "gcp", - "beam", - "asgi", - "wsgi", - ] - - for integration in framework_integrations: - if integration in installed_integrations: - return "sentry.python.{}".format(integration) - - return "sentry.python" - - VERSION = "1.9.10" diff --git a/tests/test_basics.py b/tests/test_basics.py index 74f955d373..d76ed59178 100644 --- a/tests/test_basics.py +++ b/tests/test_basics.py @@ -18,7 +18,7 @@ ) from sentry_sdk._compat import reraise -from sentry_sdk.consts import _get_sdk_name +from sentry_sdk.client import _get_sdk_name from sentry_sdk.integrations import _AUTO_ENABLING_INTEGRATIONS from sentry_sdk.integrations.logging import LoggingIntegration from sentry_sdk.scope import ( # noqa: F401 From ee09dcc84805e69ec52010920fe092f1f954c048 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Mon, 10 Oct 2022 14:09:07 +0200 Subject: [PATCH 6/6] Cleanup --- sentry_sdk/client.py | 38 ++------------------------------------ sentry_sdk/utils.py | 34 ++++++++++++++++++++++++++++++++++ tests/test_basics.py | 4 ++-- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/sentry_sdk/client.py b/sentry_sdk/client.py index 3519ace16b..02741a2f10 100644 --- a/sentry_sdk/client.py +++ b/sentry_sdk/client.py @@ -10,6 +10,7 @@ current_stacktrace, disable_capture_event, format_timestamp, + get_sdk_name, get_type_name, get_default_release, handle_in_app, @@ -35,7 +36,6 @@ from typing import Any from typing import Callable from typing import Dict - from typing import List from typing import Optional from sentry_sdk.scope import Scope @@ -53,40 +53,6 @@ } -def _get_sdk_name(installed_integrations): - # type: (List[str]) -> str - """Return the SDK name including the name of the used web framework.""" - - # Note: I can not use for example sentry_sdk.integrations.django.DjangoIntegration.identifier - # here because if django is not installed the integration is not accessible. - framework_integrations = [ - "django", - "flask", - "fastapi", - "bottle", - "falcon", - "quart", - "sanic", - "starlette", - "chalice", - "serverless", - "pyramid", - "tornado", - "aiohttp", - "aws_lambda", - "gcp", - "beam", - "asgi", - "wsgi", - ] - - for integration in framework_integrations: - if integration in installed_integrations: - return "sentry.python.{}".format(integration) - - return "sentry.python" - - def _get_options(*args, **kwargs): # type: (*Optional[str], **Any) -> Dict[str, Any] if args and (isinstance(args[0], (text_type, bytes, str)) or args[0] is None): @@ -175,7 +141,7 @@ def _capture_envelope(envelope): ], ) - sdk_name = _get_sdk_name(list(self.integrations.keys())) + sdk_name = get_sdk_name(list(self.integrations.keys())) SDK_INFO["name"] = sdk_name logger.debug("Setting SDK name to '%s'", sdk_name) diff --git a/sentry_sdk/utils.py b/sentry_sdk/utils.py index 5e74885b32..9b970a307d 100644 --- a/sentry_sdk/utils.py +++ b/sentry_sdk/utils.py @@ -95,6 +95,40 @@ def get_default_release(): return None +def get_sdk_name(installed_integrations): + # type: (List[str]) -> str + """Return the SDK name including the name of the used web framework.""" + + # Note: I can not use for example sentry_sdk.integrations.django.DjangoIntegration.identifier + # here because if django is not installed the integration is not accessible. + framework_integrations = [ + "django", + "flask", + "fastapi", + "bottle", + "falcon", + "quart", + "sanic", + "starlette", + "chalice", + "serverless", + "pyramid", + "tornado", + "aiohttp", + "aws_lambda", + "gcp", + "beam", + "asgi", + "wsgi", + ] + + for integration in framework_integrations: + if integration in installed_integrations: + return "sentry.python.{}".format(integration) + + return "sentry.python" + + class CaptureInternalException(object): __slots__ = () diff --git a/tests/test_basics.py b/tests/test_basics.py index d76ed59178..8657231fc9 100644 --- a/tests/test_basics.py +++ b/tests/test_basics.py @@ -18,13 +18,13 @@ ) from sentry_sdk._compat import reraise -from sentry_sdk.client import _get_sdk_name from sentry_sdk.integrations import _AUTO_ENABLING_INTEGRATIONS from sentry_sdk.integrations.logging import LoggingIntegration from sentry_sdk.scope import ( # noqa: F401 add_global_event_processor, global_event_processors, ) +from sentry_sdk.utils import get_sdk_name def test_processors(sentry_init, capture_events): @@ -503,4 +503,4 @@ def foo(event, hint): ], ) def test_get_sdk_name(installed_integrations, expected_name): - assert _get_sdk_name(installed_integrations) == expected_name + assert get_sdk_name(installed_integrations) == expected_name