Skip to content

Commit 2915b1b

Browse files
committed
refactor code to use interfaces
1 parent 626dedb commit 2915b1b

File tree

7 files changed

+70
-58
lines changed

7 files changed

+70
-58
lines changed

lambdas/shared/src/common/validator/error_report/error_reporter.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ def check_error_record_for_fail(expression_identifier: str, error_records: list[
2929

3030

3131
def build_error_report(event_id: str, data_parser: dict, error_records: list[ErrorReport]) -> dict:
32-
occurrence_date_time = data_parser.get_fhir_value("occurrenceDateTime")
32+
occurrence_date_time = data_parser.extract_field_value("occurrenceDateTime")
3333
dq_reporter = DQReporter()
3434
return dq_reporter.generate_error_report(event_id, occurrence_date_time, error_records)
35-
36-
37-
def has_validation_failed(error_records: list[ErrorReport]) -> bool:
38-
return any(er.error_level == ErrorLevels.CRITICAL_ERROR for er in error_records)

lambdas/shared/src/common/validator/parsers/fetch_parsers.py

Lines changed: 0 additions & 28 deletions
This file was deleted.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# validation_engine/sources/source_definitions.py
2+
3+
from abc import ABC, abstractmethod
4+
5+
from common.validator.parsers.csv_line_parser import CSVLineParser
6+
from common.validator.parsers.fhir_parser import FHIRParser
7+
8+
9+
class PaserInterface(ABC):
10+
"""Defines a common interface for all data extractors."""
11+
12+
@abstractmethod
13+
def extract_field_values(self, field_path: str, data) -> dict:
14+
pass
15+
16+
@abstractmethod
17+
def get_data_format(self) -> str:
18+
pass
19+
20+
21+
class FHIRInterface(PaserInterface):
22+
def __init__(self, fhir_data: dict):
23+
self.fhir_parser = FHIRParser()
24+
self.fhir_parser.parse_fhir_data(fhir_data)
25+
26+
def get_data_format(self) -> str:
27+
return "fhir"
28+
29+
def extract_field_values(self, field_path):
30+
fhir_value = self.fhir_parser.get_fhir_value_list(field_path)
31+
return fhir_value
32+
33+
34+
class BatchInterface(PaserInterface):
35+
def __init__(self, csv_row: str, csv_header: str):
36+
self.csv_line_parser = CSVLineParser()
37+
self.csv_line_parser.parse_csv_line(csv_row, csv_header)
38+
39+
def get_data_format(self) -> str:
40+
return "batch"
41+
42+
def extract_field_values(self, field_path):
43+
csv_value = self.csv_line_parser.get_key_value(field_path)
44+
return csv_value

lambdas/shared/src/common/validator/parsers/schema_parser.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ def parse_schema(self, schema_file: dict) -> None:
3131
"""
3232
self.schema_file = schema_file
3333
self.expressions = self.schema_file["expressions"]
34+
return self
3435

3536
def expression_count(self) -> int:
3637
"""Returns the number of expressions containing the 'expression' key."""

lambdas/shared/src/common/validator/validator.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,28 @@
99
from common.validator.error_report.error_reporter import add_error_record, check_error_record_for_fail
1010
from common.validator.error_report.record_error import ErrorReport
1111
from common.validator.expression_checker import ExpressionChecker
12-
from common.validator.parsers.fetch_parsers import FetchParsers
12+
from common.validator.parsers.schema_parser import SchemaParser
13+
from src.common.validator.parsers.paser_interface import BatchInterface, FHIRInterface, PaserInterface
1314

1415

1516
class Validator:
1617
def __init__(self, schema_file=""):
1718
self.schema_file = schema_file
18-
self.get_data_from_parsers = FetchParsers()
19+
self.schema_parser = SchemaParser()
1920

20-
# validate a single expression against the data file
21+
# validate expression against incoming data
2122
def _validate_expression(
2223
self,
2324
expression_validator: ExpressionChecker,
2425
expression: dict,
25-
data_parser,
26+
data_parser: PaserInterface,
2627
error_records: list[ErrorReport],
2728
inc_header_in_row_count: bool,
28-
is_csv: bool,
2929
) -> ErrorReport | int:
3030
row = 2 if inc_header_in_row_count else 1
31-
expression_fieldname = expression["fieldNameFlat"] if is_csv else expression["fieldNameFHIR"]
31+
32+
data_format = data_parser.get_data_format()
33+
expression_fieldname = expression["fieldNameFlat"] if data_format == "batch" else expression["fieldNameFHIR"]
3234

3335
expression_id = expression["expressionId"]
3436
error_level = expression["errorLevel"]
@@ -51,7 +53,8 @@ def _validate_expression(
5153
return
5254

5355
try:
54-
expression_values = data_parser.get_key_value(expression_fieldname)
56+
expression_values = data_parser.extract_field_values(expression_fieldname)
57+
print(f"Extracted values for field {expression_fieldname}: {expression_values}")
5558
except Exception as e:
5659
message = f"Data get values Unexpected exception [{e.__class__.__name__}]: {e}"
5760
error_record = ErrorReport(code=ExceptionLevels.PARSING_ERROR, message=message)
@@ -127,7 +130,6 @@ def run_validation(
127130
self,
128131
data_type: DataType,
129132
fhir_data: dict = None,
130-
batch_filepath: str = None,
131133
csv_row: str = None,
132134
csv_header: list[str] = None,
133135
summarise=False,
@@ -139,24 +141,22 @@ def run_validation(
139141
try:
140142
match data_type:
141143
case DataType.FHIR:
142-
data_parser = self.get_data_from_parsers._get_fhir_parser(fhir_data)
143-
is_csv = False
144+
data_parser = FHIRInterface(fhir_data)
144145
case DataType.CSVROW:
145-
data_parser = self.get_data_from_parsers._get_csv_line_parser(csv_row, csv_header)
146-
is_csv = True
146+
data_parser = BatchInterface(csv_row, csv_header)
147147

148148
except Exception as e:
149149
if report_unexpected_exception:
150150
message = f"Data Parser Unexpected exception [{e.__class__.__name__}]: {e}"
151151
return [ErrorReport(code=0, message=message)]
152152

153-
schema_parser = self.get_data_from_parsers._get_schema_parser(self.schema_file)
153+
schema_parser = self.schema_parser.parse_schema(self.schema_file)
154154
expression_validator = ExpressionChecker(data_parser, summarise, report_unexpected_exception)
155-
expressions = schema_parser.get_expressions()
155+
expressions_in_schema = schema_parser.get_expressions()
156156

157-
for expression in expressions:
157+
for expression in expressions_in_schema:
158158
self._validate_expression(
159-
expression_validator, expression, data_parser, error_records, inc_header_in_row_count, is_csv
159+
expression_validator, expression, data_parser, error_records, inc_header_in_row_count
160160
)
161161

162162
return error_records

lambdas/shared/tests/test_common/validator/test_application_fhir.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,16 @@ def setUp(self):
1414
validation_folder = Path(__file__).resolve().parent
1515
self.FHIRFilePath = validation_folder / "sample_data/vaccination2.json"
1616
self.schemaFilePath = validation_folder / "test_schemas/test_schema.json"
17-
self.fhir_resources = None
1817

1918
def test_validation(self):
2019
start = time.time()
2120

2221
SchemaFile = parse_test_file(self.schemaFilePath)
2322
self.fhir_resources = parse_test_file(self.FHIRFilePath)
2423
fhir_parser = Mock()
25-
fhir_parser.get_fhir_value.return_value = "2025-11-06T12:00:00Z"
24+
fhir_parser.extract_field_value.return_value = "2025-11-06T12:00:00Z"
2625

27-
validator = Validator(SchemaFile) # FHIR File Path not needed
26+
validator = Validator(SchemaFile)
2827
error_list = validator.validate_fhir(self.fhir_resources, True, True, True)
2928
error_report = build_error_report(
3029
"25a8cc4d-1875-4191-ac6d-2d63a0ebc64b", fhir_parser, error_list

lambdas/shared/tests/test_common/validator/test_schemas/test_schema.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@
7878
"errorLevel": 2,
7979
"expression": {
8080
"expressionName": "Defaults to",
81-
"expressionType": "",
82-
"expressionRule": "NOTEMPTY"
81+
"expressionType": "NOTEMPTY",
82+
"expressionRule": ""
8383
},
8484
"errorGroup": "completeness"
8585
},
@@ -91,7 +91,7 @@
9191
"errorLevel": 0,
9292
"expression": {
9393
"expressionName": "Date Convert",
94-
"expressionType": "",
94+
"expressionType": "NOTEMPTY",
9595
"expressionRule": ""
9696
},
9797
"errorGroup": "consistency"
@@ -117,7 +117,7 @@
117117
"errorLevel": 1,
118118
"expression": {
119119
"expressionName": "Defaults to",
120-
"expressionType": "DEFAULT",
120+
"expressionType": "NOTEMPTY",
121121
"expressionRule": ""
122122
},
123123
"errorGroup": "consistency"
@@ -195,7 +195,7 @@
195195
"errorLevel": 1,
196196
"expression": {
197197
"expressionName": "Recorded Date Convert",
198-
"expressionType": "DATECONVERT",
198+
"expressionType": "NOTEMPTY",
199199
"expressionRule": ""
200200
},
201201
"errorGroup": "consistency"
@@ -442,7 +442,7 @@
442442
"errorLevel": 1,
443443
"expression": {
444444
"expressionName": "Location Code Type URI Default Check",
445-
"expressionType": "DEFAULT",
445+
"expressionType": "NOTEMPTY",
446446
"expressionRule": ""
447447
},
448448
"errorGroup": "consistency"

0 commit comments

Comments
 (0)