Skip to content

Commit 4228d03

Browse files
committed
VED-367: Refactor search params controller, handler, utility and unittest
1 parent 3c684b7 commit 4228d03

File tree

5 files changed

+105
-88
lines changed

5 files changed

+105
-88
lines changed

backend/src/fhir_controller.py

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -549,47 +549,64 @@ def authorize_request(self, aws_event: dict) -> Optional[dict]:
549549
return self.create_response(500, id_error)
550550

551551
def fetch_identifier_system_and_element(self, event: dict):
552+
"""
553+
Extracts `identifier` and `_elements` from an incoming FHIR search request.
554+
555+
FHIR search supports two input formats:
556+
1. GET search: parameters appear in the query string (e.g. ?identifier=abc123&_elements=id,meta)
557+
2. POST search: parameters appear in the request body, form-encoded (e.g. identifier=abc123&_elements=id,meta)
558+
559+
This function handles both cases, returning:
560+
- The extracted identifier value
561+
- The extracted _elements value
562+
- Any validation check result for disallowed keys
563+
- Booleans indicating whether identifier/_elements were present
564+
"""
565+
552566
query_params = event.get("queryStringParameters", {})
553567
body = event["body"]
554568
not_required_keys = ["-date.from", "-date.to", "-immunization.target", "_include", "patient.identifier"]
569+
570+
# Get Search Identifer Parameters
555571
if query_params and not body:
556-
# Check for the presence of 'immunization.identifier' and '_element'
557-
query_string_has_immunization_identifier = "immunization.identifier" in event.get(
572+
query_string_has_immunization_identifier = "identifier" in event.get(
558573
"queryStringParameters", {}
559574
)
560-
query_string_has_element = "_element" in event.get("queryStringParameters", {})
561-
immunization_identifier = query_params.get("immunization.identifier", "")
562-
element = query_params.get("_element", "")
575+
query_string_has_element = "_elements" in event.get("queryStringParameters", {})
576+
identifier = query_params.get("identifier", "")
577+
element = query_params.get("_elements", "")
563578
query_check = check_keys_in_sources(event, not_required_keys)
564579

565580
return (
566-
immunization_identifier,
581+
identifier,
567582
element,
568583
query_check,
569584
query_string_has_immunization_identifier,
570585
query_string_has_element,
571586
)
587+
588+
# Post Search Identifier by body form
572589
if body and not query_params:
573590
decoded_body = base64.b64decode(body).decode("utf-8")
574591
parsed_body = urllib.parse.parse_qs(decoded_body)
575-
# Attempt to extract 'immunization.identifier' and '_element'
576-
converted_identifer = ""
577-
converted_element = ""
578-
immunization_identifier = parsed_body.get("immunization.identifier", "")
579-
if immunization_identifier:
580-
converted_identifer = "".join(immunization_identifier)
581-
_element = parsed_body.get("_element", "")
582-
if _element:
583-
converted_element = "".join(_element)
584-
body_has_immunization_identifier = "immunization.identifier" in parsed_body
585-
body_has_immunization_element = "_element" in parsed_body
592+
# Attempt to extract 'identifier' and '_elements'
593+
converted_identifier = ""
594+
converted_elements = ""
595+
identifier = parsed_body.get("identifier", "")
596+
if identifier:
597+
converted_identifier = "".join(identifier)
598+
_elements = parsed_body.get("_elements", "")
599+
if _elements:
600+
converted_elements = "".join(_elements)
601+
body_has_identifier = "identifier" in parsed_body
602+
body_has_immunization_elements = "_elements" in parsed_body
586603
body_check = check_keys_in_sources(event, not_required_keys)
587604
return (
588-
converted_identifer,
589-
converted_element,
605+
converted_identifier,
606+
converted_elements,
590607
body_check,
591-
body_has_immunization_identifier,
592-
body_has_immunization_element,
608+
body_has_identifier,
609+
body_has_immunization_elements,
593610
)
594611

595612
def create_response_for_identifier(self, not_required, has_identifier, has_element):
@@ -598,7 +615,7 @@ def create_response_for_identifier(self, not_required, has_identifier, has_eleme
598615
resource_id=str(uuid.uuid4()),
599616
severity=Severity.error,
600617
code=Code.server_error,
601-
diagnostics="Search parameter should have either immunization.identifier or patient.identifier",
618+
diagnostics="Search parameter should have either identifier or patient.identifier",
602619
)
603620
return self.create_response(400, error)
604621

@@ -607,7 +624,7 @@ def create_response_for_identifier(self, not_required, has_identifier, has_eleme
607624
resource_id=str(uuid.uuid4()),
608625
severity=Severity.error,
609626
code=Code.server_error,
610-
diagnostics="Search parameter immunization.identifier must have the following parameter: _element",
627+
diagnostics="Search parameter identifier must have the following parameter: _elements",
611628
)
612629
return self.create_response(400, error)
613630

@@ -616,7 +633,7 @@ def create_response_for_identifier(self, not_required, has_identifier, has_eleme
616633
resource_id=str(uuid.uuid4()),
617634
severity=Severity.error,
618635
code=Code.server_error,
619-
diagnostics="Search parameter _element must have the following parameter: immunization.identifier",
636+
diagnostics="Search parameter _elements must have the following parameter: identifier",
620637
)
621638
return self.create_response(400, error)
622639

backend/src/models/utils/generic_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def form_json(response, _element, identifier, baseurl):
142142
"resourceType": "Bundle",
143143
"type": "searchset",
144144
"link": [
145-
{"relation": "self", "url": f"{baseurl}?immunization.identifier={identifier}&_elements={_element}"}
145+
{"relation": "self", "url": f"{baseurl}?identifier={identifier}&_elements={_element}"}
146146
],
147147
"entry": [],
148148
"total": 0,
@@ -153,7 +153,7 @@ def form_json(response, _element, identifier, baseurl):
153153
json = {
154154
"resourceType": "Bundle",
155155
"type": "searchset",
156-
"link": [{"relation": "self", "url": f"{baseurl}?immunization.identifier={identifier}&_elements={_element}"}],
156+
"link": [{"relation": "self", "url": f"{baseurl}?identifier={identifier}&_elements={_element}"}],
157157
"entry": [
158158
{
159159
"fullUrl": f"https://api.service.nhs.uk/immunisation-fhir-api/Immunization/{response['id']}",

backend/src/search_imms_handler.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,19 @@ def search_imms(event: events.APIGatewayProxyEventV1, controller: FhirController
3232
body_has_immunization_element = False
3333
if not (query_params == None and body == None):
3434
if query_params:
35-
query_string_has_immunization_identifier = "immunization.identifier" in event.get(
35+
query_string_has_immunization_identifier = "identifier" in event.get(
3636
"queryStringParameters", {}
3737
)
38-
query_string_has_element = "_element" in event.get("queryStringParameters", {})
38+
query_string_has_element = "_elements" in event.get("queryStringParameters", {})
3939
# Decode body from base64
4040
if body:
4141
decoded_body = base64.b64decode(body).decode("utf-8")
4242
# Parse the URL encoded body
4343
parsed_body = urllib.parse.parse_qs(decoded_body)
4444

4545
# Check for 'immunization.identifier' in body
46-
body_has_immunization_identifier = "immunization.identifier" in parsed_body
47-
body_has_immunization_element = "_element" in parsed_body
46+
body_has_immunization_identifier = "identifier" in parsed_body
47+
body_has_immunization_element = "_elements" in parsed_body
4848
if (
4949
query_string_has_immunization_identifier
5050
or body_has_immunization_identifier
@@ -97,13 +97,13 @@ def search_imms(event: events.APIGatewayProxyEventV1, controller: FhirController
9797
parser.add_argument("--date.from", type=str, required=False, dest="date_from")
9898
parser.add_argument("--date.to", type=str, required=False, dest="date_to")
9999
parser.add_argument(
100-
"--immunization.identifier",
100+
"--identifier",
101101
help="Identifier of System",
102102
type=str,
103103
required=False,
104-
dest="immunization_identifier",
104+
dest="identifier",
105105
)
106-
parser.add_argument("--element", help="Identifier of System", type=str, required=False, dest="_element")
106+
parser.add_argument("--elements", help="Identifier of System", type=str, required=False, dest="_elements")
107107
args = parser.parse_args()
108108

109109
event: events.APIGatewayProxyEventV1 = {
@@ -113,8 +113,8 @@ def search_imms(event: events.APIGatewayProxyEventV1, controller: FhirController
113113
"-date.from": [args.date_from] if args.date_from else [],
114114
"-date.to": [args.date_to] if args.date_to else [],
115115
"_include": ["Immunization:patient"],
116-
"immunization_identifier": [args.immunization_identifier] if args.immunization_identifier else [],
117-
"_element": [args._element] if args._element else [],
116+
"identifier": [args.immunization_identifier] if args.immunization_identifier else [],
117+
"_elements": [args._element] if args._element else [],
118118
},
119119
"httpMethod": "POST",
120120
"headers": {

0 commit comments

Comments
 (0)