Skip to content

Commit 0ea4a5f

Browse files
committed
feat(api): Add enable_integration
1 parent a979755 commit 0ea4a5f

File tree

4 files changed

+64
-0
lines changed

4 files changed

+64
-0
lines changed

sentry_sdk/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"capture_message",
2525
"configure_scope",
2626
"continue_trace",
27+
"enable_integration",
2728
"flush",
2829
"get_baggage",
2930
"get_client",

sentry_sdk/api.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from sentry_sdk import tracing_utils, Client
66
from sentry_sdk._init_implementation import init
7+
from sentry_sdk.integrations import Integration, _enable_integration
78
from sentry_sdk.consts import INSTRUMENTER
89
from sentry_sdk.scope import Scope, _ScopeManager, new_scope, isolation_scope
910
from sentry_sdk.tracing import NoOpSpan, Transaction, trace
@@ -57,6 +58,7 @@ def overload(x: "T") -> "T":
5758
"capture_message",
5859
"configure_scope",
5960
"continue_trace",
61+
"enable_integration",
6062
"flush",
6163
"get_baggage",
6264
"get_client",
@@ -523,3 +525,28 @@ def update_current_span(
523525

524526
if attributes is not None:
525527
current_span.update_data(attributes)
528+
529+
530+
def enable_integration(integration: Integration) -> None:
531+
"""
532+
Enable an additional integration after sentry_sdk.init() has been called.
533+
534+
This should be used sparingly, only in situations where, for whatever reason,
535+
it's not feasible to enable an integration during init().
536+
537+
Most integrations rely on being enabled before any actual user code is
538+
executed, and this function doesn't change that. enable_integration should
539+
still be called as early as possible.
540+
541+
One usecase for enable_integration is setting up the AsyncioIntegration only
542+
once the event loop is running, but without having to set up the whole SDK
543+
anew.
544+
545+
:param integration: The integration instance or class to enable.
546+
:type integration: sentry_sdk.integrations.Integration
547+
"""
548+
client = get_client()
549+
integration = _enable_integration(integration)
550+
if integration is None:
551+
return
552+
client.integrations[integration.identifier] = integration

sentry_sdk/integrations/__init__.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from threading import Lock
33
from typing import TYPE_CHECKING
44

5+
import sentry_sdk
56
from sentry_sdk.utils import logger
67

78
if TYPE_CHECKING:
@@ -279,6 +280,27 @@ def setup_integrations(
279280
return integrations
280281

281282

283+
def _enable_integration(integration: "Integration") -> None:
284+
if integration.identifier in _installed_integrations:
285+
return
286+
287+
client = sentry_sdk.get_client()
288+
289+
with _installer_lock:
290+
logger.debug(
291+
"Setting up previously not enabled integration %s", integration.identifier
292+
)
293+
_processed_integrations.add(integration.identifier)
294+
try:
295+
type(integration).setup_once()
296+
integration.setup_once_with_options(client.options)
297+
except DidNotEnable as e:
298+
logger.debug("Did not enable integration %s: %s", integration.identifier, e)
299+
else:
300+
_installed_integrations.add(integration.identifier)
301+
return integration
302+
303+
282304
def _check_minimum_version(
283305
integration: "type[Integration]",
284306
version: "Optional[tuple[int, ...]]",

tests/test_basics.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,20 @@ def test_multiple_setup_integrations_calls():
985985
assert second_call_return == {NoOpIntegration.identifier: NoOpIntegration()}
986986

987987

988+
def test_enable_integration(sentry_init):
989+
sentry_init()
990+
991+
client = get_client()
992+
assert "asyncio" not in client.integrations
993+
994+
from sentry_sdk.integrations import AsyncioIntegration
995+
996+
sentry_sdk.enable_integration(AsyncioIntegration())
997+
998+
client = get_client()
999+
assert "asyncio" in client.integrations
1000+
1001+
9881002
class TracingTestClass:
9891003
@staticmethod
9901004
def static(arg):

0 commit comments

Comments
 (0)