Skip to content

Commit 42e28df

Browse files
committed
Move FHIR constants to single enum
1 parent 6db5298 commit 42e28df

16 files changed

Lines changed: 369 additions & 70 deletions

File tree

gateway-api/scripts/call_gateway.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from uuid import uuid4
88

99
import requests
10+
from fhir.constants import FHIRSystem
1011

1112

1213
def main() -> None:
@@ -43,7 +44,7 @@ def main() -> None:
4344
{
4445
"name": "patientNHSNumber",
4546
"valueIdentifier": {
46-
"system": "https://fhir.nhs.uk/Id/nhs-number",
47+
"system": FHIRSystem.NHS_NUMBER,
4748
"value": args.nhs_number,
4849
},
4950
}

gateway-api/scripts/test_call_gateway.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import pytest
99
import requests
1010
from call_gateway import main
11+
from fhir.constants import FHIRSystem
1112

1213

1314
class TestCallGateway:
@@ -122,7 +123,7 @@ def test_request_payload_structure(self, monkeypatch: pytest.MonkeyPatch) -> Non
122123
assert payload["parameter"][0]["name"] == "patientNHSNumber"
123124
assert (
124125
payload["parameter"][0]["valueIdentifier"]["system"]
125-
== "https://fhir.nhs.uk/Id/nhs-number"
126+
== FHIRSystem.NHS_NUMBER
126127
)
127128
assert payload["parameter"][0]["valueIdentifier"]["value"] == nhs_number
128129

gateway-api/src/fhir/constants.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from enum import StrEnum
2+
3+
4+
class FHIRSystem(StrEnum):
5+
"""
6+
Enum for FHIR identifier systems used in the clinical data gateway.
7+
"""
8+
9+
NHS_NUMBER = "https://fhir.nhs.uk/Id/nhs-number"
10+
ODS_CODE = "https://fhir.nhs.uk/Id/ods-organization-code"
11+
SDS_USER_ID = "https://fhir.nhs.uk/Id/sds-user-id"
12+
SDS_ROLE_PROFILE_ID = "https://fhir.nhs.uk/Id/sds-role-profile-id"
13+
NHS_SERVICE_INTERACTION_ID = "https://fhir.nhs.uk/Id/nhsServiceInteractionId"
14+
NHS_MHS_PARTY_KEY = "https://fhir.nhs.uk/Id/nhsMhsPartyKey"
15+
NHS_SPINE_ASID = "https://fhir.nhs.uk/Id/nhsSpineASID"

gateway-api/src/gateway_api/clinical_jwt/organization.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from dataclasses import dataclass
22
from typing import Any
33

4+
from fhir.constants import FHIRSystem
5+
46

57
@dataclass(frozen=True, kw_only=True)
68
class Organization:
@@ -15,7 +17,7 @@ def to_dict(self) -> dict[str, Any]:
1517
"resourceType": "Organization",
1618
"identifier": [
1719
{
18-
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
20+
"system": FHIRSystem.ODS_CODE,
1921
"value": self.ods_code,
2022
}
2123
],

gateway-api/src/gateway_api/clinical_jwt/practitioner.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from dataclasses import dataclass
22
from typing import Any
33

4+
from fhir.constants import FHIRSystem
5+
46

57
@dataclass(frozen=True, kw_only=True)
68
class Practitioner:
@@ -26,8 +28,8 @@ def to_dict(self) -> dict[str, Any]:
2628
"""
2729
Return the Practitioner as a dictionary suitable for JWT payload.
2830
"""
29-
user_id_system = "https://fhir.nhs.uk/Id/sds-user-id"
30-
role_id_system = "https://fhir.nhs.uk/Id/sds-role-profile-id"
31+
user_id_system = FHIRSystem.SDS_USER_ID
32+
role_id_system = FHIRSystem.SDS_ROLE_PROFILE_ID
3133

3234
return {
3335
"resourceType": "Practitioner",

gateway-api/src/gateway_api/conftest.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import pytest
88
import requests
99
from fhir import Bundle, OperationOutcome, Patient
10+
from fhir.constants import FHIRSystem
1011
from fhir.parameters import Parameters
1112
from flask import Request
1213
from requests.structures import CaseInsensitiveDict
@@ -62,7 +63,7 @@ def valid_simple_request_payload() -> Parameters:
6263
{
6364
"name": "patientNHSNumber",
6465
"valueIdentifier": {
65-
"system": "https://fhir.nhs.uk/Id/nhs-number",
66+
"system": FHIRSystem.NHS_NUMBER,
6667
"value": "9999999999",
6768
},
6869
},
@@ -103,7 +104,7 @@ def valid_simple_response_payload() -> Bundle:
103104
"identifier": {
104105
"value": "A12345",
105106
"period": {"start": "2020-01-01", "end": "9999-12-31"},
106-
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
107+
"system": FHIRSystem.ODS_CODE,
107108
},
108109
}
109110
],
@@ -143,7 +144,7 @@ def happy_path_pds_response_body() -> Patient:
143144
"identifier": {
144145
"value": "A12345",
145146
"period": {"start": "2020-01-01", "end": "9999-12-31"},
146-
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
147+
"system": FHIRSystem.ODS_CODE,
147148
},
148149
}
149150
],
@@ -174,7 +175,7 @@ def valid_jwt() -> JWT:
174175
"resourceType": "Organization",
175176
"identifier": [
176177
{
177-
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
178+
"system": FHIRSystem.ODS_CODE,
178179
"value": "T1234",
179180
}
180181
],
@@ -184,9 +185,9 @@ def valid_jwt() -> JWT:
184185
"resourceType": "Practitioner",
185186
"id": "prac123",
186187
"identifier": [
187-
{"system": "https://fhir.nhs.uk/Id/sds-user-id", "value": "user123"},
188+
{"system": FHIRSystem.SDS_USER_ID, "value": "user123"},
188189
{
189-
"system": "https://fhir.nhs.uk/Id/sds-role-profile-id",
190+
"system": FHIRSystem.SDS_ROLE_PROFILE_ID,
190191
"value": "role123",
191192
},
192193
{"system": "https://example.com/userid", "value": "userid123"},

gateway-api/src/gateway_api/pds/test_client.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import pytest
1010
from fhir import Patient
11+
from fhir.constants import FHIRSystem
1112
from pytest_mock import MockerFixture
1213

1314
from gateway_api.common.error import PdsRequestFailedError
@@ -144,7 +145,7 @@ def test_search_patient_by_nhs_number_finds_current_gp_ods_code_when_pds_returns
144145
"identifier": {
145146
"value": "OLDGP",
146147
"period": {"start": "2010-01-01", "end": "2012-01-01"},
147-
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
148+
"system": FHIRSystem.ODS_CODE,
148149
},
149150
}
150151
current_gp: GeneralPractitioner = {
@@ -153,7 +154,7 @@ def test_search_patient_by_nhs_number_finds_current_gp_ods_code_when_pds_returns
153154
"identifier": {
154155
"value": "CURRGP",
155156
"period": {"start": "2020-01-01", "end": "9999-01-01"},
156-
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
157+
"system": FHIRSystem.ODS_CODE,
157158
},
158159
}
159160
pds_response_body_with_two_gps = happy_path_pds_response_body.copy()
@@ -187,7 +188,7 @@ def test_find_current_gp_with_today_override() -> None:
187188
"identifier": {
188189
"value": "a",
189190
"period": {"start": "2020-01-01", "end": "2020-12-31"},
190-
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
191+
"system": FHIRSystem.ODS_CODE,
191192
},
192193
},
193194
{
@@ -196,7 +197,7 @@ def test_find_current_gp_with_today_override() -> None:
196197
"identifier": {
197198
"value": "b",
198199
"period": {"start": "2021-01-01", "end": "2021-12-31"},
199-
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
200+
"system": FHIRSystem.ODS_CODE,
200201
},
201202
},
202203
]
@@ -349,7 +350,7 @@ def test_find_current_gp_ignore_dates_returns_last_or_none() -> None:
349350
"identifier": {
350351
"value": "GP-OLD",
351352
"period": {"start": "1900-01-01", "end": "1900-12-31"},
352-
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
353+
"system": FHIRSystem.ODS_CODE,
353354
},
354355
},
355356
{
@@ -358,7 +359,7 @@ def test_find_current_gp_ignore_dates_returns_last_or_none() -> None:
358359
"identifier": {
359360
"value": "GP-NEWER",
360361
"period": {"start": "1901-01-01", "end": "1901-12-31"},
361-
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
362+
"system": FHIRSystem.ODS_CODE,
362363
},
363364
},
364365
]

gateway-api/src/gateway_api/sds/client.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from enum import StrEnum
1313
from typing import Any, cast
1414

15+
from fhir.constants import FHIRSystem
1516
from stubs import SdsFhirApiStub
1617

1718
from gateway_api.get_structured_record import ACCESS_RECORD_STRUCTURED_INTERACTION_ID
@@ -76,12 +77,6 @@ class SdsClient:
7677
SANDBOX_URL = "https://sandbox.api.service.nhs.uk/spine-directory/FHIR/R4"
7778
INT_URL = "https://int.api.service.nhs.uk/spine-directory/FHIR/R4"
7879

79-
# FHIR identifier systems
80-
ODS_SYSTEM = "https://fhir.nhs.uk/Id/ods-organization-code"
81-
INTERACTION_SYSTEM = "https://fhir.nhs.uk/Id/nhsServiceInteractionId"
82-
PARTYKEY_SYSTEM = "https://fhir.nhs.uk/Id/nhsMhsPartyKey"
83-
ASID_SYSTEM = "https://fhir.nhs.uk/Id/nhsSpineASID"
84-
8580
# Default service interaction ID for GP Connect
8681
DEFAULT_SERVICE_INTERACTION_ID = ACCESS_RECORD_STRUCTURED_INTERACTION_ID
8782

@@ -138,8 +133,8 @@ def get_org_details(
138133

139134
# TODO: Post-steel-thread handle case where no device is found for ODS code
140135

141-
asid = self._extract_identifier(device, self.ASID_SYSTEM)
142-
party_key = self._extract_identifier(device, self.PARTYKEY_SYSTEM)
136+
asid = self._extract_identifier(device, FHIRSystem.NHS_SPINE_ASID)
137+
party_key = self._extract_identifier(device, FHIRSystem.NHS_MHS_PARTY_KEY)
143138

144139
# Step 2: Get Endpoint to obtain endpoint URL
145140
endpoint_url: str | None = None
@@ -190,12 +185,14 @@ def _query_sds(
190185
url = f"{self.base_url}/{querytype.value}"
191186

192187
params: dict[str, Any] = {
193-
"organization": f"{self.ODS_SYSTEM}|{ods_code}",
194-
"identifier": [f"{self.INTERACTION_SYSTEM}|{self.service_interaction_id}"],
188+
"organization": f"{FHIRSystem.ODS_CODE}|{ods_code}",
189+
"identifier": [
190+
f"{FHIRSystem.NHS_SERVICE_INTERACTION_ID}|{self.service_interaction_id}"
191+
],
195192
}
196193

197194
if party_key is not None:
198-
params["identifier"].append(f"{self.PARTYKEY_SYSTEM}|{party_key}")
195+
params["identifier"].append(f"{FHIRSystem.NHS_MHS_PARTY_KEY}|{party_key}")
199196

200197
response = get(
201198
url,

gateway-api/src/gateway_api/sds/test_client.py

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from __future__ import annotations
66

77
import pytest
8+
from fhir.constants import FHIRSystem
89
from stubs.sds.stub import SdsFhirApiStub
910

1011
from gateway_api.get_structured_record import ACCESS_RECORD_STRUCTURED_INTERACTION_ID
@@ -70,17 +71,17 @@ def test_sds_client_get_org_details_with_endpoint(
7071
"id": "test-device-id",
7172
"identifier": [
7273
{
73-
"system": "https://fhir.nhs.uk/Id/nhsSpineASID",
74+
"system": FHIRSystem.NHS_SPINE_ASID,
7475
"value": "999999999999",
7576
},
7677
{
77-
"system": "https://fhir.nhs.uk/Id/nhsMhsPartyKey",
78+
"system": FHIRSystem.NHS_MHS_PARTY_KEY,
7879
"value": "TESTORG-123456",
7980
},
8081
],
8182
"owner": {
8283
"identifier": {
83-
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
84+
"system": FHIRSystem.ODS_CODE,
8485
"value": "TESTORG",
8586
}
8687
},
@@ -98,13 +99,13 @@ def test_sds_client_get_org_details_with_endpoint(
9899
"address": "https://testorg.example.com/fhir",
99100
"managingOrganization": {
100101
"identifier": {
101-
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
102+
"system": FHIRSystem.ODS_CODE,
102103
"value": "TESTORG",
103104
}
104105
},
105106
"identifier": [
106107
{
107-
"system": "https://fhir.nhs.uk/Id/nhsMhsPartyKey",
108+
"system": FHIRSystem.NHS_MHS_PARTY_KEY,
108109
"value": "TESTORG-123456",
109110
}
110111
],
@@ -179,13 +180,13 @@ def test_sds_client_custom_service_interaction_id(
179180
"id": "custom-device",
180181
"identifier": [
181182
{
182-
"system": "https://fhir.nhs.uk/Id/nhsSpineASID",
183+
"system": FHIRSystem.NHS_SPINE_ASID,
183184
"value": "777777777777",
184185
}
185186
],
186187
"owner": {
187188
"identifier": {
188-
"system": "https://fhir.nhs.uk/Id/ods-organization-code",
189+
"system": FHIRSystem.ODS_CODE,
189190
"value": "CUSTOMINT",
190191
}
191192
},
@@ -226,16 +227,13 @@ def test_sds_client_builds_correct_device_query_params(
226227
params = stub.get_params
227228

228229
# Check organization parameter
229-
assert (
230-
params["organization"]
231-
== "https://fhir.nhs.uk/Id/ods-organization-code|PROVIDER"
232-
)
230+
assert params["organization"] == f"{FHIRSystem.ODS_CODE}|PROVIDER"
233231

234232
# Check identifier list contains interaction ID
235233
identifiers = params["identifier"]
236234
assert isinstance(identifiers, list)
237235
assert any(
238-
"https://fhir.nhs.uk/Id/nhsServiceInteractionId|" in str(ident)
236+
f"{FHIRSystem.NHS_SERVICE_INTERACTION_ID}|" in str(ident)
239237
for ident in identifiers
240238
)
241239

@@ -261,11 +259,11 @@ def test_sds_client_extract_party_key_from_device(
261259
"id": "device-with-party-key",
262260
"identifier": [
263261
{
264-
"system": "https://fhir.nhs.uk/Id/nhsSpineASID",
262+
"system": FHIRSystem.NHS_SPINE_ASID,
265263
"value": "888888888888",
266264
},
267265
{
268-
"system": "https://fhir.nhs.uk/Id/nhsMhsPartyKey",
266+
"system": FHIRSystem.NHS_MHS_PARTY_KEY,
269267
"value": "WITHPARTYKEY-654321",
270268
},
271269
],
@@ -283,7 +281,7 @@ def test_sds_client_extract_party_key_from_device(
283281
"address": "https://withpartykey.example.com/fhir",
284282
"identifier": [
285283
{
286-
"system": "https://fhir.nhs.uk/Id/nhsMhsPartyKey",
284+
"system": FHIRSystem.NHS_MHS_PARTY_KEY,
287285
"value": "WITHPARTYKEY-654321",
288286
}
289287
],
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Scripts package for gateway-api utility scripts."""

0 commit comments

Comments
 (0)