diff --git a/CHANGELOG.md b/CHANGELOG.md index 923350d..73b97d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.9.5- 2021-09-10] +## [0.9.6- 2021-09-10] + +### Fixed +- Update SlackReport to use current API. ### Added -- Backtesting notebook example. +- Add client_token to SlackReport init. ## [0.9.4- 2021-08-17] @@ -256,7 +259,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.2.0] - 2021-03-15 ### Added -- Prophet model wrapper. +- Prophet model wrapper from `pomopt` project. - `add_future_dates` utils to add prediction dates onto time_series DataFrames. - New tests for `Forecaster` module. diff --git a/soam/reporting/slack_report.py b/soam/reporting/slack_report.py index 56bcf12..1e0bc6a 100644 --- a/soam/reporting/slack_report.py +++ b/soam/reporting/slack_report.py @@ -31,13 +31,12 @@ class SlackReport: Generates the report to share via Slack. """ - warnings.warn( - "This class will be deprecated in v1. Using SlackMessage and send_slack_message methods instead is recommended.", - PendingDeprecationWarning, - ) - def __init__( - self, channel_id: str, metric_name: str, setting_path: Optional[str], + self, + channel_id: str, + metric_name: str, + setting_path: Optional[str] = None, + client_token: Optional[str] = None, ): """ Initialization of the Slack Report object. @@ -51,7 +50,15 @@ def __init__( setting_path: str Setting path. """ - credentials = get_slack_cred(setting_path) + if setting_path and client_token: + raise ValueError("Either setting_path or client_token should be provided") + if setting_path: + credentials = get_slack_cred(setting_path) + elif client_token: + credentials = {"token": client_token} + else: + raise TypeError("Either setting_path or client_token must be provided.") + self.slack_client = slack.WebClient(credentials["token"]) self.channel_id = channel_id self.metric_name = metric_name @@ -85,23 +92,41 @@ def send_report( if greeting_message == DEFAULT_GREETING_MESSAGE: greeting_message.format(metric_name=self.metric_name) + if isinstance(plot_filename, str): + plot_filename = Path(plot_filename) + prediction[f"{YHAT_COL}_str"] = prediction[YHAT_COL].apply( lambda f: "{:.2f}".format(f) # pylint: disable=unnecessary-lambda ) - summary_message = _df_to_report_string( - prediction, - DS_COL, - f"{YHAT_COL}_str", - greeting_message=greeting_message, - farewell_message=farewell_message, - ) - prediction = prediction.drop(columns=[f"{YHAT_COL}_str"]) - return self.slack_client.files_upload( - channels=self.channel_id, - file=str(plot_filename), - initial_comment=summary_message, - title=f"{self.metric_name} Forecast", + if len(prediction) == 0: + msg = SlackMessage( + greeting_message, + attachment=plot_filename, + title=f"{self.metric_name} Forecast", + ) + else: + summary_message = _df_to_report_string( + prediction, + DS_COL, + f"{YHAT_COL}_str", + greeting_message=greeting_message, + farewell_message=farewell_message, + ) + prediction = prediction.drop(columns=[f"{YHAT_COL}_str"]) + + msg = SlackMessage( + summary_message, + arguments={ + "detection_window": len(prediction), + "metric_name": self.metric_name, + }, + attachment=plot_filename, + title=f"{self.metric_name} Forecast", + ) + + return send_slack_message( + slack_client=self.slack_client, channel=self.channel_id, msg=msg ) @@ -176,6 +201,7 @@ def __init__( template, arguments: Dict = None, attachment: Optional[Union[Path, IO]] = None, + title: Optional[str] = '', ): """Create Slack message. @@ -187,6 +213,7 @@ def __init__( self.template = template self.arguments = arguments self.attachment_ref = attachment + self.title = title @property def message(self) -> str: diff --git a/tests/integration/test_integration.py b/tests/integration/test_integration.py index 41d60ea..5fb460e 100644 --- a/tests/integration/test_integration.py +++ b/tests/integration/test_integration.py @@ -219,6 +219,6 @@ def test_integration_forecast_and_report( channels="channel_id", file=plot_filename, initial_comment=expected_msg, - title="mae Forecast", + thread_ts=None, ) assert_saved_data(tmp_path, test_run_name) diff --git a/tests/reporting/test_slack_report.py b/tests/reporting/test_slack_report.py index 35c2189..d28f15c 100644 --- a/tests/reporting/test_slack_report.py +++ b/tests/reporting/test_slack_report.py @@ -50,7 +50,7 @@ def test_send_slack_message_no_attachment(): template_params = dict(user="test", version="0.1.0") slack_msg = SlackMessage(SLACK_MSG_TEMPLATE, arguments=template_params) test_channel = "test" - send_slack_message(client_mock, channel=test_channel, msg=slack_msg) + send_slack_message(slack_client=client_mock, channel=test_channel, msg=slack_msg) client_mock.chat_postMessage.assert_called_once_with( channel=test_channel, text=slack_msg.message, thread_ts=None ) @@ -66,7 +66,7 @@ def test_send_slack_message_with_path_attachment(tmp_path): SLACK_MSG_TEMPLATE, arguments=template_params, attachment=temp_file ) test_channel = "test" - send_slack_message(client_mock, channel=test_channel, msg=slack_msg) + send_slack_message(slack_client=client_mock, channel=test_channel, msg=slack_msg) client_mock.files_upload.assert_called_once_with( file=slack_msg.attachment, channels=test_channel, @@ -83,7 +83,7 @@ def test_send_slack_message_with_buffer_attachment(): SLACK_MSG_TEMPLATE, arguments=template_params, attachment=byte_file ) test_channel = "test" - send_slack_message(client_mock, channel=test_channel, msg=slack_msg) + send_slack_message(slack_client=client_mock, channel=test_channel, msg=slack_msg) client_mock.files_upload.assert_called_once_with( file=byte_file, channels=test_channel,