55import urllib .parse
66import uuid
77from decimal import Decimal
8+ from json import JSONDecodeError
89from typing import Optional
910
1011from aws_lambda_typing .events import APIGatewayProxyEventV1
2021 Code ,
2122 IdentifierDuplicationError ,
2223 InvalidImmunizationId ,
24+ InvalidJsonError ,
2325 ParameterException ,
2426 Severity ,
2527 UnauthorizedError ,
2628 UnauthorizedVaxError ,
27- UnhandledResponseError ,
2829 ValidationError ,
2930 create_operation_outcome ,
3031)
@@ -48,7 +49,8 @@ def make_controller(
4849
4950
5051class FhirController :
51- immunization_id_pattern = r"^[A-Za-z0-9\-.]{1,64}$"
52+ _IMMUNIZATION_ID_PATTERN = r"^[A-Za-z0-9\-.]{1,64}$"
53+ _API_SERVICE_URL = get_service_url ()
5254
5355 def __init__ (
5456 self ,
@@ -105,46 +107,22 @@ def get_immunization_by_id(self, aws_event: APIGatewayProxyEventV1) -> dict:
105107
106108 return create_response (200 , resource .json (), {E_TAG_HEADER_NAME : version })
107109
108- def create_immunization (self , aws_event ):
109- if not aws_event .get ("headers" ):
110- return create_response (
111- 403 ,
112- create_operation_outcome (
113- resource_id = str (uuid .uuid4 ()),
114- severity = Severity .error ,
115- code = Code .forbidden ,
116- diagnostics = "Unauthorized request" ,
117- ),
118- )
119-
120- supplier_system = self ._identify_supplier_system (aws_event )
110+ @fhir_api_exception_handler
111+ def create_immunization (self , aws_event : APIGatewayProxyEventV1 ) -> dict :
112+ supplier_system = get_supplier_system_header (aws_event )
121113
122114 try :
123- immunisation = json .loads (aws_event ["body" ], parse_float = Decimal )
124- except json .decoder .JSONDecodeError as e :
125- return self ._create_bad_request (f"Request's body contains malformed JSON: { e } " )
126- try :
127- resource = self .fhir_service .create_immunization (immunisation , supplier_system )
128- if "diagnostics" in resource :
129- exp_error = create_operation_outcome (
130- resource_id = str (uuid .uuid4 ()),
131- severity = Severity .error ,
132- code = Code .invariant ,
133- diagnostics = resource ["diagnostics" ],
134- )
135- return create_response (400 , json .dumps (exp_error ))
136- else :
137- location = f"{ get_service_url ()} /Immunization/{ resource .id } "
138- version = "1"
139- return create_response (201 , None , {"Location" : location , "E-Tag" : version })
140- except ValidationError as error :
141- return create_response (400 , error .to_operation_outcome ())
142- except IdentifierDuplicationError as duplicate :
143- return create_response (422 , duplicate .to_operation_outcome ())
144- except UnhandledResponseError as unhandled_error :
145- return create_response (500 , unhandled_error .to_operation_outcome ())
146- except UnauthorizedVaxError as unauthorized :
147- return create_response (403 , unauthorized .to_operation_outcome ())
115+ immunisation : dict = json .loads (aws_event ["body" ], parse_float = Decimal )
116+ except JSONDecodeError as e :
117+ raise InvalidJsonError (message = str (f"Request's body contains malformed JSON: { e } " ))
118+
119+ created_resource_id = self .fhir_service .create_immunization (immunisation , supplier_system )
120+
121+ return create_response (
122+ status_code = 201 ,
123+ body = None ,
124+ headers = {"Location" : f"{ self ._API_SERVICE_URL } /Immunization/{ created_resource_id } " , "E-Tag" : "1" },
125+ )
148126
149127 def update_immunization (self , aws_event ):
150128 try :
@@ -188,7 +166,7 @@ def update_immunization(self, aws_event):
188166 )
189167 return create_response (400 , json .dumps (exp_error ))
190168 # Validate the imms id in the path params and body of request - end
191- except json . decoder . JSONDecodeError as e :
169+ except JSONDecodeError as e :
192170 return self ._create_bad_request (f"Request's body contains malformed JSON: { e } " )
193171 except Exception as e :
194172 return self ._create_bad_request (f"Request's body contains string: { e } " )
@@ -405,7 +383,7 @@ def search_immunizations(self, aws_event: APIGatewayProxyEventV1) -> dict:
405383
406384 def _is_valid_immunization_id (self , immunization_id : str ) -> bool :
407385 """Validates if the given unique Immunization ID is valid."""
408- return False if not re .match (self .immunization_id_pattern , immunization_id ) else True
386+ return False if not re .match (self ._IMMUNIZATION_ID_PATTERN , immunization_id ) else True
409387
410388 def _validate_identifier_system (self , _id : str , _elements : str ) -> Optional [dict ]:
411389 if not _id :
0 commit comments