|
1 | 1 | from logging import INFO, basicConfig, getLogger |
2 | 2 | from typing import Union |
3 | | - |
4 | 3 | from flask import Flask, request |
5 | 4 |
|
6 | 5 | from .constants import ( |
|
13 | 12 | RELATED__VERIFY_RELATIONSHIP_25, |
14 | 13 | RELATED__VERIFY_RELATIONSHIP_09_WITH_INCLUDE, |
15 | 14 | RELATED__VERIFY_RELATIONSHIP_25_WITH_INCLUDE, |
16 | | - CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP, |
17 | | - CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP_INCLUDE_BOTH, |
18 | | - CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP, |
19 | | - CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP_INCLUDE_BOTH, |
20 | | - CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_BOTH, |
21 | | - CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PERFORMER, |
22 | | - CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PATIENT, |
23 | | - CONSENT__MULTIPLE_RELATIONSHIPS, |
24 | | - CONSENT__NO_RELATIONSHIPS, |
25 | | - CONSENT__FILTERED_RELATIONSHIPS_STATUS_ACTIVE, |
26 | | - CONSENT__FILTERED_RELATIONSHIPS_STATUS_INACTIVE, |
27 | | - CONSENT__FILTERED_RELATIONSHIPS_STATUS_PROPOSED_ACTIVE, |
| 15 | + GET_CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP, |
| 16 | + GET_CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP_INCLUDE_BOTH, |
| 17 | + GET_CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP, |
| 18 | + GET_CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP_INCLUDE_BOTH, |
| 19 | + GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_BOTH, |
| 20 | + GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PERFORMER, |
| 21 | + GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PATIENT, |
| 22 | + GET_CONSENT__MULTIPLE_RELATIONSHIPS, |
| 23 | + GET_CONSENT__NO_RELATIONSHIPS, |
| 24 | + GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_ACTIVE, |
| 25 | + GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_INACTIVE, |
| 26 | + GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_PROPOSED_ACTIVE, |
| 27 | + POST_CONSENT__SUCCESS, |
| 28 | + POST_CONSENT__DUPLICATE_RELATIONSHIP_ERROR, |
| 29 | + POST_CONSENT__INVALID_ACCESS_LEVEL_ERROR, |
| 30 | + POST_CONSENT__INVALID_EVIDENCE_ERROR, |
| 31 | + POST_CONSENT__INVALID_PATIENT_AGE_ERROR, |
| 32 | + POST_CONSENT__PERFORMER_IDENTIFIER_ERROR, |
28 | 33 | ) |
29 | 34 | from .utils import ( |
30 | 35 | check_for_empty, |
|
41 | 46 | app = Flask(__name__) |
42 | 47 | basicConfig(level=INFO, format="%(asctime)s - %(message)s") |
43 | 48 | logger = getLogger(__name__) |
| 49 | +APP_BASE_PATH = "https://sandbox.api.service.nhs.uk/validated-relationships/FHIR/R4/Consent" |
44 | 50 | COMMON_PATH = "FHIR/R4" |
45 | 51 |
|
46 | 52 |
|
@@ -147,40 +153,92 @@ def get_consent() -> Union[dict, tuple]: |
147 | 153 | if performer_identifier == "9000000010": |
148 | 154 | return check_for_consent_include_params( |
149 | 155 | _include, |
150 | | - CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP, |
151 | | - CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP_INCLUDE_BOTH, |
| 156 | + GET_CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP, |
| 157 | + GET_CONSENT__SINGLE_CONSENTING_ADULT_RELATIONSHIP_INCLUDE_BOTH, |
152 | 158 | ) |
153 | 159 | # Single mother child relationship |
154 | 160 | elif performer_identifier == "9000000019": |
155 | 161 | return check_for_consent_include_params( |
156 | 162 | _include, |
157 | | - CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP, |
158 | | - CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP_INCLUDE_BOTH, |
| 163 | + GET_CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP, |
| 164 | + GET_CONSENT__SINGLE_MOTHER_CHILD_RELATIONSHIP_INCLUDE_BOTH, |
159 | 165 | ) |
160 | 166 | # Filtering |
161 | 167 | elif performer_identifier == "9000000017": |
162 | 168 | return check_for_consent_filtering( |
163 | 169 | status, |
164 | 170 | _include, |
165 | | - CONSENT__FILTERED_RELATIONSHIPS_STATUS_ACTIVE, |
166 | | - CONSENT__FILTERED_RELATIONSHIPS_STATUS_INACTIVE, |
167 | | - CONSENT__FILTERED_RELATIONSHIPS_STATUS_PROPOSED_ACTIVE, |
| 171 | + GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_ACTIVE, |
| 172 | + GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_INACTIVE, |
| 173 | + GET_CONSENT__FILTERED_RELATIONSHIPS_STATUS_PROPOSED_ACTIVE, |
168 | 174 | ) |
169 | 175 | elif performer_identifier == "9000000022": |
170 | 176 | return check_for_consent_include_params( |
171 | 177 | _include, |
172 | | - CONSENT__MULTIPLE_RELATIONSHIPS, |
173 | | - CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_BOTH, |
174 | | - CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PATIENT, |
175 | | - CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PERFORMER, |
| 178 | + GET_CONSENT__MULTIPLE_RELATIONSHIPS, |
| 179 | + GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_BOTH, |
| 180 | + GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PATIENT, |
| 181 | + GET_CONSENT__MULTIPLE_RELATIONSHIPS_INCLUDE_PERFORMER, |
176 | 182 | ) |
177 | 183 | # No relationships |
178 | 184 | elif performer_identifier == "9000000025": |
179 | | - return generate_response_from_example(CONSENT__NO_RELATIONSHIPS, 200) |
| 185 | + return generate_response_from_example(GET_CONSENT__NO_RELATIONSHIPS, 200) |
180 | 186 | else: |
181 | 187 | logger.error("Performer identifier does not match examples") |
182 | 188 | return generate_response_from_example(INVALIDATED_RESOURCE, 404) |
183 | 189 |
|
184 | 190 | except Exception as e: |
185 | 191 | logger.error(e) |
186 | 192 | return generate_response_from_example(INTERNAL_SERVER_ERROR_EXAMPLE, 500) |
| 193 | + |
| 194 | + |
| 195 | +@app.route(f"/{COMMON_PATH}/Consent", methods=["POST"]) |
| 196 | +def post_consent() -> Union[dict, tuple]: |
| 197 | + """Sandbox API for POST /Consent |
| 198 | +
|
| 199 | + Returns: |
| 200 | + Union[dict, tuple]: Response for POST /Consent |
| 201 | + """ |
| 202 | + try: |
| 203 | + logger.debug("Received request to POST consent") |
| 204 | + # Validate body - beyond the scope of sandbox - assume body is valid for scenario |
| 205 | + json = request.get_json() |
| 206 | + patient_identifier = json["performer"][0]["identifier"]["value"] |
| 207 | + response = None |
| 208 | + |
| 209 | + # Successful parent-child proxy creation |
| 210 | + # Successful adult-adult proxy creation |
| 211 | + if patient_identifier == "9000000009" or patient_identifier == "9000000017": |
| 212 | + header = {"location": f"{APP_BASE_PATH}/{patient_identifier}"} |
| 213 | + response = generate_response_from_example(POST_CONSENT__SUCCESS, 201, headers=header) |
| 214 | + |
| 215 | + # Invalid access level |
| 216 | + elif patient_identifier == "9000000025": |
| 217 | + response = generate_response_from_example(POST_CONSENT__INVALID_ACCESS_LEVEL_ERROR, 400) |
| 218 | + |
| 219 | + # Missing required evidence |
| 220 | + elif patient_identifier == "9000000033": |
| 221 | + response = generate_response_from_example(POST_CONSENT__INVALID_EVIDENCE_ERROR, 422) |
| 222 | + |
| 223 | + # Patient age validation failure |
| 224 | + elif patient_identifier == "9000000041": |
| 225 | + response = generate_response_from_example(POST_CONSENT__INVALID_PATIENT_AGE_ERROR, 422) |
| 226 | + |
| 227 | + # Duplicate relationship |
| 228 | + elif patient_identifier == "9000000049": |
| 229 | + response = generate_response_from_example(POST_CONSENT__DUPLICATE_RELATIONSHIP_ERROR, 409) |
| 230 | + |
| 231 | + # Invalid performer NHS number |
| 232 | + elif patient_identifier == "9000000000": |
| 233 | + response = generate_response_from_example(POST_CONSENT__PERFORMER_IDENTIFIER_ERROR, 400) |
| 234 | + |
| 235 | + else: |
| 236 | + # Out of scope errors |
| 237 | + raise ValueError("Invalid Request") |
| 238 | + |
| 239 | + return response |
| 240 | + |
| 241 | + except Exception as e: |
| 242 | + # Handle any general error |
| 243 | + logger.error(e) |
| 244 | + return generate_response_from_example(INTERNAL_SERVER_ERROR_EXAMPLE, 500) |
0 commit comments