-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP: Add initial Bedrock Agent and DDB for Calendar events
- Loading branch information
1 parent
1b2e5fc
commit 24176fa
Showing
7 changed files
with
1,248 additions
and
861 deletions.
There are no files selected for viewing
Empty file.
This file contains 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,62 @@ | ||
# Built-in imports | ||
import os | ||
import boto3 | ||
from boto3.dynamodb.conditions import Key | ||
from botocore.exceptions import ClientError | ||
|
||
# TODO: Enhance code to be production grade. This is just a POC | ||
# (Add logger, add error handling, add optimizations, etc...) | ||
|
||
TABLE_NAME = os.environ.get("TABLE_NAME") | ||
dynamodb_resource = boto3.resource("dynamodb") | ||
table = dynamodb_resource.Table(TABLE_NAME) | ||
|
||
|
||
def get_all_calendar_events(partition_key: str, sort_key_portion: str) -> list[dict]: | ||
""" | ||
Function to run a query against DynamoDB with partition key and the sort | ||
key with <begins-with> functionality on it. | ||
:param partition_key (str): partition key value. | ||
:param sort_key_portion (str): sort key portion to use in query. | ||
""" | ||
print( | ||
f"Starting get_all_calendar_events with " | ||
f"pk: ({partition_key}) and sk: ({sort_key_portion})" | ||
) | ||
|
||
all_items = [] | ||
try: | ||
# The structure key for a single-table-design "PK" and "SK" naming | ||
key_condition = Key("PK").eq(partition_key) & Key("SK").begins_with( | ||
sort_key_portion | ||
) | ||
limit = 50 | ||
|
||
# Initial query before pagination | ||
response = table.query( | ||
KeyConditionExpression=key_condition, | ||
Limit=limit, | ||
) | ||
if "Items" in response: | ||
all_items.extend(response["Items"]) | ||
|
||
# Pagination loop for possible following queries | ||
while "LastEvaluatedKey" in response: | ||
response = table.query( | ||
KeyConditionExpression=key_condition, | ||
Limit=limit, | ||
ExclusiveStartKey=response["LastEvaluatedKey"], | ||
) | ||
if "Items" in response: | ||
all_items.extend(response["Items"]) | ||
|
||
return all_items | ||
except ClientError as error: | ||
print( | ||
f"query operation failed for: " | ||
f"table_name: {TABLE_NAME}." | ||
f"pk: {partition_key}." | ||
f"sort_key_portion: {sort_key_portion}." | ||
f"error: {error}." | ||
) | ||
raise error |
This file contains 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,50 @@ | ||
# NOTE: This is a super-MVP code for testing. Still has a lot of gaps to solve/fix. Do not use in prod. | ||
|
||
from bedrock_agent.fetch_calendar_events import get_all_calendar_events | ||
|
||
|
||
def lambda_handler(event, context): | ||
action_group = event["actionGroup"] | ||
_function = event["function"] | ||
parameters = event.get("parameters", []) | ||
|
||
print("PARAMETERS ARE: ", parameters) | ||
|
||
# Extract date from parameters | ||
date = None | ||
event_name = None | ||
for param in parameters: | ||
if param["name"] == "date": | ||
date = param["value"] | ||
|
||
all_events_for_user = get_all_calendar_events( | ||
partition_key="USER#[email protected]", # TODO: Extract user from input when multi-user support | ||
sort_key_portion=f"DATE#{date}", | ||
) | ||
print("DEBUG, ", all_events_for_user) | ||
|
||
# TODO: Add a more robust search engine/algorithm for matching/finding events | ||
result_events = [] | ||
for calendar_event in all_events_for_user: | ||
if calendar_event.get("events"): | ||
result_events.extend(calendar_event["events"]) | ||
|
||
print(f"Events found: {result_events}") | ||
|
||
# Convert the list of events to a string to be able to return it in the response as a string | ||
result_events_string = "\n-".join(result_events) | ||
response_body = {"TEXT": {"body": result_events_string}} | ||
|
||
action_response = { | ||
"actionGroup": action_group, | ||
"function": _function, | ||
"functionResponse": {"responseBody": str(response_body)}, | ||
} | ||
|
||
function_response = { | ||
"response": action_response, | ||
"messageVersion": event["messageVersion"], | ||
} | ||
print("Response: {}".format(function_response)) | ||
|
||
return function_response |
This file contains 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 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
Oops, something went wrong.