generated from NHSDigital/nhs-notify-repository-template
-
Notifications
You must be signed in to change notification settings - Fork 2
11378 low scoring alerts #61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
7e0c5b5
feat: initial commit
ChristopherBacon 27de804
fix: update imports and requirements for lambda deployment
ChristopherBacon 6757d51
fix: lambda issue
ChristopherBacon f550b84
fix: updates to lambda and code for bedrock evaluation service
ChristopherBacon 516e32d
Merge branch 'main' into 11378-low-scoring-alerts
ChristopherBacon ac382b4
fix: catch for preventing overwriting log groups
ChristopherBacon dd1c847
fix: local get template email not working
ChristopherBacon 940b485
fix: simply mail as IAM issue with get mail template
ChristopherBacon 917cb98
fix: trigger the lambda by s3 completion event
ChristopherBacon 556fea0
fix: only send on below 75 percent
ChristopherBacon e646e9a
fix: lambda permissions remove iam pass role
ChristopherBacon 047d093
feat: tests added
ChristopherBacon 5b83b61
fix: remove redundant code
ChristopherBacon bd4d404
fix: path for trivy scan and remove redundant code
ChristopherBacon 63b16ba
fix: pytest ini location and also tests
ChristopherBacon 8927d61
fix: tests and update lambda function
ChristopherBacon 420fd33
fix: remove old pytest ini
ChristopherBacon ea1b0d8
fix: tests and tests paths
ChristopherBacon 452b083
fix: pytest.ini config
ChristopherBacon 9398142
fix: tests and pytest.ini
ChristopherBacon 128390b
fix: more test fixes
ChristopherBacon 26b57da
fix: mock for aws on find results in bucket
ChristopherBacon e32c68c
fix: region attempt 2
ChristopherBacon e97eee3
Merge branch '11378-low-scoring-alerts'
ChristopherBacon 8ebc342
feat: updated lambda zip
ChristopherBacon 8c5ab5f
fix: business BUSINESS and module imports for lambda
ChristopherBacon 0dc0a0a
fix: prompts.jsonl file
ChristopherBacon e07327c
fix: lambda and Ai Feedback for trivy
ChristopherBacon 49038f6
fix: build script for lambda and folder structure reorg
ChristopherBacon cfff941
Merge branch 'main' into 11378-low-scoring-alerts
timireland f7ddcf9
CCM-11378 fixing lamba package path
timireland 90d9840
CCM-11378 refactored to user SNS rather than SES
timireland File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 31 additions & 31 deletions
62
infrastructure/terraform/components/notifyai/resources/prompt-data/prompts.jsonl
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| resource "aws_sns_topic" "admail_eval_alerts_topic" { | ||
| name = "${local.csi}-notifyai-eval-alerts" | ||
| tags = local.default_tags | ||
|
|
||
| } | ||
| resource "aws_sns_topic_subscription" "admail_eval_alerts_subscription" { | ||
| topic_arn = aws_sns_topic.admail_eval_alerts_topic.arn | ||
| protocol = "email" | ||
| endpoint = "admail-eval-alerts@example.com" | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| [pytest] | ||
| pythonpath = src/backend | ||
| testpaths = src/backend/app/tests | ||
| python_files = test_*.py |
Empty file.
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| #!/bin/bash | ||
|
|
||
| # Script to build an AWS Lambda deployment package for bedrock_alerts | ||
| set -e | ||
|
|
||
|
|
||
| BUILD_DIR="lambda_build" | ||
| ZIP_FILE="evaluations_alerts.zip" | ||
|
|
||
|
|
||
| echo "Creating build directory: $BUILD_DIR" | ||
| mkdir -p "$BUILD_DIR" | ||
|
|
||
| if [ -f "requirements.txt" ]; then | ||
| echo "Installing dependencies from requirements.txt to $BUILD_DIR" | ||
| pip install -r requirements.txt -t "$BUILD_DIR" | ||
| else | ||
| echo "Error: requirements.txt not found" | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "Creating bedrock_alerts package in $BUILD_DIR" | ||
| mkdir -p "$BUILD_DIR/bedrock_alerts" | ||
|
|
||
| for file in evaluations_alert_lambda.py evaluations_alert_service.py; do | ||
| if [ -f "$file" ]; then | ||
| echo "Copying $file to $BUILD_DIR/bedrock_alerts/" | ||
| cp "$file" "$BUILD_DIR/bedrock_alerts/" | ||
| else | ||
| echo "Error: $file not found" | ||
| exit 1 | ||
| fi | ||
| done | ||
|
|
||
| if [ -f "bedrock_alerts/__init__.py" ]; then | ||
| echo "Copying bedrock_alerts/__init__.py to $BUILD_DIR/bedrock_alerts/" | ||
| cp "bedrock_alerts/__init__.py" "$BUILD_DIR/bedrock_alerts/" | ||
| else | ||
| echo "Warning: bedrock_alerts/__init__.py not found, creating empty file" | ||
| touch "$BUILD_DIR/bedrock_alerts/__init__.py" | ||
| fi | ||
|
|
||
| echo "Creating zip file: $ZIP_FILE" | ||
| cd "$BUILD_DIR" | ||
| zip -r "../$ZIP_FILE" . | ||
| cd .. | ||
|
|
||
| echo "Lambda package created successfully: $ZIP_FILE" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| import json | ||
| from bedrock_alerts.evaluations_alert_service import BedrockAlertsService | ||
| import os | ||
| import logging | ||
|
|
||
| logging.basicConfig( | ||
| level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" | ||
| ) | ||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| def lambda_handler(event, context): | ||
| bucket = os.environ["env_results_bucket"] | ||
| bucket_key = os.environ["env_results_bucket_key"] | ||
| sns_topic_arn = os.environ["env_sns_topic_arn"] | ||
|
|
||
| alerts = BedrockAlertsService() | ||
| try: | ||
| results = alerts.find_results_file_in_s3(bucket, bucket_key) | ||
| rating_percentage = alerts.calculate_rating_percentage_from_list(results) | ||
| if rating_percentage < 75.0: | ||
| alerts.send_alert(sns_topic_arn) | ||
| logger.info(f"Alert sent successfully rating below 75 percent") | ||
| return { | ||
| 'statusCode': 200, | ||
| 'body': json.dumps({ | ||
| 'message': 'Alert sent successfully', | ||
| }) | ||
| } | ||
| else: | ||
| return | ||
| except Exception as e: | ||
| logger.error(f"Failed to send alert: {str(e)}") | ||
| raise |
16 changes: 16 additions & 0 deletions
16
src/backend/bedrock_alerts/evaluations_alert_local_runner.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import os | ||
| import json | ||
| import logging | ||
| from bedrock_alerts.evaluations_alert_lambda import lambda_handler | ||
| from dotenv import load_dotenv | ||
|
|
||
| logging.basicConfig( | ||
| level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" | ||
| ) | ||
| logger = logging.getLogger(__name__) | ||
|
|
||
| load_dotenv() | ||
|
|
||
| response = lambda_handler({}, {}) | ||
|
|
||
| print(json.dumps(response, indent=2)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| import boto3 | ||
| import jsonlines | ||
| import logging | ||
| from botocore.exceptions import ClientError | ||
| import io | ||
|
|
||
| logging.basicConfig(level=logging.INFO) | ||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| class BedrockAlertsService: | ||
| def __init__(self, sns_client=None, s3_client=None): | ||
| self.sns = sns_client if sns_client is not None else boto3.client("sns") | ||
| self.s3 = s3_client if s3_client is not None else boto3.client("s3") | ||
| self.success_percentage = 0.0 | ||
|
|
||
| def find_results_file_in_s3(self, bucket, prefix): | ||
| try: | ||
| logger.info(f"Searching for files in bucket '{bucket}' with prefix '{prefix}'...") | ||
| paginator = self.s3.get_paginator('list_objects_v2') | ||
| pages = paginator.paginate(Bucket=bucket, Prefix=prefix) | ||
| for page in pages: | ||
| if "Contents" in page: | ||
| for obj in page["Contents"]: | ||
| if obj['Key'].endswith('_output.jsonl'): | ||
| response = self.s3.get_object(Bucket=bucket, Key=obj['Key']) | ||
| file_content_string = response['Body'].read().decode('utf-8') | ||
| try: | ||
| file_like_object = io.StringIO(file_content_string) | ||
| with jsonlines.Reader(file_like_object) as reader: | ||
| return [obj for obj in reader] | ||
| except Exception as e: | ||
| print(f"Error occurred while reading the file: {e}") | ||
| return None | ||
|
|
||
| except ClientError as e: | ||
| print(f"An AWS error occurred while listing objects: {e}") | ||
| return None | ||
|
|
||
| def calculate_rating_percentage_from_list(self, records_list: list) -> float: | ||
| total_rating_score = 0 | ||
| rating_records_count = 0 | ||
| for record in records_list: | ||
| try: | ||
| scores = record.get('automatedEvaluationResult', {}).get('scores', []) | ||
| for metric in scores: | ||
| if metric.get('metricName') == 'Rating': | ||
| total_rating_score += metric.get('result', 0.0) | ||
| rating_records_count += 1 | ||
| break | ||
| except TypeError: | ||
| logger.warning(f"Skipping a record that is not in the expected format: {record}") | ||
| continue | ||
|
|
||
| if rating_records_count == 0: | ||
| logger.warning("No 'Rating' metrics were found in the list.") | ||
| return 0.0 | ||
|
|
||
| success_percentage = round((total_rating_score / rating_records_count) * 100) | ||
| self.success_percentage = success_percentage | ||
| return success_percentage | ||
|
|
||
|
|
||
| def send_alert(self, topic_arn=None): | ||
| try: | ||
| subject = "Bedrock Model Evaluation Alert" | ||
| message = f"Alert Percentage: {self.success_percentage or 'N/A'}\n\nThis alert is below the threshold, please review bedrock model evaluations performance.\n\nThis is an automated alert from Bedrock." | ||
| response = self.sns.publish(TopicArn=topic_arn, Message=message, Subject=subject) | ||
| print(f"Alert sent successfully with response: {response}") | ||
| print("Message published") | ||
|
|
||
| return response | ||
| except Exception as e: | ||
| logger.error( | ||
| f"Failed to send alert: {str(e)}" | ||
| ) | ||
| raise |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| boto3 | ||
| python-dotenv | ||
| jsonlines | ||
| pytest-mock | ||
| moto |
Empty file.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.