Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/sentry_sdk/integrations/__init__.py: 78%

70 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1"""This package""" 

2from __future__ import absolute_import 

3 

4from threading import Lock 

5 

6from sentry_sdk._compat import iteritems 

7from sentry_sdk.utils import logger 

8 

9from sentry_sdk._types import MYPY 

10 

11if MYPY: 11 ↛ 12line 11 didn't jump to line 12, because the condition on line 11 was never true

12 from typing import Callable 

13 from typing import Dict 

14 from typing import Iterator 

15 from typing import List 

16 from typing import Set 

17 from typing import Tuple 

18 from typing import Type 

19 

20 

21_installer_lock = Lock() 

22_installed_integrations = set() # type: Set[str] 

23 

24 

25def _generate_default_integrations_iterator(integrations, auto_enabling_integrations): 

26 # type: (Tuple[str, ...], Tuple[str, ...]) -> Callable[[bool], Iterator[Type[Integration]]] 

27 

28 def iter_default_integrations(with_auto_enabling_integrations): 

29 # type: (bool) -> Iterator[Type[Integration]] 

30 """Returns an iterator of the default integration classes:""" 

31 from importlib import import_module 

32 

33 if with_auto_enabling_integrations: 33 ↛ 36line 33 didn't jump to line 36, because the condition on line 33 was never false

34 all_import_strings = integrations + auto_enabling_integrations 

35 else: 

36 all_import_strings = integrations 

37 

38 for import_string in all_import_strings: 

39 try: 

40 module, cls = import_string.rsplit(".", 1) 

41 yield getattr(import_module(module), cls) 

42 except (DidNotEnable, SyntaxError) as e: 

43 logger.debug( 

44 "Did not import default integration %s: %s", import_string, e 

45 ) 

46 

47 if isinstance(iter_default_integrations.__doc__, str): 47 ↛ 51line 47 didn't jump to line 51, because the condition on line 47 was never false

48 for import_string in integrations: 

49 iter_default_integrations.__doc__ += "\n- `{}`".format(import_string) 

50 

51 return iter_default_integrations 

52 

53 

54_AUTO_ENABLING_INTEGRATIONS = ( 

55 "sentry_sdk.integrations.django.DjangoIntegration", 

56 "sentry_sdk.integrations.flask.FlaskIntegration", 

57 "sentry_sdk.integrations.bottle.BottleIntegration", 

58 "sentry_sdk.integrations.falcon.FalconIntegration", 

59 "sentry_sdk.integrations.sanic.SanicIntegration", 

60 "sentry_sdk.integrations.celery.CeleryIntegration", 

61 "sentry_sdk.integrations.rq.RqIntegration", 

62 "sentry_sdk.integrations.aiohttp.AioHttpIntegration", 

63 "sentry_sdk.integrations.tornado.TornadoIntegration", 

64 "sentry_sdk.integrations.sqlalchemy.SqlalchemyIntegration", 

65 "sentry_sdk.integrations.redis.RedisIntegration", 

66 "sentry_sdk.integrations.pyramid.PyramidIntegration", 

67 "sentry_sdk.integrations.boto3.Boto3Integration", 

68) 

69 

70 

71iter_default_integrations = _generate_default_integrations_iterator( 

72 integrations=( 

73 # stdlib/base runtime integrations 

74 "sentry_sdk.integrations.logging.LoggingIntegration", 

75 "sentry_sdk.integrations.stdlib.StdlibIntegration", 

76 "sentry_sdk.integrations.excepthook.ExcepthookIntegration", 

77 "sentry_sdk.integrations.dedupe.DedupeIntegration", 

78 "sentry_sdk.integrations.atexit.AtexitIntegration", 

79 "sentry_sdk.integrations.modules.ModulesIntegration", 

80 "sentry_sdk.integrations.argv.ArgvIntegration", 

81 "sentry_sdk.integrations.threading.ThreadingIntegration", 

82 ), 

83 auto_enabling_integrations=_AUTO_ENABLING_INTEGRATIONS, 

84) 

85 

86del _generate_default_integrations_iterator 

87 

88 

89def setup_integrations( 

90 integrations, with_defaults=True, with_auto_enabling_integrations=False 

91): 

92 # type: (List[Integration], bool, bool) -> Dict[str, Integration] 

93 """Given a list of integration instances this installs them all. When 

94 `with_defaults` is set to `True` then all default integrations are added 

95 unless they were already provided before. 

96 """ 

97 integrations = dict( 

98 (integration.identifier, integration) for integration in integrations or () 

99 ) 

100 

101 logger.debug("Setting up integrations (with default = %s)", with_defaults) 

102 

103 # Integrations that are not explicitly set up by the user. 

104 used_as_default_integration = set() 

105 

106 if with_defaults: 106 ↛ 115line 106 didn't jump to line 115, because the condition on line 106 was never false

107 for integration_cls in iter_default_integrations( 

108 with_auto_enabling_integrations 

109 ): 

110 if integration_cls.identifier not in integrations: 

111 instance = integration_cls() 

112 integrations[instance.identifier] = instance 

113 used_as_default_integration.add(instance.identifier) 

114 

115 for identifier, integration in iteritems(integrations): 

116 with _installer_lock: 

117 if identifier not in _installed_integrations: 117 ↛ 115line 117 didn't jump to line 115, because the condition on line 117 was never false

118 logger.debug( 

119 "Setting up previously not enabled integration %s", identifier 

120 ) 

121 try: 

122 type(integration).setup_once() 

123 except NotImplementedError: 123 ↛ 124line 123 didn't jump to line 124, because the exception caught by line 123 didn't happen

124 if getattr(integration, "install", None) is not None: 

125 logger.warning( 

126 "Integration %s: The install method is " 

127 "deprecated. Use `setup_once`.", 

128 identifier, 

129 ) 

130 integration.install() 

131 else: 

132 raise 

133 except DidNotEnable as e: 

134 if identifier not in used_as_default_integration: 134 ↛ 135line 134 didn't jump to line 135, because the condition on line 134 was never true

135 raise 

136 

137 logger.debug( 

138 "Did not enable default integration %s: %s", identifier, e 

139 ) 

140 

141 _installed_integrations.add(identifier) 

142 

143 for identifier in integrations: 

144 logger.debug("Enabling integration %s", identifier) 

145 

146 return integrations 

147 

148 

149class DidNotEnable(Exception): # noqa: N818 

150 """ 

151 The integration could not be enabled due to a trivial user error like 

152 `flask` not being installed for the `FlaskIntegration`. 

153 

154 This exception is silently swallowed for default integrations, but reraised 

155 for explicitly enabled integrations. 

156 """ 

157 

158 

159class Integration(object): 

160 """Baseclass for all integrations. 

161 

162 To accept options for an integration, implement your own constructor that 

163 saves those options on `self`. 

164 """ 

165 

166 install = None 

167 """Legacy method, do not implement.""" 

168 

169 identifier = None # type: str 

170 """String unique ID of integration type""" 

171 

172 @staticmethod 

173 def setup_once(): 

174 # type: () -> None 

175 """ 

176 Initialize the integration. 

177 

178 This function is only called once, ever. Configuration is not available 

179 at this point, so the only thing to do here is to hook into exception 

180 handlers, and perhaps do monkeypatches. 

181 

182 Inside those hooks `Integration.current` can be used to access the 

183 instance again. 

184 """ 

185 raise NotImplementedError()