async def test_async_fhir_client_patient_by_identifier_missing_true() -> None: # Arrange test_name = "test_fhir_client_patient_by_id_async" mock_server_url = "http://mock-server:1080" mock_client: MockServerFriendlyClient = MockServerFriendlyClient( base_url=mock_server_url) relative_url: str = test_name absolute_url: str = mock_server_url + "/" + test_name mock_client.clear(f"/{test_name}/*") mock_client.reset() response_text: str = json.dumps({"resourceType": "Patient", "id": "12355"}) mock_client.expect( mock_request( path=f"/{relative_url}/Patient", method="GET", querystring={"identifier:missing": "true"}, ), mock_response(body=response_text), timing=times(1), ) # Act fhir_client = FhirClient() fhir_client = (fhir_client.url(absolute_url).resource("Patient").filter( [PropertyMissingFilter(property_="identifier", missing=True)])) response: FhirGetResponse = await fhir_client.get_async() # Assert print(response.responses) assert response.responses == response_text
def test_fhir_client_patient_by_id() -> None: test_name = "test_fhir_client_patient_by_id" mock_server_url = "http://mock-server:1080" mock_client: MockServerFriendlyClient = MockServerFriendlyClient( base_url=mock_server_url ) relative_url: str = test_name absolute_url: str = mock_server_url + "/" + test_name mock_client.clear(f"/{test_name}/*.*") mock_client.reset() response_text: str = json.dumps({"resourceType": "Patient", "id": "12355"}) mock_client.expect( mock_request(path=f"/{relative_url}/Patient/12355", method="GET"), mock_response(body=response_text), timing=times(1), ) fhir_client = FhirClient() fhir_client = fhir_client.url(absolute_url).resource("Patient").id_("12355") response: FhirGetResponse = fhir_client.get() print(response.responses) assert response.responses == response_text
async def test_fhir_client_patient_delete_async() -> None: test_name = "test_fhir_client_patient_delete_async" mock_server_url = "http://mock-server:1080" mock_client: MockServerFriendlyClient = MockServerFriendlyClient( base_url=mock_server_url) relative_url: str = test_name absolute_url: str = mock_server_url + "/" + test_name mock_client.clear(f"/{test_name}/*.*") mock_client.reset() mock_client.expect( mock_request(path=f"/{relative_url}/Patient/12345", method="DELETE"), mock_response(code=204), timing=times(1), ) # Act fhir_client = FhirClient() fhir_client = fhir_client.url(absolute_url).resource("Patient").id_( "12345") response: FhirDeleteResponse = await fhir_client.delete_async() # Assert assert response.status == 204
async def test_fhir_client_patient_update_async() -> None: test_name = "test_fhir_client_patient_merge_async" mock_server_url = "http://mock-server:1080" mock_client: MockServerFriendlyClient = MockServerFriendlyClient( base_url=mock_server_url) relative_url: str = test_name absolute_url: str = mock_server_url + "/" + test_name mock_client.clear(f"/{test_name}/*.*") mock_client.reset() response_text_1: List[Dict[str, int]] = [{"created": 1, "updated": 0}] resource = {"resourceType": "Patient", "id": "12355"} # request_body = {"resourceType": "Bundle", "entry": [{"resource": resource}]} mock_client.expect( mock_request( path=f"/{relative_url}/Patient/12355", method="PUT", body=json.dumps(resource), ), mock_response(body=json.dumps(response_text_1)), timing=times(1), ) fhir_client = FhirClient() fhir_client = fhir_client.url(absolute_url).resource("Patient") fhir_client = fhir_client.id_(resource["id"]) response: FhirUpdateResponse = await fhir_client.update_async( json.dumps(resource)) assert not response.error
def test_fhir_client_patient_merge() -> None: with requests_mock.Mocker() as mock: url = "http://foo" request_data = {"resourceType": "Patient", "id": "12355"} response_json = [{"created": 1, "updated": 0}] def custom_matcher(request: Any) -> Optional[Response]: if request.path == "/patient/1/$merge" and request.text == json.dumps( [request_data]): resp: Response = requests.Response() resp.status_code = 200 return resp return None mock.post( f"{url}/Patient/1/$merge", additional_matcher=custom_matcher, text=f"{json.dumps(response_json)}", ) fhir_client = FhirClient() fhir_client = fhir_client.url(url).resource("Patient") response: FhirMergeResponse = fhir_client.merge( [json.dumps(request_data)]) print(response.responses) assert response.responses == response_json
def test_dev_server_auth() -> None: url = "https://fhir-auth.dev.bwell.zone/4_0_0" fhir_client = FhirClient() fhir_client = fhir_client.url(url).resource("Patient") fhir_client = fhir_client.client_credentials( client_id="4opocimdhppokn1ks0hpbo9fkv", client_secret="{Put secret here}" ).auth_scopes(["user/*.read"]) response: FhirGetResponse = fhir_client.get() print(response.responses)
def test_fhir_client_patient_by_id() -> None: with requests_mock.Mocker() as mock: url = "http://foo" response_text = {"resourceType": "Patient", "id": "12355"} mock.get(f"{url}/Patient/12355", json=response_text) fhir_client = FhirClient() fhir_client = fhir_client.url(url).resource("Patient").id_("12355") response: FhirGetResponse = fhir_client.get() print(response.responses) assert response.responses == json.dumps(response_text)
def test_fhir_client_patient_list_auth_fail() -> None: with requests_mock.Mocker() as mock: url = "http://foo" mock.get(f"{url}/Patient", status_code=403) fhir_client = FhirClient() fhir_client = fhir_client.url(url).resource("Patient") with pytest.raises(AssertionError): response: FhirGetResponse = fhir_client.get() print(response.responses) assert response.error == "403"
async def test_fhir_graph_async() -> None: test_name = "test_fhir_graph_async" mock_server_url = "http://mock-server:1080" mock_client: MockServerFriendlyClient = MockServerFriendlyClient( base_url=mock_server_url) relative_url: str = test_name absolute_url: str = mock_server_url + "/" + test_name mock_client.clear(f"/{test_name}/*.*") mock_client.reset() response_text = {"resourceType": "Patient", "id": "12355"} graph_definition = GraphDefinition( id_="123", name="my_everything", start="Patient", link=[ GraphDefinitionLink(target=[ GraphDefinitionTarget(type_="Location", params="managingOrganization={ref}") ]), GraphDefinitionLink(target=[ GraphDefinitionTarget( type_="HealthcareService", params="providedBy={ref}", link=[ GraphDefinitionLink(target=[ GraphDefinitionTarget(type_="Schedule", params="actor={ref}") ]) ], ) ]), ], ) mock_client.expect( mock_request(path=f"/{relative_url}/Patient/1/$graph", method="POST"), mock_response(body=response_text), timing=times(1), ) fhir_client = FhirClient() fhir_client = fhir_client.url(absolute_url).resource("Patient") response: FhirGetResponse = await fhir_client.graph_async( graph_definition=graph_definition, contained=False) assert json.loads(response.responses) == response_text
async def test_fhir_client_patient_list_auth_fail_retry_async() -> None: test_name = "test_fhir_client_patient_list_auth_fail_retry_async" mock_server_url = "http://mock-server:1080" mock_client: MockServerFriendlyClient = MockServerFriendlyClient( base_url=mock_server_url ) relative_url: str = test_name absolute_url: str = mock_server_url + "/" + test_name mock_client.clear(f"/{test_name}/*.*") mock_client.reset() mock_client.expect( mock_request(path=f"/{relative_url}/Patient", method="GET"), mock_response(code=401), timing=times(1), ) auth_response_text = { "access_token": "my_access_token", "expires_in": 86400, "token_type": "Bearer", } mock_client.expect( mock_request(path=f"/{relative_url}/auth", method="POST"), mock_response(code=200, body=auth_response_text), timing=times(1), ) response_text: str = json.dumps({"resourceType": "Patient", "id": "12355"}) mock_client.expect( mock_request(path=f"/{relative_url}/Patient", method="GET"), mock_response(body=response_text), timing=times(1), ) fhir_client = FhirClient() fhir_client = fhir_client.url(absolute_url).resource("Patient") fhir_client = fhir_client.client_credentials( client_id="client_id", client_secret="client_secret" ) fhir_client = fhir_client.auth_server_url(absolute_url + "/" + "auth").auth_scopes( ["user/*.ready"] ) response: FhirGetResponse = await fhir_client.get_async() print(response.responses) assert response.responses == response_text
async def test_fhir_client_patient_list_ids_async() -> None: test_name = "test_fhir_client_patient_list_ids_async" mock_server_url = "http://mock-server:1080" mock_client: MockServerFriendlyClient = MockServerFriendlyClient( base_url=mock_server_url) relative_url: str = test_name absolute_url: str = mock_server_url + "/" + test_name mock_client.clear(f"/{test_name}/*.*") mock_client.reset() last_updated_after = datetime.datetime.strptime("2022-01-10", "%Y-%m-%d") response_text: str = json.dumps([ { "resourceType": "Patient", "id": "12355" }, { "resourceType": "Patient", "id": "5555" }, ]) mock_client.expect( mock_request( path=f"/{relative_url}/Patient", method="GET", querystring={ "_elements": "id", "_count": "10000", "_getpagesoffset": "9", "_lastUpdated": "ge2022-01-10T00:00:00Z", }, ), mock_response(body=response_text), timing=times(1), ) fhir_client = FhirClient() fhir_client = fhir_client.url(absolute_url).resource("Patient") fhir_client = fhir_client.last_updated_after(last_updated_after) list_of_ids: List[str] = await fhir_client.get_ids_for_query_async() print(json.dumps(list_of_ids)) assert list_of_ids == ["12355", "5555"]
def test_dev_server_get_patients() -> None: clean_fhir_server() url = "http://fhir:3000/4_0_0" fhir_client = FhirClient() fhir_client = fhir_client.url(url).resource("Patient") resource = { "resourceType": "Patient", "id": "12355", "meta": { "security": [{ "system": "https://www.icanbwell.com/access", "code": "bwell" }] }, } merge_response: FhirMergeResponse = fhir_client.merge( [json.dumps(resource)]) print(merge_response.responses) assert merge_response.status == 200, merge_response.responses assert merge_response.responses[0][ "created"] is True, merge_response.responses fhir_client = fhir_client.url(url).resource("Patient") response: FhirGetResponse = fhir_client.get() print(response.responses) responses_ = json.loads(response.responses)[0] assert responses_["id"] == resource["id"] assert responses_["resourceType"] == resource["resourceType"]
def test_fhir_client_patient_list_auth_fail_retry() -> None: with requests_mock.Mocker() as mock: url = "http://foo" response_text = {"resourceType": "Patient", "id": "12355"} mock.get(f"{url}/Patient", [{ "status_code": 403 }, { "json": response_text }]) auth_response = { "access_token": "my_access_token", "expires_in": 86400, "token_type": "Bearer", } mock.post( "http://auth", [{ "status_code": 200 }, { "json": auth_response, "status_code": 200 }], ) fhir_client = FhirClient() fhir_client = fhir_client.url(url).resource("Patient") fhir_client = fhir_client.client_credentials( client_id="client_id", client_secret="client_secret") fhir_client = fhir_client.auth_server_url("http://auth").auth_scopes( ["user/*.ready"]) response: FhirGetResponse = fhir_client.get() print(response.responses) assert mock.call_count == 4, ",".join( [r.url for r in mock.request_history]) assert response.responses == json.dumps(response_text)
def test_dev_server_no_auth() -> None: url = "http://fhir:3000/4_0_0" fhir_client = FhirClient() fhir_client = fhir_client.url(url).resource("Patient") response: FhirGetResponse = fhir_client.get() print(response.responses)
async def test_fhir_client_patient_list_in_batches_async() -> None: test_name = "test_fhir_client_patient_list_in_batches_async" mock_server_url = "http://mock-server:1080" mock_client: MockServerFriendlyClient = MockServerFriendlyClient( base_url=mock_server_url ) relative_url: str = test_name absolute_url: str = mock_server_url + "/" + test_name mock_client.clear(f"/{test_name}/*.*") mock_client.reset() # this is the first call made by the first concurrent request mock_client.expect( mock_request( path=f"/{relative_url}/Patient", method="GET", querystring={ "_elements": "id", "_count": "1", "_getpagesoffset": "0", "_total": "accurate", }, ), mock_response( body=json.dumps( { "resourceType": "Bundle", "total": 2, "entry": [{"resource": {"id": "1"}}], } ) ), timing=times(1), ) # this is the second call made by first concurrent request mock_client.expect( mock_request( path=f"/{relative_url}/Patient", method="GET", querystring={ "_elements": "id", "_count": "1", "_getpagesoffset": "3", "_total": "accurate", "id:above": "1", }, ), mock_response( body=json.dumps( { "resourceType": "Bundle", "total": 2, "entry": [], } ) ), timing=times(1), ) # this is the first call made by the second concurrent request mock_client.expect( mock_request( path=f"/{relative_url}/Patient", method="GET", querystring={ "_elements": "id", "_count": "1", "_getpagesoffset": "1", "_total": "accurate", }, ), mock_response( body=json.dumps( { "resourceType": "Bundle", "total": 2, "entry": [{"resource": {"id": "2"}}], } ) ), timing=times(1), ) # this is the second call made by second concurrent request mock_client.expect( mock_request( path=f"/{relative_url}/Patient", method="GET", querystring={ "_elements": "id", "_count": "1", "_getpagesoffset": "3", "_total": "accurate", "id:above": "2", }, ), mock_response( body=json.dumps( { "resourceType": "Bundle", "total": 2, "entry": [], } ) ), timing=times(1), ) # this is the call made by the third concurrent request mock_client.expect( mock_request( path=f"/{relative_url}/Patient", method="GET", querystring={ "_elements": "id", "_count": "1", "_getpagesoffset": "2", "_total": "accurate", }, ), mock_response( body=json.dumps( { "resourceType": "Bundle", "total": 2, "entry": [], } ) ), timing=times(1), ) # now mock the actual calls to get resources response_text_1: Dict[str, Any] = { "resourceType": "Bundle", "total": 2, "entry": [ {"resource": {"resourceType": "Patient", "id": "1"}}, {"resource": {"resourceType": "Patient", "id": "2"}}, ], } mock_client.expect( mock_request( path=f"/{relative_url}/Patient", method="GET", querystring={ "id": "1,2", "_count": "1", "_getpagesoffset": "0", "_total": "accurate", }, ), mock_response(body=json.dumps(response_text_1)), timing=times(1), ) fhir_client = FhirClient() fhir_client = fhir_client.url(absolute_url).resource("Patient") fhir_client = fhir_client.page_size(10) fhir_client = fhir_client.include_total(True) def handle_batch( x: Optional[List[Dict[str, Any]]], page_number: Optional[int] ) -> bool: if x: resources_list.extend(x) return True resources_list: List[Dict[str, Any]] = [] response: List[Dict[str, Any]] = await fhir_client.get_resources_by_query_async( fn_handle_batch=handle_batch, page_size_for_retrieving_ids=1, page_size_for_retrieving_resources=2, concurrent_requests=3, ) print(response) assert response == [] assert len(resources_list) == 2 print(resources_list) assert resources_list == [ {"resourceType": "Patient", "id": "1"}, {"resourceType": "Patient", "id": "2"}, ]
def test_fhir_client_bundle_separated() -> None: test_name = "test_fhir_client_bundle_separated" mock_server_url = "http://mock-server:1080" mock_client: MockServerFriendlyClient = MockServerFriendlyClient( base_url=mock_server_url) relative_url: str = test_name absolute_url: str = mock_server_url + "/" + test_name mock_client.clear(f"/{test_name}/*.*") mock_client.reset() test_path = Path(__file__).parent with open(test_path.joinpath("../practitioner_graph_sample.json")) as f: response_text = json.load(f) action_payload = { "resourceType": "GraphDefinition", "id": "o", "name": "provider_everything", "status": "active", "start": "Practitioner", "link": [{ "description": "Practitioner Roles for this Practitioner", "target": [{ "type": "PractitionerRole", "params": "practitioner={ref}", "link": [ { "path": "organization", "target": [{ "type": "Organization" }], }, { "path": "location[x]", "target": [{ "type": "Location" }], }, { "path": "healthcareService[x]", "target": [{ "type": "HealthcareService" }], }, ], }], }], } mock_client.expect( mock_request( path=f"/{relative_url}/Patient/$graph", method="POST", querystring={ "id": "1053306548,1710949219", "contained": "true" }, ), mock_response(body=response_text), timing=times(1), ) fhir_client = (FhirClient().action("$graph").id_( ["1710949219", "1053306548"]).additional_parameters([ "&contained=true" ]).action_payload(action_payload).separate_bundle_resources(True)) fhir_client = fhir_client.url(absolute_url).resource("Patient") response: FhirGetResponse = fhir_client.get() with open(test_path.joinpath( "./practitioner_graph_sample_separated.json")) as f: expected_response = json.load(f) assert json.loads(response.responses) == expected_response
def test_fhir_client_bundle() -> None: with requests_mock.Mocker() as mock: url = "http://foo" response_text = { "resourceType": "Bundle", "id": "1437321965", "entry": [ { "link": "https://localhost:3000/4_0_0/Practitioner/1437321965", "resource": { "resourceType": "Practitioner", "id": "1437321965", "meta": { "versionId": "1", "lastUpdated": "2021-01-13T04:37:06+00:00", "source": "http://medstarhealth.org/provider", }, "identifier": [ { "use": "usual", "type": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/v2-0203", "code": "PRN", }] }, "system": "http://medstarhealth.org", "value": "500524", }, { "use": "official", "type": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/v2-0203", "code": "NPI", }] }, "system": "http://hl7.org/fhir/sid/us-npi", "value": "1437321965", }, ], "active": True, "name": [{ "use": "usual", "text": "ZOOVIA AMAN MD", "family": "AMAN", "given": ["ZOOVIA", ""], }], "gender": "female", "qualification": [ { "code": { "coding": [{ "system": "http://terminology.hl7.org/ValueSet/v2-2.7-030", "code": "MD", }] } }, { "code": { "coding": [{ "system": "http://terminology.hl7.org/ValueSet/v2-2.7-030", "code": "MD", }] }, "period": { "start": "2011-01-01", "end": "2023-12-31" }, "issuer": { "reference": "Organization/Harpers_Ferry_Family_Medicine" }, }, ], "communication": [{ "coding": [{ "system": "urn:ietf:bcp:47", "code": "en" }] }], }, }, { "link": "https://localhost:3000/4_0_0/PractitionerRole/1437321965-ML1-MLSW", "resource": { "resourceType": "PractitionerRole", "id": "1437321965-ML1-MLSW", "meta": { "versionId": "1", "lastUpdated": "2021-01-13T04:37:24+00:00", "source": "http://medstarhealth.org/provider", }, "practitioner": { "reference": "Practitioner/1437321965" }, "organization": { "reference": "Organization/Medstar-15888213" }, "code": [{ "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/practitioner-role", "code": "doctor", "display": "Doctor", }], "text": "Doctor", }], "specialty": [ { "coding": [{ "system": "https://www.http://medstarhealth.org", "code": "Family Medicine", "display": "Family Medicine", }], "text": "Family Medicine", }, { "coding": [{ "system": "http://nucc.org/provider-taxonomy", "code": "207Q00000X", "display": "Family Medicine", }], "text": "Family Medicine", }, { "coding": [{ "system": "http://nucc.org/provider-taxonomy", "code": "261QP2300X", "display": "Primary Care", }], "text": "Primary Care", }, ], "location": [{ "reference": "Location/Medstar-Alias-ML1-MLSW" }], }, }, ], } expected_response = { "practitioner": [{ "resourceType": "Practitioner", "id": "1437321965", "meta": { "versionId": "1", "lastUpdated": "2021-01-13T04:37:06+00:00", "source": "http://medstarhealth.org/provider", }, "identifier": [ { "use": "usual", "type": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/v2-0203", "code": "PRN", }] }, "system": "http://medstarhealth.org", "value": "500524", }, { "use": "official", "type": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/v2-0203", "code": "NPI", }] }, "system": "http://hl7.org/fhir/sid/us-npi", "value": "1437321965", }, ], "active": True, "name": [{ "use": "usual", "text": "ZOOVIA AMAN MD", "family": "AMAN", "given": ["ZOOVIA", ""], }], "gender": "female", "qualification": [ { "code": { "coding": [{ "system": "http://terminology.hl7.org/ValueSet/v2-2.7-030", "code": "MD", }] } }, { "code": { "coding": [{ "system": "http://terminology.hl7.org/ValueSet/v2-2.7-030", "code": "MD", }] }, "period": { "start": "2011-01-01", "end": "2023-12-31" }, "issuer": { "reference": "Organization/Harpers_Ferry_Family_Medicine" }, }, ], "communication": [{ "coding": [{ "system": "urn:ietf:bcp:47", "code": "en" }] }], }], "practitionerrole": [{ "resourceType": "PractitionerRole", "id": "1437321965-ML1-MLSW", "meta": { "versionId": "1", "lastUpdated": "2021-01-13T04:37:24+00:00", "source": "http://medstarhealth.org/provider", }, "practitioner": { "reference": "Practitioner/1437321965" }, "organization": { "reference": "Organization/Medstar-15888213" }, "code": [{ "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/practitioner-role", "code": "doctor", "display": "Doctor", }], "text": "Doctor", }], "specialty": [ { "coding": [{ "system": "https://www.http://medstarhealth.org", "code": "Family Medicine", "display": "Family Medicine", }], "text": "Family Medicine", }, { "coding": [{ "system": "http://nucc.org/provider-taxonomy", "code": "207Q00000X", "display": "Family Medicine", }], "text": "Family Medicine", }, { "coding": [{ "system": "http://nucc.org/provider-taxonomy", "code": "261QP2300X", "display": "Primary Care", }], "text": "Primary Care", }, ], "location": [{ "reference": "Location/Medstar-Alias-ML1-MLSW" }], }], } mock.get(f"{url}/Patient", json=response_text) fhir_client = FhirClient().separate_bundle_resources(True) fhir_client = fhir_client.url(url).resource("Patient") response: FhirGetResponse = fhir_client.get() print(response.responses) assert response.responses == json.dumps(expected_response)