1+ from __future__ import annotations
2+
13import json
24import ssl
35from abc import ABC , abstractmethod
4- from typing import Dict , List , Optional , Tuple , Union
6+ from typing import TYPE_CHECKING , Dict , List , Optional , Tuple , Union
7+
8+ if TYPE_CHECKING :
9+ from slack_sdk .errors import SlackApiError
10+ from slack_sdk .webhook import WebhookResponse
511
612import requests
713from ratelimit import limits , sleep_and_retry
8- from slack_sdk import WebClient , WebhookClient
9- from slack_sdk .errors import SlackApiError
10- from slack_sdk .http_retry .builtin_handlers import RateLimitErrorRetryHandler
11- from slack_sdk .webhook .webhook_response import WebhookResponse
1214
1315from elementary .clients .slack .schema import SlackMessageSchema
1416from elementary .config .config import Config
1517from elementary .tracking .tracking_interface import Tracking
18+ from elementary .utils .deps import import_optional_dependency
1619from elementary .utils .log import get_logger
1720from elementary .utils .ssl import create_ssl_context
1821
@@ -59,7 +62,10 @@ def _initial_client(self, ssl_context: Optional[ssl.SSLContext]):
5962 raise NotImplementedError
6063
6164 def _initial_retry_handlers (self ):
62- if isinstance (self .client , WebClient ):
65+ slack_sdk = import_optional_dependency ("slack_sdk" , "slack" )
66+ if isinstance (self .client , slack_sdk .WebClient ):
67+ from slack_sdk .http_retry .builtin_handlers import RateLimitErrorRetryHandler
68+
6369 rate_limit_handler = RateLimitErrorRetryHandler (max_retry_count = 5 )
6470 self .client .retry_handlers .append (rate_limit_handler )
6571
@@ -96,13 +102,16 @@ def __init__(
96102 super ().__init__ (tracking , ssl_context )
97103
98104 def _initial_client (self , ssl_context : Optional [ssl .SSLContext ]):
99- return WebClient (token = self .token , ssl = ssl_context )
105+ slack_sdk = import_optional_dependency ("slack_sdk" , "slack" )
106+ return slack_sdk .WebClient (token = self .token , ssl = ssl_context )
100107
101108 @sleep_and_retry
102109 @limits (calls = 1 , period = ONE_SECOND )
103110 def send_message (
104111 self , channel_name : str , message : SlackMessageSchema , ** kwargs
105112 ) -> bool :
113+ from slack_sdk .errors import SlackApiError
114+
106115 try :
107116 self .client .chat_postMessage (
108117 channel = channel_name ,
@@ -128,6 +137,8 @@ def send_file(
128137 file_path : str ,
129138 message : Optional [SlackMessageSchema ] = None ,
130139 ) -> bool :
140+ from slack_sdk .errors import SlackApiError
141+
131142 channel_id = self ._get_channel_id (channel_name )
132143 try :
133144 self .client .files_upload_v2 (
@@ -157,6 +168,8 @@ def send_report(self, channel_name: str, report_file_path: str):
157168 @sleep_and_retry
158169 @limits (calls = 50 , period = ONE_MINUTE )
159170 def get_user_id_from_email (self , email : str ) -> Optional [str ]:
171+ from slack_sdk .errors import SlackApiError
172+
160173 try :
161174 if email not in self .email_to_user_id_cache :
162175 user_id = self .client .users_lookupByEmail (email = email )["user" ]["id" ]
@@ -197,6 +210,8 @@ def _get_channel_id(self, channel_name: str) -> Optional[str]:
197210 return None
198211
199212 def _join_channel (self , channel_id : str ) -> bool :
213+ from slack_sdk .errors import SlackApiError
214+
200215 try :
201216 self .client .conversations_join (channel = channel_id )
202217 logger .info ("Elementary app joined the channel successfully." )
@@ -249,7 +264,8 @@ def _initial_client(self, ssl_context: Optional[ssl.SSLContext]):
249264 # requests.Session() uses the requests default CA bundle (certifi).
250265 return requests .Session ()
251266
252- return WebhookClient (
267+ slack_sdk = import_optional_dependency ("slack_sdk" , "slack" )
268+ return slack_sdk .WebhookClient (
253269 url = self .webhook ,
254270 default_headers = {"Content-type" : "application/json" },
255271 ssl = ssl_context ,
0 commit comments