From 59b841bfbb5d5690aef7b33b9f658782c689f143 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 18 Jan 2024 11:11:47 +0100 Subject: [PATCH 1/2] add slack bot support --- fink_fat/command_line/cli_main/fitroid.py | 92 ++++++++++++++++++----- fink_fat/data/fink_fat.conf | 5 +- fink_fat/slack_bot/__init__.py | 0 fink_fat/slack_bot/slack_bot.py | 45 +++++++++++ setup.py | 3 +- 5 files changed, 126 insertions(+), 19 deletions(-) create mode 100644 fink_fat/slack_bot/__init__.py create mode 100644 fink_fat/slack_bot/slack_bot.py diff --git a/fink_fat/command_line/cli_main/fitroid.py b/fink_fat/command_line/cli_main/fitroid.py index 6ad5d7f2..49c5f430 100644 --- a/fink_fat/command_line/cli_main/fitroid.py +++ b/fink_fat/command_line/cli_main/fitroid.py @@ -23,6 +23,7 @@ from fink_fat.command_line.association_cli import get_last_roid_streaming_alert from fink_fat.others.utils import LoggerNewLine +import fink_fat.slack_bot.slack_bot as slack def get_default_input(): @@ -348,39 +349,96 @@ def fitroid_associations( nb_remove_chi = nb_after_tw - len(fit_roid_df) - if arguments["--verbose"]: + post_on_slack = string_to_bool(config["SLACK"]["post_on_slack"]) + if arguments["--verbose"] or post_on_slack: nb_trcand = len(fit_roid_df) diff_last_night = nb_trcand - nb_tr_last_night nb_orbits = len(orbits) - traj_cand_size = Counter( - trajectory_df["trajectory_id"].value_counts().sort_index() - ) - traj_orbits_size = Counter( - trajectory_orb["ssoCandId"].value_counts().sort_index() - ) - - logger.info( - f""" -STATISTICS - ASSOCIATIONS ----------- + statistic_string = f""" number of orbits: {nb_orbits} -number of total trcand (end of the processing): {nb_trcand} +number of polyfit trajectories: {nb_trcand} * difference from last night: {f"+{diff_last_night}" if diff_last_night > 0 else f"{diff_last_night}"} * number of deviating trajectory: {nb_deviating_trcand} - * number of new trajectory: {nb_new_trcand} + * number of new trajectory (before the orbit fitting): {nb_new_trcand} * number of trajectories removed by time_window: {nb_remove_tw} * number of trajectories removed by chi_square filter: {nb_remove_chi} +""" + + if post_on_slack: + import matplotlib.pyplot as plt + import io + + def size_hist(data, title): + plt.figure() + plt.title(title) + plt.xlabel("number of observations") + plt.hist(data) + bytes_fig = io.BytesIO() + plt.savefig(bytes_fig, format="png") + bytes_fig.seek(0) + return bytes_fig + + slack_client = slack.init_slackbot() + + result = slack_client.files_upload_v2( + file_uploads=[ + { + "file": size_hist( + trajectory_df["trajectory_id"].value_counts(), + "Distribution of the polyfit trajectories number of observations", + ), + "title": "traj_size_distrib", + }, + { + "file": size_hist( + trajectory_orb["ssoCandId"].value_counts(), + "Distribution of the orbit trajectories number of observations", + ), + "title": "traj_size_distrib", + }, + ] + ) + time.sleep(3) + + traj_size_perml = f"<{result['files'][0]['permalink']}|{' '}>" + orb_size_perml = f"<{result['files'][1]['permalink']}|{' '}>" + + slack_msg = f""" +FINK-FAT STATISTICS OF THE NIGHT: {last_night} + +{statistic_string} + +{traj_size_perml} + +{orb_size_perml} +""" + + slack.post_msg_on_slack(slack_client, slack_msg) + + if arguments["--verbose"]: + traj_cand_size = Counter( + trajectory_df["trajectory_id"].value_counts().sort_index() + ) + traj_orbits_size = Counter( + trajectory_orb["ssoCandId"].value_counts().sort_index() + ) + logger.info( + f""" +STATISTICS - ASSOCIATIONS +---------- + +{statistic_string} trajectories candidate size: {Counter(traj_cand_size)} orbits trajectories size: {Counter(traj_orbits_size)} -""" - ) - logger.newline(2) + """ + ) + logger.newline(2) if arguments["--verbose"]: logger.info("write the results") diff --git a/fink_fat/data/fink_fat.conf b/fink_fat/data/fink_fat.conf index 70c596b5..36684934 100644 --- a/fink_fat/data/fink_fat.conf +++ b/fink_fat/data/fink_fat.conf @@ -79,4 +79,7 @@ roid_module_output=fitroid_output [OFFLINE] log_path=offline_logs -stream_datapath=fink_fat/test/cli_test/small_sso_dataset/ \ No newline at end of file +stream_datapath=fink_fat/test/cli_test/small_sso_dataset/ + +[SLACK] +post_on_slack=false \ No newline at end of file diff --git a/fink_fat/slack_bot/__init__.py b/fink_fat/slack_bot/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/fink_fat/slack_bot/slack_bot.py b/fink_fat/slack_bot/slack_bot.py new file mode 100644 index 00000000..5ec43774 --- /dev/null +++ b/fink_fat/slack_bot/slack_bot.py @@ -0,0 +1,45 @@ +from slack_sdk import WebClient +from slack_sdk.errors import SlackApiError +import configparser +import time +import os + +from fink_fat.others.utils import init_logging + + +def init_slackbot()->WebClient: + try: + token_slack = os.environ['ANOMALY_SLACK_TOKEN'] + except KeyError as ke: + l = init_logging() + l.error("ANOMALY_SLACK_TOKEN environement variable not found !!", exc_info=1) + client = WebClient(token=token_slack) + return client + + +def post_msg_on_slack(webclient: WebClient, msg: str): + logging = init_logging() + try: + webclient.chat_postMessage( + channel='#bot_asteroid_test', + text=msg, + blocks=[ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": msg + } + } + ] + ) + logging.info("Post msg on slack successfull") + except SlackApiError as e: + if e.response["ok"] is False: + logging.error("Post slack msg error", exc_info=1) + +if __name__ == "__main__": + + slack_client = init_slackbot() + + post_msg_on_slack(slack_client, "bonjour") \ No newline at end of file diff --git a/setup.py b/setup.py index 3a7354e8..d49b77ad 100644 --- a/setup.py +++ b/setup.py @@ -40,7 +40,8 @@ "scipy>=1.4.1", "healpy==1.16.6", "pandera==0.18.0", - "lxml>=4.9.3" + "lxml>=4.9.3", + "slack_sdk>=3.26.2" ], entry_points={ "console_scripts": ["fink_fat=fink_fat.command_line.fink_fat_cli:main"] From 3c0142169c299680e0e8eb57c5d721c42d591f80 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 18 Jan 2024 11:16:33 +0100 Subject: [PATCH 2/2] pep8 --- fink_fat/slack_bot/slack_bot.py | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/fink_fat/slack_bot/slack_bot.py b/fink_fat/slack_bot/slack_bot.py index 5ec43774..8238eeb7 100644 --- a/fink_fat/slack_bot/slack_bot.py +++ b/fink_fat/slack_bot/slack_bot.py @@ -1,18 +1,16 @@ from slack_sdk import WebClient from slack_sdk.errors import SlackApiError -import configparser -import time import os from fink_fat.others.utils import init_logging -def init_slackbot()->WebClient: +def init_slackbot() -> WebClient: try: - token_slack = os.environ['ANOMALY_SLACK_TOKEN'] - except KeyError as ke: - l = init_logging() - l.error("ANOMALY_SLACK_TOKEN environement variable not found !!", exc_info=1) + token_slack = os.environ["ANOMALY_SLACK_TOKEN"] + except KeyError: + logger = init_logging() + logger.error("ANOMALY_SLACK_TOKEN environement variable not found !!", exc_info=1) client = WebClient(token=token_slack) return client @@ -21,25 +19,17 @@ def post_msg_on_slack(webclient: WebClient, msg: str): logging = init_logging() try: webclient.chat_postMessage( - channel='#bot_asteroid_test', - text=msg, - blocks=[ - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": msg - } - } - ] - ) + channel="#bot_asteroid_test", + text=msg, + blocks=[{"type": "section", "text": {"type": "mrkdwn", "text": msg}}], + ) logging.info("Post msg on slack successfull") except SlackApiError as e: if e.response["ok"] is False: logging.error("Post slack msg error", exc_info=1) -if __name__ == "__main__": +if __name__ == "__main__": slack_client = init_slackbot() - post_msg_on_slack(slack_client, "bonjour") \ No newline at end of file + post_msg_on_slack(slack_client, "bonjour")