From d33915f31e9be259e4e3934d0ae5a3d0cd241ddf Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 25 Mar 2025 12:13:32 +0000 Subject: [PATCH] [server]: Update punctuality_by_timestamp table --- .../lambda_function.py | 51 ++++++++++++++++--- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/server/src/functions/update_average_punctuality/lambda_function.py b/server/src/functions/update_average_punctuality/lambda_function.py index d548af9..ee507ef 100644 --- a/server/src/functions/update_average_punctuality/lambda_function.py +++ b/server/src/functions/update_average_punctuality/lambda_function.py @@ -4,16 +4,20 @@ import requests import os from decimal import Decimal +# Initialize DynamoDB resource dynamodb = boto3.resource("dynamodb") -table = dynamodb.Table("punctuality_by_objectID") +table_train = dynamodb.Table("punctuality_by_objectID") +table_timestamp = dynamodb.Table("punctuality_by_timestamp") + API_URL = "https://281bc6mcm5.execute-api.us-east-1.amazonaws.com/transient_data?objectType=IrishRailTrain" def fetch_train_data(): + """Fetch train data from API.""" try: response = requests.get(API_URL) - response.raise_for_status() # Raise an error for bad status codes - if response.text.strip(): # Ensure response is not empty + response.raise_for_status() + if response.text.strip(): return response.json() else: print("Error: Empty response from API") @@ -27,8 +31,9 @@ def fetch_train_data(): def update_punctuality(objectID, new_punctuality): + """Update punctuality data for a specific train.""" new_punctuality = Decimal(str(new_punctuality)) # Ensure Decimal type for DynamoDB - response = table.get_item(Key={"objectID": objectID}) + response = table_train.get_item(Key={"objectID": objectID}) if "Item" in response: item = response["Item"] old_avg = Decimal(str(item["average_punctuality"])) @@ -38,8 +43,8 @@ def update_punctuality(objectID, new_punctuality): new_avg = ((old_avg * count) + new_punctuality) / (count + 1) count += 1 - # Update the DynamoDB table, renaming 'count' to avoid using a reserved keyword - table.update_item( + # Update the DynamoDB table, renaming 'count' to avoid reserved keyword issues + table_train.update_item( Key={"objectID": objectID}, UpdateExpression="SET average_punctuality = :avg, #cnt = :cnt", ExpressionAttributeValues={":avg": new_avg, ":cnt": count}, @@ -47,22 +52,52 @@ def update_punctuality(objectID, new_punctuality): ) else: # Insert new train punctuality record - table.put_item( + table_train.put_item( Item={"objectID": objectID, "average_punctuality": new_punctuality, "count": 1} ) +def update_punctuality_by_timestamp(timestamp, punctualities): + """Update the average punctuality for a given timestamp.""" + if not punctualities: + return + + avg_punctuality = sum(punctualities) / len(punctualities) + + # Insert or update record in DynamoDB + table_timestamp.put_item( + Item={ + "timestamp": timestamp, + "average_punctuality": avg_punctuality + } + ) + + def lambda_handler(event, context): + """AWS Lambda handler.""" train_data = fetch_train_data() + + if not train_data: + return {"statusCode": 500, "body": json.dumps("No train data available")} + + # Extract timestamp (assuming all records share the same timestamp) + timestamp = train_data[0].get("timestamp") if train_data else None + if not timestamp: + return {"statusCode": 500, "body": json.dumps("Missing timestamp in train data")} + + punctualities = [] for train in train_data: objectID = train.get("objectID") punctuality = int(train.get("trainPunctuality", 0)) if objectID: update_punctuality(objectID, punctuality) + punctualities.append(punctuality) + + # Update average punctuality for the timestamp + update_punctuality_by_timestamp(timestamp, punctualities) return { "statusCode": 200, "body": json.dumps("Punctuality data updated successfully") } -