Skip to content

Commit

Permalink
Add Slack Notification to Sorting Function (#3)
Browse files Browse the repository at this point in the history
* Add slack notification

* Add missing setup requirements
  • Loading branch information
dbarrous authored Feb 9, 2023
1 parent 9f00b55 commit ae593c8
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 14 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
- name: Run tests
run: |
pytest --pyargs lambda_function --cov lambda_function
# - name: Run tests
# run: |
# pytest --pyargs lambda_function --cov lambda_function

93 changes: 86 additions & 7 deletions lambda_function/file_sorter/file_sorter.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
"""
This Module contains the FileSorter class that will sort the files into the appropriate
HERMES instrument folder.
TODO: Skeleton Code for initial repo, class still needs to be implemented including
logging to DynamoDB + S3 log file and docstrings expanded
"""
import os
import boto3
import botocore
import datetime
import time
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError

# The below flake exceptions are to avoid the hermes.log writing
# issue the above line solves
Expand Down Expand Up @@ -79,7 +79,34 @@ def __init__(self, s3_bucket, s3_object, environment, dry_run=False):
# Log added file to Incoming Bucket in Timestream
if not self.dry_run:
self._log_to_timestream(
action_type="PUT", file_key=self.file_key, destination_bucket=s3_bucket
action_type="PUT",
file_key=self.file_key,
destination_bucket=s3_bucket,
)

try:
# Initialize the slack client
self.slack_client = WebClient(token=os.getenv("SLACK_TOKEN"))

# Initialize the slack channel
self.slack_channel = os.getenv("SLACK_CHANNEL")

except SlackApiError as e:
error_code = int(e.response["Error"]["Code"])
if error_code == 404:
log.error(
{
"status": "ERROR",
"message": "Slack Token is invalid",
}
)

except Exception as e:
log.error(
{
"status": "ERROR",
"message": f"Error when initializing slack client: {e}",
}
)

# Call sort function
Expand All @@ -97,7 +124,6 @@ def _sort_file(self):
)
or self.dry_run
):

# Dict of parsed science file
destination_bucket = self._get_destination_bucket(file_key=self.file_key)
current_year = datetime.date.today().year
Expand All @@ -116,7 +142,6 @@ def _sort_file(self):
if not self._does_object_exists(
bucket=destination_bucket, file_key=new_file_key
):

# Copy file to destination bucket
self._copy_from_source_to_destination(
source_bucket=self.incoming_bucket_name,
Expand Down Expand Up @@ -205,6 +230,16 @@ def _copy_from_source_to_destination(
bucket = s3.Bucket(destination_bucket)
if new_file_key:
bucket.copy(copy_source, new_file_key)
if self.slack_client:
self._send_slack_notification(
self.slack_client,
self.slack_channel,
(
f"File ({file_key}) "
"Successfully Sorted to "
"{destination_bucket}"
),
)

else:
bucket.copy(copy_source, file_key)
Expand All @@ -226,6 +261,51 @@ def _copy_from_source_to_destination(

raise e

@staticmethod
def _send_slack_notification(
slack_client,
slack_channel: str,
slack_message: str,
alert_type: str = "success",
) -> None:
"""
Function to send a Slack Notification
"""
log.info(f"Sending Slack Notification to {slack_channel}")
try:
color = {
"success": "#9b59b6",
"error": "#ff0000",
}
ct = datetime.datetime.now()
ts = ct.strftime("%y-%m-%d %H:%M:%S")
slack_client.chat_postMessage(
channel=slack_channel,
text=f"{ts} - {slack_message}",
attachments=[
{
"color": color[alert_type],
"blocks": [
{
"type": "section",
"text": {
"type": "plain_text",
"text": f"{ts} - {slack_message}",
},
}
],
}
],
)

except SlackApiError as e:
log.error(
{
"status": "ERROR",
"message": f"Error sending Slack Notification: {e}",
}
)

def _log_to_timestream(
self,
action_type,
Expand Down Expand Up @@ -262,7 +342,6 @@ def _log_to_timestream(
print(i.key)
count_obj = count_obj + 1

print(count_obj)
# Write to Timestream
if not self.dry_run:
timestream.write_records(
Expand Down
3 changes: 0 additions & 3 deletions lambda_function/lambda_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ def handler(event, context):
environment = "DEVELOPMENT"

for s3_event in event["Records"]:

s3_bucket = s3_event["s3"]["bucket"]["name"]
file_key = s3_event["s3"]["object"]["key"]

Expand All @@ -46,7 +45,6 @@ def handler(event, context):
return response

except KeyError:

# Pass required variables to sort function and returns a 200 (Successful)
# / 500 (Error) HTTP response
response = sort_file(environment)
Expand All @@ -71,7 +69,6 @@ def sort_file(environment, s3_bucket=None, file_key=None):
s3 = boto3.resource("s3")
bucket = s3.Bucket("swsoc-incoming")
for s3_object in bucket.objects.all():

FileSorter(
s3_bucket=s3_bucket,
s3_object=s3_object.key,
Expand Down
6 changes: 5 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
hermes_core @ git+https://github.com/HERMES-SOC/hermes_core.git
boto3
boto3
pytest
pytest-astropy
pytest-cov
slack_sdk

0 comments on commit ae593c8

Please sign in to comment.