diff --git a/containers/message-parser/app/default_schemas/ecr_with_metadata.json b/containers/message-parser/app/default_schemas/ecr_with_metadata.json new file mode 100644 index 0000000000..2e206e5e15 --- /dev/null +++ b/containers/message-parser/app/default_schemas/ecr_with_metadata.json @@ -0,0 +1,366 @@ +{ + "patient_id": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Patient').id", + "data_type": "string", + "nullable": false + }, + "person_id": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Person').id", + "data_type": "string", + "nullable": false + }, + "last_name": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').name.first().family", + "data_type": "string", + "nullable": true, + "metadata": { + "category": "Personal info" + } + }, + "first_name": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').name.first().given.first()", + "data_type": "string", + "nullable": true, + "metadata": { + "category": "Personal info" + } + }, + "birth_date": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').birthDate", + "data_type": "date", + "nullable": true, + "metadata": { + "category": "Personal info" + } + }, + "gender": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').gender", + "data_type": "string", + "nullable": true, + "metadata": { + "category": "Personal info" + } + }, + "race": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-race').extension.valueCoding.display", + "data_type": "string", + "nullable": true, + "metadata": { + "category": "Personal info" + } + }, + "ethnicity": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url = 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity').extension.valueCoding.display", + "data_type": "string", + "nullable": true, + "metadata": { + "category": "Personal info" + } + }, + "street_address1": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').address.line[0]", + "data_type": "string", + "nullable": true, + "metadata": { + "category": "Personal info" + } + }, + "street_address2": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').address.line[1]", + "data_type": "string", + "nullable": true, + "metadata": { + "category": "Personal info" + } + }, + "state": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').address.state", + "data_type": "string", + "nullable": true, + "metadata": { + "category": "Personal info" + } + }, + "zip": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').address.postalCode", + "data_type": "string", + "nullable": true, + "metadata": { + "category": "Personal info" + } + }, + "latitude": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').address.extension.where(url='http://hl7.org/fhir/StructureDefinition/geolocation').extension.where(url='latitude').valueDecimal", + "data_type": "float", + "nullable": true + }, + "longitude": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').address.extension.where(url='http://hl7.org/fhir/StructureDefinition/geolocation').extension.where(url='longitude').valueDecimal", + "data_type": "float", + "nullable": true + }, + "rr_id": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Composition').section.where(title = 'Reportability Response Information Section').extension.where(url='http://hl7.org/fhir/us/ecr/StructureDefinition/rr-composition').valueIdentifier.where(use='official' and type.coding.code='88085-6').value", + "data_type": "string", + "nullable": true + }, + "status": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Composition').section.where(title = 'Reportability Response Information Section').extension.where(url='http://hl7.org/fhir/us/ecr/StructureDefinition/rr-eicr-processing-status-extension').valueCodeableConcept.coding.where(system='urn:oid:2.16.840.1.114222.4.5.274').code", + "data_type": "string", + "nullable": true + }, + "conditions": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Observation').where(code.coding.first().code='64572001' and code.coding.first().system='http://snomed.info/sct').valueCodeableConcept.coding.display", + "data_type": "string", + "nullable": true + }, + "eicr_set_id": { + "fhir_path": "Bundle.entry.resource.where(resourceType= 'Composition').identifier.where(type.coding.code = '55751-2').where(use='official').value", + "data_type": "string", + "nullable": true + }, + "eicr_id": { + "fhir_path": "Bundle.entry.resource.where(resourceType= 'Composition').id", + "data_type": "string", + "nullable": false + }, + "eicr_version_number": { + "fhir_path": "Bundle.entry.resource.where(resourceType= 'Composition' ).extension.where(url='http://hl7.org/fhir/StructureDefinition/composition-clinicaldocument-versionNumber').valueString", + "data_type": "string", + "nullable": false + }, + "replaced_eicr_id": { + "fhir_path": "Bundle.entry.resource.where(resourceType= 'Composition').relatesTo.where(code='replaces').targetReference.reference", + "data_type": "string", + "nullable": true + }, + "replaced_eicr_version": { + "fhir_path": "Bundle.entry.resource.where(resourceType= 'Composition').relatesTo.where(code='replaces').extension.where(url='http://hl7.org/fhir/StructureDefinition/composition-clinicaldocument-versionNumber').valueString", + "data_type": "string", + "nullable": true + }, + "authoring_datetime": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Composition').date", + "data_type": "datetime", + "nullable": true + }, + "provider_id": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Practitioner').where(extension.valueString='Responsible Party').identifier.value", + "data_type": "string", + "nullable": true + }, + "facility_id_number": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Encounter')[0].location[0].id", + "data_type": "string", + "nullable": true + }, + "facility_name": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Encounter')[0].location[0].location.display", + "data_type": "string", + "nullable": true + }, + "facility_type": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Encounter')[0].location[0].extension.where(url = 'http://build.fhir.org/ig/HL7/case-reporting/StructureDefinition-us-ph-location-definitions.html#Location.type').valueCodeableConcept.coding[0].display", + "data_type": "string", + "nullable": true + }, + "encounter_type": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Encounter')[0].class.where(system = 'urn:oid:2.16.840.1.113883.5.4').display", + "data_type": "string", + "nullable": true + }, + "encounter_start_date": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Encounter').period.start", + "data_type": "datetime", + "nullable": true + }, + "encounter_end_date": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Encounter').period.end", + "data_type": "datetime", + "nullable": true + }, + "reason_for_visit": { + "fhir_path": "Bundle.entry.resource.where(resourceType= 'Composition' ).section.where(code.coding.code='29299-5').extension.where(url='http://hl7.org/fhir/cda/ccda/StructureDefinition/2.16.840.1.113883.10.20.22.2.12').valueString", + "data_type": "string", + "nullable": true + }, + "active_problems": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Condition').where(category.coding.code='problem-item-list')", + "data_type": "array", + "nullable": true, + "secondary_schema": { + "problem": { + "fhir_path": "Condition.code.coding.display", + "data_type": "string", + "nullable": true + }, + "problem_date": { + "fhir_path": "Condition.onsetDateTime", + "data_type": "datetime", + "nullable": true + } + } + }, + "labs": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Observation').where(category.coding.code='laboratory')", + "data_type": "array", + "nullable": true, + "secondary_schema": { + "test_type": { + "fhir_path": "Observation.code.coding.display", + "data_type": "string", + "nullable": true + }, + "test_type_code": { + "fhir_path": "Observation.code.coding.code", + "data_type": "string", + "nullable": true + }, + "test_type_system": { + "fhir_path": "Observation.code.coding.system", + "data_type": "string", + "nullable": true + }, + "test_result_qualitative": { + "fhir_path": "Observation.valueString", + "data_type": "string", + "nullable": true + }, + "test_result_quantitative": { + "fhir_path": "Observation.valueQuantity.value", + "data_type": "float", + "nullable": true + }, + "test_result_units": { + "fhir_path": "Observation.valueQuantity.unit", + "data_type": "string", + "nullable": true + }, + "test_result_code": { + "fhir_path": "Observation.valueCodeableConcept.coding.code", + "data_type": "string", + "nullable": true + }, + "test_result_code_display": { + "fhir_path": "Observation.valueCodeableConcept.coding.display", + "data_type": "string", + "nullable": true + }, + "test_result_code_system": { + "fhir_path": "Observation.valueCodeableConcept.coding.system", + "data_type": "string", + "nullable": true + }, + "test_result_interp": { + "fhir_path": "Observation.interpretation.coding.display", + "data_type": "string", + "nullable": true + }, + "test_result_interp_code": { + "fhir_path": "Observation.interpretation.coding.code", + "data_type": "string", + "nullable": true + }, + "test_result_interp_system": { + "fhir_path": "Observation.interpretation.coding.system", + "data_type": "string", + "nullable": true + }, + "test_result_ref_range_low": { + "fhir_path": "Observation.refereneceRange.low.value", + "data_type": "float", + "nullable": true + }, + "test_result_ref_range_low_units": { + "fhir_path": "Observation.refereneceRange.low.unit", + "data_type": "string", + "nullable": true + }, + "test_result_ref_range_high": { + "fhir_path": "Observation.refereneceRange.high.value", + "data_type": "float", + "nullable": true + }, + "test_result_ref_range_high_units": { + "fhir_path": "Observation.refereneceRange.high.unit", + "data_type": "string", + "nullable": true + }, + "specimen_type": { + "fhir_path": "Observation.extension.where(url='http://hl7.org/fhir/R4/specimen.html').extension.where(url='specimen source').valueString", + "data_type": "string", + "nullable": true + }, + "performing_lab": { + "fhir_path": "Observation.performer.display", + "data_type": "string", + "nullable": true + }, + "specimen_collection_date": { + "fhir_path": "Observation.extension.where(url='http://hl7.org/fhir/R4/specimen.html').extension.where(url='specimen collection time').valueDateTime", + "data_type": "datetime", + "nullable": true + } + } + }, + "birth_sex": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url='http: //hl7.org/fhir/us/core/StructureDefinition/us-core-birthsex').extension.value.coding.display", + "data_type": "string", + "nullable": true + }, + "gender_identity": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url='http: //hl7.org/fhir/us/ecr/StructureDefinition/us-ph-genderidentity-extension').extension.value.coding.display", + "data_type": "string", + "nullable": true + }, + "homelessness_status": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Observation').where(code.coding.code='75274-1').where(category.coding.code='social-history').valueCodeableConcept.coding.display", + "data_type": "string", + "nullable": true + }, + "disabilities": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Observation').where(meta.profile='http://hl7.org/fhir/us/ecr/StructureDefinition/us-ph-disability-status').where(category.coding.code='social-history').where(valueBoolean).code.coding.display", + "data_type": "string", + "nullable": true + }, + "tribal_affiliation": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url='http: //hl7.org/fhir/us/ecr/StructureDefinition/us-ph-tribal-affiliation-extension').extension.where(url='TribeName').value.display", + "data_type": "string", + "nullable": true + }, + "tribal_enrollment_status": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').extension.where(url='http: //hl7.org/fhir/us/ecr/StructureDefinition/us-ph-tribal-affiliation-extension').extension.where(url='EnrolledTribeMember').value", + "data_type": "string", + "nullable": true + }, + "current_job_title": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Observation').where(meta.profile='http://hl7.org/fhir/us/odh/StructureDefinition/odh-PastOrPresentJob').where(effectivePeriod.end.exists().not()).valueCodeableConcept.coding.display", + "data_type": "string", + "nullable": true + }, + "current_job_industry": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Observation').where(meta.profile='http: //hl7.org/fhir/us/odh/StructureDefinition/odh-PastOrPresentJob').where(effectivePeriod.end.exists().not()).component.where(code.coding.code='86188-0').value.coding.display", + "data_type": "string", + "nullable": true + }, + "usual_occupation": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Observation').where(meta.profile='http: //hl7.org/fhir/us/odh/StructureDefinition/odh-UsualWork').valueCodeableConcept.coding.display", + "data_type": "string", + "nullable": true + }, + "usual_industry": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Observation').where(meta.profile='http: //hl7.org/fhir/us/odh/StructureDefinition/odh-UsualWork').component.where(code.coding.code='21844-6').value.coding.display", + "data_type": "string", + "nullable": true + }, + "preferred_language": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').communication.where(preferred).language.coding.display", + "data_type": "string", + "nullable": true + }, + "pregnancy_status": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Observation').where(meta.profile='http: //hl7.org/fhir/us/ecr/StructureDefinition/us-ph-pregnancy-status-observation').value.coding.display", + "data_type": "string", + "nullable": true + } +} \ No newline at end of file diff --git a/containers/message-parser/app/default_schemas/test_schema.json b/containers/message-parser/app/default_schemas/test_schema.json index 24d123035b..159084ea6a 100644 --- a/containers/message-parser/app/default_schemas/test_schema.json +++ b/containers/message-parser/app/default_schemas/test_schema.json @@ -1,39 +1,42 @@ { - "first_name": { - "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').name.first().given.first()", - "data_type": "string", - "nullable": true - }, - "last_name": { - "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').name.first().family", - "data_type": "string", - "nullable": true - }, - "latitude": { - "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').address.extension.where(url='http://hl7.org/fhir/StructureDefinition/geolocation').extension.where(url='latitude').valueDecimal", - "data_type": "float", - "nullable": true - }, - "longitude": { - "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').address.extension.where(url='http://hl7.org/fhir/StructureDefinition/geolocation').extension.where(url='longitude').valueDecimal", - "data_type": "float", - "nullable": true - }, - "active_problems": { - "fhir_path": "Bundle.entry.resource.where(resourceType='Condition').where(category.coding.code='problem-item-list')", - "data_type": "array", - "nullable": true, - "secondary_schema": { - "problem": { - "fhir_path": "Condition.code.coding.display", - "data_type": "string", - "nullable": true - }, - "problem_date": { - "fhir_path": "Condition.onsetDateTime", - "data_type": "datetime", - "nullable": true - } + "first_name": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').name.first().given.first()", + "data_type": "string", + "nullable": true, + "metadata": { + "category": "name" + } + }, + "last_name": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').name.first().family", + "data_type": "string", + "nullable": true + }, + "latitude": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').address.extension.where(url='http://hl7.org/fhir/StructureDefinition/geolocation').extension.where(url='latitude').valueDecimal", + "data_type": "float", + "nullable": true + }, + "longitude": { + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').address.extension.where(url='http://hl7.org/fhir/StructureDefinition/geolocation').extension.where(url='longitude').valueDecimal", + "data_type": "float", + "nullable": true + }, + "active_problems": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Condition').where(category.coding.code='problem-item-list')", + "data_type": "array", + "nullable": true, + "secondary_schema": { + "problem": { + "fhir_path": "Condition.code.coding.display", + "data_type": "string", + "nullable": true + }, + "problem_date": { + "fhir_path": "Condition.onsetDateTime", + "data_type": "datetime", + "nullable": true } - } + } + } } \ No newline at end of file diff --git a/containers/message-parser/app/main.py b/containers/message-parser/app/main.py index b907cf5f60..2131af870c 100644 --- a/containers/message-parser/app/main.py +++ b/containers/message-parser/app/main.py @@ -7,6 +7,7 @@ from app.utils import ( load_parsing_schema, get_parsers, + get_metadata, convert_to_fhir, get_credential_manager, search_for_required_values, @@ -69,6 +70,10 @@ class ParseMessageInput(BaseModel): "FHIR converter when conversion to FHIR is required.", default=None, ) + include_metadata: Optional[Literal["true", "false"]] = Field( + description="Boolean to include metadata in the response.", + default=None, + ) message: Union[str, dict] = Field(description="The message to be parsed.") @root_validator @@ -200,7 +205,8 @@ async def parse_message_endpoint( ) values.append(value) parsed_values[field] = values - + if input.include_metadata == "true": + parsed_values = get_metadata(parsed_values, parsing_schema) return {"message": "Parsing succeeded!", "parsed_values": parsed_values} diff --git a/containers/message-parser/app/utils.py b/containers/message-parser/app/utils.py index e7eb493061..03d1b3cc7d 100644 --- a/containers/message-parser/app/utils.py +++ b/containers/message-parser/app/utils.py @@ -12,6 +12,7 @@ from phdi.cloud.azure import AzureCredentialManager from phdi.cloud.core import BaseCredentialManager from phdi.cloud.gcp import GcpCredentialManager +import re @cache @@ -51,19 +52,16 @@ def freeze_parsing_schema(parsing_schema: dict) -> frozendict: :param parsing_schema: A dictionary containing a parsing schema. :return: A frozen dictionary containing the parsing schema. """ - for field, field_definition in parsing_schema.items(): - if "secondary_schema" in field_definition: - for secondary_field, secondary_field_definition in field_definition[ - "secondary_schema" - ].items(): - field_definition["secondary_schema"][secondary_field] = frozendict( - secondary_field_definition - ) - field_definition["secondary_schema"] = frozendict( - field_definition["secondary_schema"] - ) - parsing_schema[field] = frozendict(field_definition) - return frozendict(parsing_schema) + return freeze_parsing_schema_helper(parsing_schema) + + +# Recursive function to freeze sub dictionaries in the schema +def freeze_parsing_schema_helper(schema: dict) -> frozendict: + if type(schema) is dict: + for key, value in schema.items(): + if type(value) is dict: + schema[key] = freeze_parsing_schema_helper(value) + return frozendict(schema) # Using frozendict here to have an immutable that can be hashed for caching purposes. @@ -80,7 +78,6 @@ def get_parsers(extraction_schema: frozendict) -> frozendict: :return: A dictionary containing a FHIRpath parsers for each field in the provided schema. """ - parsers = {} for field, field_definiton in extraction_schema.items(): @@ -99,6 +96,41 @@ def get_parsers(extraction_schema: frozendict) -> frozendict: return frozendict(parsers) +def get_metadata(parsed_values: dict, schema): + data = {} + for key, value in parsed_values.items(): + if key not in schema: + data[key] = field_metadata(value=value) + else: + fhir_path = schema[key]["fhir_path"] if "fhir_path" in schema[key] else "" + match = re.search(r"resourceType\s*=\s*'([^']+)'", fhir_path) + resource_type = match.group(1) if match and match.group(1) else "" + data_type = schema[key]["data_type"] if "data_type" in schema[key] else "" + metadata = schema[key]["metadata"] if "metadata" in schema[key] else {} + data[key] = field_metadata( + value=value, + fhir_path=fhir_path, + data_type=data_type, + resource_type=resource_type, + metadata=metadata, + ) + return data + + +def field_metadata( + value="", fhir_path="", data_type="", resource_type="", metadata: dict = {} +): + data = { + "value": value, + "fhir_path": fhir_path, + "data_type": data_type, + "resource_type": resource_type, + } + for key, key_value in metadata.items(): + data[key] = key_value + return data + + def search_for_required_values(input: dict, required_values: list) -> str: """ Search for required values in the input dictionary and the environment. diff --git a/containers/message-parser/tests/test_parse_message_endpoint.py b/containers/message-parser/tests/test_parse_message_endpoint.py index d6392edfb9..1b65e879c7 100644 --- a/containers/message-parser/tests/test_parse_message_endpoint.py +++ b/containers/message-parser/tests/test_parse_message_endpoint.py @@ -47,6 +47,52 @@ }, } +expected_successful_response_with_meta_data = { + "message": "Parsing succeeded!", + "parsed_values": { + "first_name": { + "value": "John ", + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').name" + + ".first().given.first()", + "data_type": "string", + "resource_type": "Patient", + "category": "name", + }, + "last_name": { + "value": "doe", + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').name" + + ".first().family", + "data_type": "string", + "resource_type": "Patient", + }, + "latitude": { + "value": None, + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient')" + + ".address.extension.where" + + "(url='http://hl7.org/fhir/StructureDefinition/geolocation').extension." + + "where(url='latitude').valueDecimal", + "data_type": "float", + "resource_type": "Patient", + }, + "longitude": { + "value": None, + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').address" + + ".extension.where" + + "(url='http://hl7.org/fhir/StructureDefinition/geolocation').extension" + + ".where(url='longitude').valueDecimal", + "data_type": "float", + "resource_type": "Patient", + }, + "active_problems": { + "value": [], + "fhir_path": "Bundle.entry.resource.where(resourceType='Condition')" + + ".where(category.coding.code='problem-item-list')", + "data_type": "array", + "resource_type": "Condition", + }, + }, +} + expected_successful_response_floats = { "message": "Parsing succeeded!", "parsed_values": { @@ -58,6 +104,52 @@ }, } +expected_successful_response_floats_with_meta_data = { + "message": "Parsing succeeded!", + "parsed_values": { + "first_name": { + "value": "John ", + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').name" + + ".first().given.first()", + "data_type": "string", + "resource_type": "Patient", + "category": "name", + }, + "last_name": { + "value": "doe", + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').name" + + ".first().family", + "data_type": "string", + "resource_type": "Patient", + }, + "latitude": { + "value": "34.58002", + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').address" + + ".extension" + + ".where(url='http://hl7.org/fhir/StructureDefinition/geolocation')" + + ".extension.where(url='latitude').valueDecimal", + "data_type": "float", + "resource_type": "Patient", + }, + "longitude": { + "value": "-118.08925", + "fhir_path": "Bundle.entry.resource.where(resourceType = 'Patient').address" + + ".extension" + + ".where(url='http://hl7.org/fhir/StructureDefinition/geolocation')" + + ".extension.where(url='longitude').valueDecimal", + "data_type": "float", + "resource_type": "Patient", + }, + "active_problems": { + "value": [], + "fhir_path": "Bundle.entry.resource.where(resourceType='Condition')" + + ".where(category.coding.code='problem-item-list')", + "data_type": "array", + "resource_type": "Condition", + }, + }, +} + def test_parse_message_success_internal_schema(): test_request = { @@ -82,6 +174,30 @@ def test_parse_message_success_internal_schema(): assert actual_response2.json() == expected_successful_response_floats +def test_parse_message_success_internal_schema_with_metadata(): + test_request = { + "message_format": "fhir", + "parsing_schema_name": "test_schema.json", + "include_metadata": "true", + "message": fhir_bundle, + } + + actual_response = client.post("/parse_message", json=test_request) + assert actual_response.status_code == 200 + assert actual_response.json() == expected_successful_response_with_meta_data + + test_request2 = { + "message_format": "fhir", + "include_metadata": "true", + "parsing_schema_name": "test_schema.json", + "message": fhir_bundle_w_float, + } + + actual_response2 = client.post("/parse_message", json=test_request2) + assert actual_response2.status_code == 200 + assert actual_response2.json() == expected_successful_response_floats_with_meta_data + + def test_parse_message_success_external_schema(): request = { "message_format": "fhir", diff --git a/containers/message-parser/tests/test_utils.py b/containers/message-parser/tests/test_utils.py index 695b8924ee..0578702092 100644 --- a/containers/message-parser/tests/test_utils.py +++ b/containers/message-parser/tests/test_utils.py @@ -4,6 +4,7 @@ from frozendict import frozendict from unittest import mock import os + from app.utils import ( load_parsing_schema, get_parsers, @@ -11,6 +12,9 @@ search_for_required_values, convert_to_fhir, freeze_parsing_schema, + field_metadata, + get_metadata, + freeze_parsing_schema_helper, ) from app.config import get_settings @@ -170,3 +174,61 @@ def test_freeze_parsing_schema(): for key in test_schema: for subkey in test_schema[key]: assert test_schema[key][subkey] == frozen_schema[key][subkey] + + +def test_field_metadata(): + expected_result = { + "value": "foo", + "fhir_path": "bar", + "data_type": "biz", + "resource_type": "baz", + } + assert ( + field_metadata( + value="foo", fhir_path="bar", data_type="biz", resource_type="baz" + ) + == expected_result + ) + expected_result2 = { + "value": "", + "fhir_path": "", + "data_type": "", + "resource_type": "", + } + assert field_metadata() == expected_result2 + + +def test_get_metadata(): + example_parsed_values = {"foo": "bar", "fiz": "biz", "baz": "Null"} + example_schema = { + "foo": { + "fhir_path": "Bundle.entry.resource.where(resourceType='Foo').biz", + "data_type": "string", + "nullable": False, + "metadata": {"metaFoo": "metaFooData", "metaFiz": "metaFizData"}, + }, + "baz": {}, + } + expected_result = { + "foo": { + "value": "bar", + "fhir_path": "Bundle.entry.resource.where(resourceType='Foo').biz", + "data_type": "string", + "resource_type": "Foo", + "metaFoo": "metaFooData", + "metaFiz": "metaFizData", + }, + "fiz": {"value": "biz", "fhir_path": "", "data_type": "", "resource_type": ""}, + "baz": {"value": "Null", "fhir_path": "", "data_type": "", "resource_type": ""}, + } + result = get_metadata(parsed_values=example_parsed_values, schema=example_schema) + assert result == expected_result + + +def test_freeze_parsing_schema_helper(): + input = {"foo": "bar", "fiz": {"foo": "bar", "fiz": {"foo": "bar"}}} + output = freeze_parsing_schema_helper(input) + assert isinstance(output, frozendict) + assert isinstance(output["fiz"], frozendict) + assert isinstance(output["fiz"]["fiz"], frozendict) + assert isinstance(output["foo"], str)