Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ app-docker-run:
docker run -p 9000:9000 "$(PROXYGEN_DOCKER_REGISTRY_URL):$(CONTAINER_TAG)"

app-unit-test:
uv run pytest app --cov=app --cov-fail-under=80
uv run pytest app --cov=app --cov-fail-under=80 $(PYTEST_ARGS)

# ==============================================================================
# Sandbox Commands
Expand Down
9 changes: 8 additions & 1 deletion app/api/domain/forward_response_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
from pydantic.alias_generators import to_camel


class Permissions(BaseModel):
"""A data model that encapsulates all the essential permissions data."""


class Demographics(BaseModel):
"""A data model that encapsulates all the essential demographic data."""

Expand All @@ -10,6 +14,8 @@ class Demographics(BaseModel):
first_name: str
surname: str
title: str
date_of_birth: str
permissions: Permissions


class ForwardResponse(BaseModel):
Expand All @@ -19,7 +25,8 @@ class ForwardResponse(BaseModel):

session_id: str
supplier: str
proxy: Demographics
ods_code: str
user: Demographics
patients: list[Demographics]

@field_validator("patients")
Expand Down
25 changes: 22 additions & 3 deletions app/api/domain/tests/test_forward_response_model.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from app.api.domain.forward_response_model import Demographics, ForwardResponse
from app.api.domain.forward_response_model import (
Demographics,
ForwardResponse,
Permissions,
)


def test_forward_response() -> None:
Expand All @@ -7,6 +11,21 @@ def test_forward_response() -> None:
ForwardResponse(
sessionId="some session id",
supplier="some supplier",
proxy=Demographics(firstName="Betty", surname="Jones", title="Ms"),
patients=[Demographics(firstName="John", surname="Jones", title="Mr")],
odsCode="some ods code",
user=Demographics(
firstName="Betty",
surname="Jones",
title="Ms",
dateOfBirth="12/03/1965",
permissions=Permissions(),
),
patients=[
Demographics(
firstName="John",
surname="Jones",
title="Mr",
dateOfBirth="18/05/1966",
permissions=Permissions(),
),
],
)
62 changes: 51 additions & 11 deletions app/api/infrastructure/emis/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@
InvalidValueError,
NotFoundError,
)
from app.api.domain.forward_response_model import Demographics
from app.api.infrastructure.emis.models import (
EffectiveServices,
Identifier,
MedicalRecordPermissions,
Patient,
Permissions,
SessionRequestData,
SessionRequestHeaders,
SessionResponse,
Expand Down Expand Up @@ -96,16 +95,45 @@ def transform_response(self, response: dict) -> SessionResponse:
Returns:
SessionResponse: Homogenised response with other clients
"""
# UserPatientLinks relating the user to their patient details
user_self_links = [
patient_link
for patient_link in response.get("UserPatientLinks", [])
if patient_link.get("AssociationType") == "Self"
]

# UserPatientLinks relating the user to patients they can act on behalf of
user_patient_links = [
patient_link
for patient_link in response.get("UserPatientLinks", [])
if patient_link.get("AssociationType") == "Proxy"
]

return SessionResponse(
sessionId=response.get("SessionId"),
endUserSessionId=response.get("EndUserSessionId"),
supplier=self.supplier,
proxy=Demographics(
odsCode=self.request.patient_ods_code,
user=Patient(
firstName=response.get("FirstName"),
surname=response.get("Surname"),
title=response.get("Title"),
dateOfBirth=user_self_links[0].get("DateOfBirth")
if user_self_links
else None,
userPatientLinkToken=user_self_links[0].get("UserPatientLinkToken")
if user_self_links
else None,
patientIdentifiers=self._parse_identifiers(
response.get("UserPatientIdentifiers", [])
),
permissions=self._parse_permissions(
user_self_links[0].get("EffectiveServices", {})
if user_self_links
else {}
),
),
Comment thread
ehallam marked this conversation as resolved.
patients=self._parse_patients(response),
patients=self._parse_patients(user_patient_links),
)

def _mock_response(self) -> dict:
Expand All @@ -117,17 +145,15 @@ def _mock_response(self) -> dict:
with Path((BASE_DIR) / "data" / "mocked_response.json").open("r") as f:
return load(f)

def _parse_patients(self, data: dict) -> list[Patient]:
def _parse_patients(self, patient_links: list) -> list[Patient]:
"""Parsing raw data from Client into structual model.

Args:
data (dict): Raw data containing information about multiple patients
patient_links (dict): Raw data containing information about patients

Returns:
list[Patient]: Parsed information about multiple patients
list[Patient]: Parsed information about patients
"""
# Extra Patient data
patient_links = data.get("UserPatientLinks", [])
parsed_patients = []
for patient in patient_links:
raw_permissions = patient.get("EffectiveServices", {})
Expand All @@ -136,13 +162,18 @@ def _parse_patients(self, data: dict) -> list[Patient]:
firstName=patient.get("FirstName"),
surname=patient.get("Surname"),
title=patient.get("Title"),
dateOfBirth=patient.get("DateOfBirth"),
userPatientLinkToken=patient.get("UserPatientLinkToken"),
patientIdentifiers=self._parse_identifiers(
patient.get("PatientIdentifiers", [])
),
permissions=self._parse_permissions(raw_permissions),
)
)
return parsed_patients

def _parse_permissions(self, raw_permissions: dict) -> Permissions:
return Permissions(
def _parse_permissions(self, raw_permissions: dict) -> EffectiveServices:
return EffectiveServices(
appointmentsEnabled=raw_permissions.get("AppointmentsEnabled"),
demographicsUpdateEnabled=raw_permissions.get("DemographicsUpdateEnabled"),
epsEnabled=raw_permissions.get("EpsEnabled"),
Expand Down Expand Up @@ -181,3 +212,12 @@ def _parse_permissions(self, raw_permissions: dict) -> Permissions:
),
),
)

def _parse_identifiers(self, raw_identifiers: list) -> list[Identifier]:
return [
Identifier(
value=identifier.get("IdentifierValue"),
type=identifier.get("IdentifierType"),
)
for identifier in raw_identifiers
]
17 changes: 13 additions & 4 deletions app/api/infrastructure/emis/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel

from app.api.domain.forward_response_model import Demographics, ForwardResponse
from app.api.domain.forward_response_model import (
Demographics,
ForwardResponse,
Permissions,
)


class Identifier(BaseModel):
Expand Down Expand Up @@ -62,7 +66,7 @@ class MedicalRecordPermissions(BaseModel):
test_results_enabled: bool


class Permissions(BaseModel):
class EffectiveServices(Permissions):
"""Base Model for Permissions."""

model_config = ConfigDict(alias_generator=to_camel)
Expand All @@ -80,9 +84,13 @@ class Permissions(BaseModel):


class Patient(Demographics):
"""Base Model for Patient."""
"""Base Model for User and Patient."""

permissions: Permissions
model_config = ConfigDict(alias_generator=to_camel)

user_patient_link_token: str
patient_identifiers: list[Identifier]
permissions: EffectiveServices


class SessionResponse(ForwardResponse):
Expand All @@ -91,4 +99,5 @@ class SessionResponse(ForwardResponse):
model_config = ConfigDict(alias_generator=to_camel)

end_user_session_id: str
user: Patient
patients: list[Patient]
Loading
Loading