diff --git a/src/__init__.py b/htk/__init__.py similarity index 100% rename from src/__init__.py rename to htk/__init__.py diff --git a/src/__version__.py b/htk/__version__.py similarity index 100% rename from src/__version__.py rename to htk/__version__.py diff --git a/src/encoders/__init__.py b/htk/encoders/__init__.py similarity index 100% rename from src/encoders/__init__.py rename to htk/encoders/__init__.py diff --git a/src/settings.py b/htk/settings.py similarity index 100% rename from src/settings.py rename to htk/settings.py diff --git a/src/utils/__init__.py b/htk/utils/__init__.py similarity index 100% rename from src/utils/__init__.py rename to htk/utils/__init__.py diff --git a/src/utils/debuggers.py b/htk/utils/debuggers.py similarity index 100% rename from src/utils/debuggers.py rename to htk/utils/debuggers.py diff --git a/htk/utils/slack.py b/htk/utils/slack.py new file mode 100644 index 0000000..911f1ab --- /dev/null +++ b/htk/utils/slack.py @@ -0,0 +1,146 @@ +# Future Imports +from __future__ import absolute_import + +# Python Standard Library Imports +import json +import typing as T +from dataclasses import dataclass + +# Third Party (PyPI) Imports +import requests + +# Local Imports +from ..settings import SLACK_WEBHOOK_URL + + +@dataclass +class SlackMessage: + channel: T.Optional[str] = None + username: T.Optional[str] = None + text: str = '' + attachments: T.Optional[list] = None + icon_emoji: T.Optional[str] = None + unfurl_links: bool = True + unfurl_media: bool = True + thread_ts: T.Optional[str] = None + reply_broadcast: bool = False + + @property + def as_payload(self): + payload = { + 'text' : self.text, + 'unfurl_links' : self.unfurl_links, + 'unfurl_media' : self.unfurl_media, + } + + if self.channel: + payload['channel'] = self.channel + if self.username: + payload['username'] = self.username + if self.icon_emoji: + payload['icon_emoji'] = self.icon_emoji + if self.attachments: + payload['attachments'] = self.attachments + + if self.thread_ts is not None: + payload['thread_ts'] = self.thread_ts + payload['reply_broadcast'] = self.reply_broadcast + + return payload + + +def slack_message( + webhook_url: T.Optional[str]=SLACK_WEBHOOK_URL, + channel: T.Optional[str] = None, + username: T.Optional[str] = None, + text: str = '', + attachments: T.Optional[list] = None, + icon_emoji: T.Optional[str] = None, + unfurl_links: bool = True, + unfurl_media: bool = True, + thread_ts: T.Optional[str] = None, + reply_broadcast: bool = False, + error_response_handlers=None +) -> requests.Response: + """Wrapper around `send_webhook_message` + `SlackMessage` for legacy/backwards-compatibility. + + New implementations should directly use `send_webhook_message` or `send_message` + """ + return send_webhook_message( + message=SlackMessage( + channel=channel, + username=username, + text=text, + attachments=attachments, + icon_emoji=icon_emoji, + unfurl_links=unfurl_links, + unfurl_media=unfurl_media, + thread_ts=thread_ts, + reply_broadcast=reply_broadcast, + ), + webhook_url=webhook_url, + error_response_handlers=error_response_handlers + ) + + +def send_webhook_message( + message: SlackMessage, + webhook_url: str=SLACK_WEBHOOK_URL, + error_response_handlers=None +) -> requests.Response: + """Performs a webhook call to Slack to send a single message + + https://api.slack.com/incoming-webhooks + https://api.slack.com/docs/message-formatting + + `channel` override must be a public channel + + NOTE: Incoming webhooks is deprecated, and when possible, `send_message` should be used instead + """ + if webhook_url is None: + raise Exception('HTK_SLACK_WEBHOOK_URL or SLACK_WEBHOOK_URL not set in ENV') + + try: + response = requests.post(webhook_url, json=message.as_payload) + if response.status_code == 200: + # success case, do nothing + pass + elif response.status_code <= 399: + # 200-300, do nothing + pass + else: + print('Slack webhook call error: [{}] {}'.format(response.status_code, response.content)) + except (requests.exceptions.InvalidSchema, requests.exceptions.MissingSchema) as e: + raise Exception( + 'Bad Slack webhook URL: [{}] ({})'.format( + webhook_url, + e.__class__.__name__ + ) + ) + except: + raise + + return response + + +def send_message(message: SlackMessage, error_response_handlers=None) -> requests.Response: + pass + + +def send_messages_as_thread( + messages: T.List[SlackMessage], + error_response_handlers=None +): + """Sends a series of `SlackMessage` objects in a thread + + The first message is posted, then each message is posted subsequently in the thread of the first message. + """ + pass + + +__all__ = [ + 'SlackMessage', + 'send_webhook_message', + 'send_webhook_messages_as_thread', + 'slack_message', +] diff --git a/src/utils/validate_emails_csv.py b/htk/utils/validate_emails_csv.py similarity index 100% rename from src/utils/validate_emails_csv.py rename to htk/utils/validate_emails_csv.py diff --git a/setup.py b/setup.py index 024ba51..8950ecb 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ about = {} -with open(os.path.join(here, 'src', '__version__.py'), 'r', 'utf-8') as f: +with open(os.path.join(here, 'htk', '__version__.py'), 'r', 'utf-8') as f: exec(f.read(), about) @@ -112,7 +112,7 @@ #'sample': ['package_data.dat'], }, package_dir={ - 'htk': 'src', + 'htk': 'htk', }, # Although 'package_data' is the preferred approach, in some case you may diff --git a/src/utils/slack.py b/src/utils/slack.py deleted file mode 100644 index bde8d02..0000000 --- a/src/utils/slack.py +++ /dev/null @@ -1,75 +0,0 @@ -# Future Imports -from __future__ import absolute_import - -# Python Standard Library Imports -import json - -# Third Party (PyPI) Imports -import requests - -# Local Imports -from ..settings import SLACK_WEBHOOK_URL - - -def slack_message( - webhook_url=SLACK_WEBHOOK_URL, - channel=None, - username=None, - text='', - attachments=None, - icon_emoji=None, - unfurl_links=True, - unfurl_media=True, - error_response_handlers=None -): - """Performs a webhook call to Slack - - https://api.slack.com/incoming-webhooks - https://api.slack.com/docs/message-formatting - - `channel` override must be a public channel - """ - if webhook_url is None: - raise Exception('HTK_SLACK_WEBHOOK_URL or SLACK_WEBHOOK_URL not set in ENV') - - payload = { - 'text' : text, - 'unfurl_links' : unfurl_links, - 'unfurl_media' : unfurl_media, - } - - if channel: - payload['channel'] = channel - if username: - payload['username'] = username - if icon_emoji: - payload['icon_emoji'] = icon_emoji - if attachments: - payload['attachments'] = attachments - - try: - response = requests.post(webhook_url, json=payload) - if response.status_code == 200: - # success case, do nothing - pass - elif response.status_code <= 399: - # 200-300, do nothing - pass - else: - print('Slack webhook call error: [{}] {}'.format(response.status_code, response.content)) - except (requests.exceptions.InvalidSchema, requests.exceptions.MissingSchema) as e: - raise Exception( - 'Bad Slack webhook URL: [{}] ({})'.format( - webhook_url, - e.__class__.__name__ - ) - ) - except: - raise - - return response - - -__all__ = [ - 'slack_message', -]