Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 25 additions & 36 deletions packages/syncKnowledgeBaseFunction/app/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import time
import traceback
import uuid
from urllib.parse import unquote_plus
import boto3
from typing import Literal
from app.config.config import (
Expand Down Expand Up @@ -361,7 +362,9 @@
logger.warning("SKIPPING - Bot is not in any channels. No messages sent.")
return []

message_default_text = "I am currently syncing changes to my knowledge base.\n This may take a few minutes."
message_default_text = (
"The documents I use to answer your questions are being updated. " "This will be completed in 10 minutes."

Check warning on line 366 in packages/syncKnowledgeBaseFunction/app/handler.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Merge these implicitly concatenated strings; or did you forget a comma?

See more on https://sonarcloud.io/project/issues?id=NHSDigital_eps-assist-me&issues=AZ0_E1ItkF-AiA4WkETC&open=AZ0_E1ItkF-AiA4WkETC&pullRequest=502
)

# Build blocks for Slack message
blocks = [
Expand All @@ -375,28 +378,17 @@
{
"type": "plan",
"plan_id": uuid.uuid4().hex,
"title": "Processing File Changes...",
"title": "Processing file updates...",
"tasks": [
self.create_task(
id=self.fetching_block_id,
title="Fetching changes",
details=[],
outputs=["Searching"],
status="complete",
),
self.create_task(
id=self.update_block_id,
title="Processing File Changes",
title="Processing file updates...",
details=[],
outputs=["Initialising"],
status="in_progress",
),
],
},
{
"type": "context",
"elements": [{"type": "plain_text", "text": "Please wait up-to 10 minutes for changes to take effect"}],
},
]

return blocks
Expand Down Expand Up @@ -477,6 +469,7 @@
self.created = 0
self.modified = 0
self.deleted = 0
self.document_names = []

@staticmethod
def is_supported_file_type(file_key):
Expand Down Expand Up @@ -506,34 +499,37 @@
return False
return True

def process_multiple_s3_events(self, records: list, slack_handler: SlackHandler):

Check failure on line 502 in packages/syncKnowledgeBaseFunction/app/handler.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 17 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=NHSDigital_eps-assist-me&issues=AZ1OZT4t13GsU-OWRFyH&open=AZ1OZT4t13GsU-OWRFyH&pullRequest=502
logger.info("Processing SQS record")

self.created += len([r for r in records if "ObjectCreated" in r.get("eventName", "")])
self.modified += len([r for r in records if "ObjectModified" in r.get("eventName", "")])
self.deleted += len([r for r in records if "ObjectRemoved" in r.get("eventName", "")])

total = self.created + self.modified + self.deleted
# Extract document names from records
for r in records:
object_key = r.get("s3", {}).get("object", {}).get("key", "")
if object_key:
decoded_key = unquote_plus(object_key)
file_name = decoded_key.split("/")[-1]
if file_name and file_name not in self.document_names:
self.document_names.append(file_name)

counts = [
("created", self.created),
("modified", self.modified),
("deleted", self.deleted),
]

# Generate the list only for non-zero values
message_list = [f"{count} files {action}" for action, count in counts if count > 0]

if message_list and len(message_list) > 0:
if self.document_names:
slack_handler.update_task(
id=slack_handler.update_block_id, message="Update pending", output_message="Processing...", replace=True
)
for i, message in enumerate(message_list):
output_message = f"Processed a total of {total} record(s)" if (i + 1 == len(message_list)) else None
for i, name in enumerate(self.document_names):
total = self.created + self.modified + self.deleted
output_message = (
f"Processed {total} file {'update' if total == 1 else 'updates'}"

Check warning on line 525 in packages/syncKnowledgeBaseFunction/app/handler.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract this nested conditional expression into an independent statement.

See more on https://sonarcloud.io/project/issues?id=NHSDigital_eps-assist-me&issues=AZ1OZT4t13GsU-OWRFyI&open=AZ1OZT4t13GsU-OWRFyI&pullRequest=502
if (i + 1 == len(self.document_names))
else None
)
slack_handler.update_task(
id=slack_handler.update_block_id, message=message, output_message=output_message, replace=(i == 0)
id=slack_handler.update_block_id, message=name, output_message=output_message, replace=(i == 0)
)
slack_handler.update_task_db(created=self.created, modified=self.modified, deleted=self.deleted)
slack_handler.update_task_db(created=self.created, modified=self.modified, deleted=self.deleted)

@staticmethod
def start_ingestion_job():
Expand Down Expand Up @@ -587,13 +583,6 @@
continue

logger.info(f"Processing {len(sqs_records)} record(s)")
output_message = "Search Complete" if (i + 1 == len(events)) else None
slack_handler.update_task(
id=slack_handler.fetching_block_id,
message=f"Found {len(sqs_records)} events",
output_message=output_message,
replace=True,
)

self.process_multiple_sqs_events(slack_handler, sqs_records)

Expand Down
27 changes: 16 additions & 11 deletions packages/syncKnowledgeBaseFunction/tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,8 @@ def mock_post_message_side_effect(**kwargs):

# Assert Messages were posted and updated
mock_slack_client.chat_postMessage.assert_called_once()
assert mock_slack_client.chat_update.call_count == 4 # Update details, update tasks (+ clear), close
# Update pending (replace), update with doc name, complete_plan
assert mock_slack_client.chat_update.call_count == 3


@patch("app.config.config.get_bot_active")
Expand Down Expand Up @@ -923,9 +924,9 @@ def mock_post_message_side_effect(**kwargs):
calls = mock_slack_client.chat_update.call_args_list
assert len(calls) > 0, "Expected chat_update to be called."

# Verify the formatted message made its way into the blocks sent to chat_update
# Verify the document names made their way into the blocks sent to chat_update
last_call_blocks_str = str(calls[-1].kwargs.get("blocks", []))
assert "2 files created" in last_call_blocks_str
assert "test-file.pdf" in last_call_blocks_str


@patch("slack_sdk.WebClient")
Expand Down Expand Up @@ -1012,11 +1013,13 @@ def mock_post_message_side_effect(**kwargs):
calls = mock_slack_client.chat_update.call_args_list
assert len(calls) > 0, "Expected chat_update to be called."

# Verify the formatted message made its way into the blocks sent to chat_update
# Verify the document names made their way into the blocks sent to chat_update
last_call_blocks_str = str(calls[-1].kwargs.get("blocks", []))
assert "4 files created" in last_call_blocks_str # +1 in initial call
assert "3 files modified" in last_call_blocks_str
assert "6 files deleted" in last_call_blocks_str
assert "test-file.pdf" in last_call_blocks_str
assert "file1.pdf" in last_call_blocks_str
assert "file4.pdf" in last_call_blocks_str
assert "file2.pdf" in last_call_blocks_str
assert "file3.pdf" in last_call_blocks_str


@patch("slack_sdk.WebClient")
Expand Down Expand Up @@ -1106,11 +1109,13 @@ def mock_post_message_side_effect(**kwargs):
calls = mock_slack_client.chat_update.call_args_list
assert len(calls) > 0, "Expected chat_update to be called."

# Verify the formatted message made its way into the blocks sent to chat_update
# Verify the document names made their way into the blocks sent to chat_update
last_call_blocks_str = str(calls[-1].kwargs.get("blocks", []))
assert "6 files created" in last_call_blocks_str # +1 initial call
assert "5 files modified" in last_call_blocks_str
assert "10 files deleted" in last_call_blocks_str
assert "test-file.pdf" in last_call_blocks_str
assert "file1.pdf" in last_call_blocks_str
assert "file4.pdf" in last_call_blocks_str
assert "file2.pdf" in last_call_blocks_str
assert "file3.pdf" in last_call_blocks_str


@patch("boto3.client")
Expand Down
66 changes: 60 additions & 6 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ aws-lambda-powertools = "^3.26.0"


[tool.poetry.group.preprocessingFunction.dependencies]
botocore = {extras = ["crt"], version = "^1.42.73"}
boto3 = "^1.42.78"
aws-lambda-powertools = "^3.26.0"
markitdown = {extras = ["pdf", "docx", "xlsx"], version = "^0.0.1a12"}
Expand Down
Loading