Skip to content

Commit 6af6b37

Browse files
authored
Merge pull request #29 from NHSDigital/AMB-1689-Map-batch-CSV-file-to-immunisation-object
AMB-1689-Map-batch-CSV-file-to-immunisation-object
2 parents 2a47c89 + 8200909 commit 6af6b37

File tree

6 files changed

+541
-0
lines changed

6 files changed

+541
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import json
2+
from time import time
3+
from boto3 import resource
4+
from boto3 import client
5+
from lambdas.batch_processing.csv_to_model import read_csv_to_immunizations
6+
from lambdas.batch_processing.model_to_fhir import convert_to_fhir
7+
8+
9+
# This is yet to be integrated with main logic
10+
def lambda_handler(_event, _context):
11+
s3_client = client("s3")
12+
records = _event.get("Records", [])
13+
s3_event = records[0].get("s3", {})
14+
source_bucket_name = s3_event.get("bucket", {}).get("name")
15+
bucket_key_name = s3_event.get("object", {}).get("key")
16+
17+
dest_bucket_name = source_bucket_name.replace("source", "destination")
18+
output_bucket = resource("s3").Bucket(dest_bucket_name)
19+
20+
# Read the contents of the CSV file from S3
21+
try:
22+
response = s3_client.get_object(Bucket=source_bucket_name, Key=bucket_key_name)
23+
csv_data = response["Body"].read().decode("utf-8")
24+
25+
immunizations = read_csv_to_immunizations(csv_data)
26+
27+
for immunization in immunizations:
28+
29+
fhir_imms = convert_to_fhir(immunization)
30+
31+
expected_json = json.loads(fhir_imms.get_immunization())
32+
expected_json["patient"] = json.loads(fhir_imms.get_patient())
33+
expected_json["reportOrigin"] = json.loads(fhir_imms.get_report_origin())
34+
expected_json["reasonCode"] = json.loads(fhir_imms.get_reason_code())
35+
expected_json["recorded"] = fhir_imms.get_recorded()
36+
expected_json["manufacturer"] = json.loads(fhir_imms.get_manufacturer())
37+
expected_json["performer"] = fhir_imms.get_actor()
38+
# Add "resourceType" to the "location" element
39+
expected_json["location"]["resourceType"] = "Location"
40+
print(json.dumps(expected_json))
41+
42+
# Write some placeholder bytestring data to a file in the bucket
43+
filename = f"output_report_{int(time())}.txt"
44+
data = (
45+
f"Test file to see if the lambda writes to the correct S3 bucket. "
46+
f"This was the name of the original file: {bucket_key_name}. "
47+
f"content of file: {immunizations}. "
48+
f"If our AWS bill skyrockets, this file has been written to the wrong bucket!"
49+
)
50+
51+
output_bucket.put_object(Body=data, Key=filename)
52+
53+
return {"statusCode": 200}
54+
except Exception as e:
55+
print(f"Error reading CSV file: {str(e)}")
56+
return {"statusCode": 500, "body": "Error reading CSV file from S3."}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import csv
2+
from models.immunization import ImmunizationModel
3+
import datetime
4+
5+
6+
def parse_iso8601_datetime(iso_datetime_str):
7+
try:
8+
# Parse ISO 8601 datetime string with timezone offset
9+
dt = datetime.fromisoformat(iso_datetime_str)
10+
11+
# Convert the parsed datetime to the system's local timezone
12+
dt = dt.astimezone()
13+
14+
return dt
15+
except ValueError:
16+
return None
17+
18+
19+
# Define a function to read and transform the CSV file
20+
def read_csv_to_immunizations(csv_data):
21+
immunizations = [] = []
22+
23+
csv_reader = csv.DictReader(csv_data.splitlines())
24+
for row in csv_reader:
25+
# Parse datetime fields if needed
26+
if row["PERSON_DOB"]:
27+
row["PERSON_DOB"] = datetime.strptime(row["PERSON_DOB"], "%Y-%m-%d").date()
28+
if row["DATE_AND_TIME"]:
29+
row["DATE_AND_TIME"] = parse_iso8601_datetime(row["DATE_AND_TIME"])
30+
if row["RECORDED_DATE"]:
31+
row["RECORDED_DATE"] = datetime.strptime(
32+
row["RECORDED_DATE"], "%Y-%m-%d"
33+
).date()
34+
if row["EXPIRY_DATE"]:
35+
row["EXPIRY_DATE"] = datetime.strptime(
36+
row["EXPIRY_DATE"], "%Y-%m-%d"
37+
).date()
38+
immunization = ImmunizationModel(**row)
39+
if immunization is not None:
40+
immunizations.append(immunization)
41+
42+
return immunizations

0 commit comments

Comments
 (0)