maleo-metadata-client 0.0.7__py3-none-any.whl → 0.0.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of maleo-metadata-client might be problematic. Click here for more details.

@@ -0,0 +1,354 @@
1
+ import json
2
+ from copy import deepcopy
3
+ from datetime import datetime, timezone
4
+ from typing import Literal, Union, overload
5
+ from uuid import UUID
6
+ from maleo.database.enums import Connection
7
+ from maleo.database.utils import build_cache_key
8
+ from maleo.enums.cardinality import Cardinality
9
+ from maleo.enums.connection import Header
10
+ from maleo.logging.enums import Level
11
+ from maleo.managers.client.maleo.config import MaleoMetadataClientConfig
12
+ from maleo.managers.client.maleo import MaleoClientService
13
+ from maleo.metadata.constants.medical_role import MEDICAL_ROLE_RESOURCE
14
+ from maleo.metadata.schemas.medical_role import (
15
+ ReadMultipleSpecializationsParameter,
16
+ ReadMultipleParameter,
17
+ ReadSingleParameter,
18
+ StandardMedicalRoleSchema,
19
+ FullMedicalRoleSchema,
20
+ )
21
+ from maleo.metadata.enums.medical_role import Granularity, IdentifierType
22
+ from maleo.metadata.utils.medical_role import get_schema_model
23
+ from maleo.schemas.connection import ConnectionContext
24
+ from maleo.schemas.exception.factory import Factory as MaleoExceptionFactory
25
+ from maleo.schemas.operation.action.resource import ReadResourceOperationAction
26
+ from maleo.schemas.operation.enums import OperationType, Target
27
+ from maleo.schemas.operation.mixins import Timestamp
28
+ from maleo.schemas.operation.resource import (
29
+ ReadMultipleResourceOperation,
30
+ ReadSingleResourceOperation,
31
+ )
32
+ from maleo.schemas.pagination import StrictPagination
33
+ from maleo.schemas.response import (
34
+ MultipleDataResponse,
35
+ ReadMultipleDataResponse,
36
+ SingleDataResponse,
37
+ ReadSingleDataResponse,
38
+ )
39
+ from maleo.schemas.security.authorization import (
40
+ OptionalAnyAuthorization,
41
+ AnyAuthorization,
42
+ Factory as AuthorizationFactory,
43
+ )
44
+ from maleo.schemas.security.impersonation import OptionalImpersonation
45
+ from maleo.types.dict import OptionalStringToStringDict
46
+ from maleo.types.integer import OptionalInteger
47
+ from maleo.utils.merger import merge_dicts
48
+
49
+
50
+ class MedicalRoleClientService(MaleoClientService[MaleoMetadataClientConfig]):
51
+ resource = MEDICAL_ROLE_RESOURCE
52
+
53
+ @overload
54
+ async def read(
55
+ self,
56
+ cardinality: Literal[Cardinality.MULTIPLE],
57
+ granularity: Literal[Granularity.STANDARD],
58
+ *,
59
+ parent_id: int,
60
+ operation_id: UUID,
61
+ resource_operation_action: ReadResourceOperationAction,
62
+ connection_context: ConnectionContext,
63
+ authorization: AnyAuthorization,
64
+ impersonation: OptionalImpersonation = None,
65
+ parameters: ReadMultipleSpecializationsParameter,
66
+ headers: OptionalStringToStringDict = None,
67
+ ) -> ReadMultipleDataResponse[
68
+ StandardMedicalRoleSchema, StrictPagination, None
69
+ ]: ...
70
+ @overload
71
+ async def read(
72
+ self,
73
+ cardinality: Literal[Cardinality.MULTIPLE],
74
+ granularity: Literal[Granularity.FULL],
75
+ *,
76
+ parent_id: int,
77
+ operation_id: UUID,
78
+ resource_operation_action: ReadResourceOperationAction,
79
+ connection_context: ConnectionContext,
80
+ authorization: AnyAuthorization,
81
+ impersonation: OptionalImpersonation = None,
82
+ parameters: ReadMultipleSpecializationsParameter,
83
+ headers: OptionalStringToStringDict = None,
84
+ ) -> ReadMultipleDataResponse[FullMedicalRoleSchema, StrictPagination, None]: ...
85
+ @overload
86
+ async def read(
87
+ self,
88
+ cardinality: Literal[Cardinality.MULTIPLE],
89
+ granularity: Literal[Granularity.STANDARD],
90
+ *,
91
+ operation_id: UUID,
92
+ resource_operation_action: ReadResourceOperationAction,
93
+ connection_context: ConnectionContext,
94
+ authorization: AnyAuthorization,
95
+ impersonation: OptionalImpersonation = None,
96
+ parameters: ReadMultipleParameter,
97
+ headers: OptionalStringToStringDict = None,
98
+ ) -> ReadMultipleDataResponse[
99
+ StandardMedicalRoleSchema, StrictPagination, None
100
+ ]: ...
101
+ @overload
102
+ async def read(
103
+ self,
104
+ cardinality: Literal[Cardinality.MULTIPLE],
105
+ granularity: Literal[Granularity.FULL],
106
+ *,
107
+ operation_id: UUID,
108
+ resource_operation_action: ReadResourceOperationAction,
109
+ connection_context: ConnectionContext,
110
+ authorization: AnyAuthorization,
111
+ impersonation: OptionalImpersonation = None,
112
+ parameters: ReadMultipleParameter,
113
+ headers: OptionalStringToStringDict = None,
114
+ ) -> ReadMultipleDataResponse[FullMedicalRoleSchema, StrictPagination, None]: ...
115
+ @overload
116
+ async def read(
117
+ self,
118
+ cardinality: Literal[Cardinality.SINGLE],
119
+ granularity: Literal[Granularity.STANDARD],
120
+ *,
121
+ operation_id: UUID,
122
+ resource_operation_action: ReadResourceOperationAction,
123
+ connection_context: ConnectionContext,
124
+ authorization: AnyAuthorization,
125
+ impersonation: OptionalImpersonation = None,
126
+ parameters: ReadSingleParameter,
127
+ headers: OptionalStringToStringDict = None,
128
+ ) -> ReadSingleDataResponse[StandardMedicalRoleSchema, None]: ...
129
+ @overload
130
+ async def read(
131
+ self,
132
+ cardinality: Literal[Cardinality.SINGLE],
133
+ granularity: Literal[Granularity.FULL],
134
+ *,
135
+ operation_id: UUID,
136
+ resource_operation_action: ReadResourceOperationAction,
137
+ connection_context: ConnectionContext,
138
+ authorization: AnyAuthorization,
139
+ impersonation: OptionalImpersonation = None,
140
+ parameters: ReadSingleParameter,
141
+ headers: OptionalStringToStringDict = None,
142
+ ) -> ReadSingleDataResponse[FullMedicalRoleSchema, None]: ...
143
+ async def read(
144
+ self,
145
+ cardinality: Cardinality,
146
+ granularity: Granularity,
147
+ *,
148
+ parent_id: OptionalInteger = None,
149
+ operation_id: UUID,
150
+ resource_operation_action: ReadResourceOperationAction,
151
+ connection_context: ConnectionContext,
152
+ authorization: OptionalAnyAuthorization = None,
153
+ impersonation: OptionalImpersonation = None,
154
+ parameters: Union[
155
+ ReadMultipleSpecializationsParameter,
156
+ ReadMultipleParameter,
157
+ ReadSingleParameter,
158
+ ],
159
+ headers: OptionalStringToStringDict = None,
160
+ ) -> Union[
161
+ ReadMultipleDataResponse[StandardMedicalRoleSchema, StrictPagination, None],
162
+ ReadMultipleDataResponse[FullMedicalRoleSchema, StrictPagination, None],
163
+ ReadSingleDataResponse[StandardMedicalRoleSchema, None],
164
+ ReadSingleDataResponse[FullMedicalRoleSchema, None],
165
+ ]:
166
+ redis_client = self._redis.manager.client.get(Connection.ASYNC)
167
+ data_model_cls = get_schema_model(granularity)
168
+
169
+ executed_at = datetime.now(tz=timezone.utc)
170
+
171
+ # Define arguments being used in this function
172
+ positional_arguments = [cardinality, granularity]
173
+ keyword_arguments = {
174
+ "authorization": (
175
+ authorization.model_dump(mode="json")
176
+ if authorization is not None
177
+ else None
178
+ ),
179
+ "parameters": parameters.model_dump(mode="json"),
180
+ }
181
+
182
+ # Define full function string
183
+ ext = f"({json.dumps(positional_arguments)}|{json.dumps(keyword_arguments)})"
184
+
185
+ # Define full cache_key
186
+ cache_key = build_cache_key(ext, namespace=self._namespace)
187
+
188
+ if parameters.use_cache:
189
+ # Initialize cache operation context
190
+ operation_context = deepcopy(self._operation_context)
191
+ operation_context.target.type = Target.CACHE
192
+
193
+ redis_response_str = await redis_client.get(cache_key)
194
+
195
+ if redis_response_str is not None:
196
+ operation_timestamp = Timestamp.completed_now(executed_at)
197
+ if cardinality is Cardinality.MULTIPLE:
198
+ response = ReadMultipleDataResponse[
199
+ data_model_cls, StrictPagination, None
200
+ ].model_validate_json(redis_response_str)
201
+ ReadMultipleResourceOperation[
202
+ data_model_cls, StrictPagination, None
203
+ ](
204
+ application_context=self._application_context,
205
+ id=operation_id,
206
+ context=operation_context,
207
+ action=resource_operation_action,
208
+ resource=self.resource,
209
+ timestamp=operation_timestamp,
210
+ summary=f"Successfully retrieved {cardinality} {granularity} medical roles from cache",
211
+ connection_context=connection_context,
212
+ authentication=None,
213
+ authorization=authorization,
214
+ impersonation=impersonation,
215
+ response=response,
216
+ ).log(
217
+ self._logger, Level.INFO
218
+ )
219
+ elif cardinality is Cardinality.SINGLE:
220
+ response = ReadSingleDataResponse[
221
+ data_model_cls, None
222
+ ].model_validate_json(redis_response_str)
223
+ ReadSingleResourceOperation[data_model_cls, None](
224
+ application_context=self._application_context,
225
+ id=operation_id,
226
+ context=operation_context,
227
+ action=resource_operation_action,
228
+ resource=self.resource,
229
+ timestamp=operation_timestamp,
230
+ summary=f"Successfully retrieved {cardinality} {granularity} medical role from cache",
231
+ connection_context=connection_context,
232
+ authentication=None,
233
+ authorization=authorization,
234
+ impersonation=impersonation,
235
+ response=response,
236
+ ).log(self._logger, Level.INFO)
237
+
238
+ return response # type: ignore
239
+
240
+ operation_context = deepcopy(self._operation_context)
241
+ operation_context.target.type = Target.MICROSERVICE
242
+
243
+ async with self._http_client_manager.get() as http_client:
244
+ base_headers = {
245
+ Header.CONTENT_TYPE.value: "application/json",
246
+ Header.X_OPERATION_ID.value: str(operation_id),
247
+ }
248
+ if impersonation is not None:
249
+ base_headers[Header.X_USER_ID.value] = str(impersonation.user_id)
250
+ if impersonation.organization_id is not None:
251
+ base_headers[Header.X_ORGANIZATION_ID.value] = str(
252
+ impersonation.organization_id
253
+ )
254
+
255
+ if headers is not None:
256
+ headers = merge_dicts(base_headers, headers)
257
+ else:
258
+ headers = base_headers
259
+
260
+ if authorization is not None:
261
+ auth = AuthorizationFactory.httpx_auth(
262
+ scheme=authorization.scheme, authorization=authorization.credentials
263
+ )
264
+ else:
265
+ auth = None
266
+
267
+ if isinstance(parameters, ReadMultipleSpecializationsParameter):
268
+ if parent_id is None:
269
+ raise ValueError(
270
+ "Parent ID can not be None to read medical role specializations"
271
+ )
272
+ url = f"{self._config.url}/v1/{self.resource.identifiers[-1].slug}/{parent_id}/specializations"
273
+ elif isinstance(parameters, ReadMultipleParameter):
274
+ url = f"{self._config.url}/v1/{self.resource.identifiers[-1].slug}/"
275
+ elif isinstance(parameters, ReadSingleParameter):
276
+ if parameters.identifier is IdentifierType.ID:
277
+ url = f"{self._config.url}/v1/{self.resource.identifiers[-1].slug}/{parameters.value}"
278
+ else:
279
+ url = f"{self._config.url}/v1/{self.resource.identifiers[-1].slug}/{parameters.identifier}/{parameters.value}"
280
+
281
+ params = parameters.to_query_params()
282
+
283
+ response = await http_client.get(
284
+ url, params=params, headers=headers, auth=auth
285
+ )
286
+
287
+ operation_timestamp = Timestamp.completed_now(executed_at)
288
+
289
+ if response.is_error:
290
+ raise MaleoExceptionFactory.from_httpx(
291
+ response,
292
+ operation_type=OperationType.REQUEST,
293
+ application_context=self._application_context,
294
+ operation_id=operation_id,
295
+ operation_context=operation_context,
296
+ operation_action=resource_operation_action,
297
+ operation_timestamp=operation_timestamp,
298
+ connection_context=connection_context,
299
+ authentication=None,
300
+ authorization=authorization,
301
+ impersonation=impersonation,
302
+ logger=self._logger,
303
+ )
304
+
305
+ if isinstance(
306
+ parameters,
307
+ (ReadMultipleSpecializationsParameter, ReadMultipleParameter),
308
+ ):
309
+ validated_response = MultipleDataResponse[
310
+ data_model_cls, StrictPagination, None
311
+ ].model_validate(response.json())
312
+ service_response = ReadMultipleDataResponse[
313
+ data_model_cls, StrictPagination, None
314
+ ].new(
315
+ data=validated_response.data,
316
+ pagination=validated_response.pagination,
317
+ )
318
+ ReadMultipleResourceOperation[data_model_cls, StrictPagination, None](
319
+ application_context=self._application_context,
320
+ id=operation_id,
321
+ context=operation_context,
322
+ action=resource_operation_action,
323
+ resource=MEDICAL_ROLE_RESOURCE,
324
+ timestamp=operation_timestamp,
325
+ summary=f"Successfully retrieved multiple {granularity} medical roles from microservice",
326
+ connection_context=connection_context,
327
+ authentication=None,
328
+ authorization=authorization,
329
+ impersonation=impersonation,
330
+ response=service_response,
331
+ ).log(self._logger, Level.INFO)
332
+ elif isinstance(parameters, ReadSingleParameter):
333
+ validated_response = SingleDataResponse[
334
+ data_model_cls, None
335
+ ].model_validate(response.json())
336
+ service_response = ReadSingleDataResponse[data_model_cls, None].new(
337
+ data=validated_response.data,
338
+ )
339
+ ReadSingleResourceOperation[data_model_cls, None](
340
+ application_context=self._application_context,
341
+ id=operation_id,
342
+ context=operation_context,
343
+ action=resource_operation_action,
344
+ resource=MEDICAL_ROLE_RESOURCE,
345
+ timestamp=operation_timestamp,
346
+ summary=f"Successfully retrieved single {granularity} medical role from microservice",
347
+ connection_context=connection_context,
348
+ authentication=None,
349
+ authorization=authorization,
350
+ impersonation=impersonation,
351
+ response=service_response,
352
+ ).log(self._logger, Level.INFO)
353
+
354
+ return service_response # type: ignore
@@ -0,0 +1,306 @@
1
+ import json
2
+ from copy import deepcopy
3
+ from datetime import datetime, timezone
4
+ from typing import Literal, Union, overload
5
+ from uuid import UUID
6
+ from maleo.database.enums import Connection
7
+ from maleo.database.utils import build_cache_key
8
+ from maleo.enums.cardinality import Cardinality
9
+ from maleo.enums.connection import Header
10
+ from maleo.logging.enums import Level
11
+ from maleo.managers.client.maleo.config import MaleoMetadataClientConfig
12
+ from maleo.managers.client.maleo import MaleoClientService
13
+ from maleo.metadata.constants.medical_service import MEDICAL_SERVICE_RESOURCE
14
+ from maleo.metadata.schemas.medical_service import (
15
+ ReadMultipleParameter,
16
+ ReadSingleParameter,
17
+ StandardMedicalServiceSchema,
18
+ FullMedicalServiceSchema,
19
+ )
20
+ from maleo.metadata.enums.medical_service import Granularity, IdentifierType
21
+ from maleo.metadata.utils.medical_service import get_schema_model
22
+ from maleo.schemas.connection import ConnectionContext
23
+ from maleo.schemas.exception.factory import Factory as MaleoExceptionFactory
24
+ from maleo.schemas.operation.action.resource import ReadResourceOperationAction
25
+ from maleo.schemas.operation.enums import OperationType, Target
26
+ from maleo.schemas.operation.mixins import Timestamp
27
+ from maleo.schemas.operation.resource import (
28
+ ReadMultipleResourceOperation,
29
+ ReadSingleResourceOperation,
30
+ )
31
+ from maleo.schemas.pagination import StrictPagination
32
+ from maleo.schemas.response import (
33
+ MultipleDataResponse,
34
+ ReadMultipleDataResponse,
35
+ SingleDataResponse,
36
+ ReadSingleDataResponse,
37
+ )
38
+ from maleo.schemas.security.authorization import (
39
+ OptionalAnyAuthorization,
40
+ AnyAuthorization,
41
+ Factory as AuthorizationFactory,
42
+ )
43
+ from maleo.schemas.security.impersonation import OptionalImpersonation
44
+ from maleo.types.dict import OptionalStringToStringDict
45
+ from maleo.utils.merger import merge_dicts
46
+
47
+
48
+ class MedicalServiceClientService(MaleoClientService[MaleoMetadataClientConfig]):
49
+ resource = MEDICAL_SERVICE_RESOURCE
50
+
51
+ @overload
52
+ async def read(
53
+ self,
54
+ cardinality: Literal[Cardinality.MULTIPLE],
55
+ granularity: Literal[Granularity.STANDARD],
56
+ *,
57
+ operation_id: UUID,
58
+ resource_operation_action: ReadResourceOperationAction,
59
+ connection_context: ConnectionContext,
60
+ authorization: AnyAuthorization,
61
+ impersonation: OptionalImpersonation = None,
62
+ parameters: ReadMultipleParameter,
63
+ headers: OptionalStringToStringDict = None,
64
+ ) -> ReadMultipleDataResponse[
65
+ StandardMedicalServiceSchema, StrictPagination, None
66
+ ]: ...
67
+ @overload
68
+ async def read(
69
+ self,
70
+ cardinality: Literal[Cardinality.MULTIPLE],
71
+ granularity: Literal[Granularity.FULL],
72
+ *,
73
+ operation_id: UUID,
74
+ resource_operation_action: ReadResourceOperationAction,
75
+ connection_context: ConnectionContext,
76
+ authorization: AnyAuthorization,
77
+ impersonation: OptionalImpersonation = None,
78
+ parameters: ReadMultipleParameter,
79
+ headers: OptionalStringToStringDict = None,
80
+ ) -> ReadMultipleDataResponse[FullMedicalServiceSchema, StrictPagination, None]: ...
81
+ @overload
82
+ async def read(
83
+ self,
84
+ cardinality: Literal[Cardinality.SINGLE],
85
+ granularity: Literal[Granularity.STANDARD],
86
+ *,
87
+ operation_id: UUID,
88
+ resource_operation_action: ReadResourceOperationAction,
89
+ connection_context: ConnectionContext,
90
+ authorization: AnyAuthorization,
91
+ impersonation: OptionalImpersonation = None,
92
+ parameters: ReadSingleParameter,
93
+ headers: OptionalStringToStringDict = None,
94
+ ) -> ReadSingleDataResponse[StandardMedicalServiceSchema, None]: ...
95
+ @overload
96
+ async def read(
97
+ self,
98
+ cardinality: Literal[Cardinality.SINGLE],
99
+ granularity: Literal[Granularity.FULL],
100
+ *,
101
+ operation_id: UUID,
102
+ resource_operation_action: ReadResourceOperationAction,
103
+ connection_context: ConnectionContext,
104
+ authorization: AnyAuthorization,
105
+ impersonation: OptionalImpersonation = None,
106
+ parameters: ReadSingleParameter,
107
+ headers: OptionalStringToStringDict = None,
108
+ ) -> ReadSingleDataResponse[FullMedicalServiceSchema, None]: ...
109
+ async def read(
110
+ self,
111
+ cardinality: Cardinality,
112
+ granularity: Granularity,
113
+ *,
114
+ operation_id: UUID,
115
+ resource_operation_action: ReadResourceOperationAction,
116
+ connection_context: ConnectionContext,
117
+ authorization: OptionalAnyAuthorization = None,
118
+ impersonation: OptionalImpersonation = None,
119
+ parameters: Union[ReadMultipleParameter, ReadSingleParameter],
120
+ headers: OptionalStringToStringDict = None,
121
+ ) -> Union[
122
+ ReadMultipleDataResponse[StandardMedicalServiceSchema, StrictPagination, None],
123
+ ReadMultipleDataResponse[FullMedicalServiceSchema, StrictPagination, None],
124
+ ReadSingleDataResponse[StandardMedicalServiceSchema, None],
125
+ ReadSingleDataResponse[FullMedicalServiceSchema, None],
126
+ ]:
127
+ redis_client = self._redis.manager.client.get(Connection.ASYNC)
128
+ data_model_cls = get_schema_model(granularity)
129
+
130
+ executed_at = datetime.now(tz=timezone.utc)
131
+
132
+ # Define arguments being used in this function
133
+ positional_arguments = [cardinality, granularity]
134
+ keyword_arguments = {
135
+ "authorization": (
136
+ authorization.model_dump(mode="json")
137
+ if authorization is not None
138
+ else None
139
+ ),
140
+ "parameters": parameters.model_dump(mode="json"),
141
+ }
142
+
143
+ # Define full function string
144
+ ext = f"({json.dumps(positional_arguments)}|{json.dumps(keyword_arguments)})"
145
+
146
+ # Define full cache_key
147
+ cache_key = build_cache_key(ext, namespace=self._namespace)
148
+
149
+ if parameters.use_cache:
150
+ # Initialize cache operation context
151
+ operation_context = deepcopy(self._operation_context)
152
+ operation_context.target.type = Target.CACHE
153
+
154
+ redis_response_str = await redis_client.get(cache_key)
155
+
156
+ if redis_response_str is not None:
157
+ operation_timestamp = Timestamp.completed_now(executed_at)
158
+ if cardinality is Cardinality.MULTIPLE:
159
+ response = ReadMultipleDataResponse[
160
+ data_model_cls, StrictPagination, None
161
+ ].model_validate_json(redis_response_str)
162
+ ReadMultipleResourceOperation[
163
+ data_model_cls, StrictPagination, None
164
+ ](
165
+ application_context=self._application_context,
166
+ id=operation_id,
167
+ context=operation_context,
168
+ action=resource_operation_action,
169
+ resource=self.resource,
170
+ timestamp=operation_timestamp,
171
+ summary=f"Successfully retrieved {cardinality} {granularity} medical services from cache",
172
+ connection_context=connection_context,
173
+ authentication=None,
174
+ authorization=authorization,
175
+ impersonation=impersonation,
176
+ response=response,
177
+ ).log(
178
+ self._logger, Level.INFO
179
+ )
180
+ elif cardinality is Cardinality.SINGLE:
181
+ response = ReadSingleDataResponse[
182
+ data_model_cls, None
183
+ ].model_validate_json(redis_response_str)
184
+ ReadSingleResourceOperation[data_model_cls, None](
185
+ application_context=self._application_context,
186
+ id=operation_id,
187
+ context=operation_context,
188
+ action=resource_operation_action,
189
+ resource=self.resource,
190
+ timestamp=operation_timestamp,
191
+ summary=f"Successfully retrieved {cardinality} {granularity} medical service from cache",
192
+ connection_context=connection_context,
193
+ authentication=None,
194
+ authorization=authorization,
195
+ impersonation=impersonation,
196
+ response=response,
197
+ ).log(self._logger, Level.INFO)
198
+
199
+ return response # type: ignore
200
+
201
+ operation_context = deepcopy(self._operation_context)
202
+ operation_context.target.type = Target.MICROSERVICE
203
+
204
+ async with self._http_client_manager.get() as http_client:
205
+ base_headers = {
206
+ Header.CONTENT_TYPE.value: "application/json",
207
+ Header.X_OPERATION_ID.value: str(operation_id),
208
+ }
209
+ if impersonation is not None:
210
+ base_headers[Header.X_USER_ID.value] = str(impersonation.user_id)
211
+ if impersonation.organization_id is not None:
212
+ base_headers[Header.X_ORGANIZATION_ID.value] = str(
213
+ impersonation.organization_id
214
+ )
215
+
216
+ if headers is not None:
217
+ headers = merge_dicts(base_headers, headers)
218
+ else:
219
+ headers = base_headers
220
+
221
+ if authorization is not None:
222
+ auth = AuthorizationFactory.httpx_auth(
223
+ scheme=authorization.scheme, authorization=authorization.credentials
224
+ )
225
+ else:
226
+ auth = None
227
+
228
+ if isinstance(parameters, ReadMultipleParameter):
229
+ url = f"{self._config.url}/v1/{self.resource.identifiers[-1].slug}/"
230
+ elif isinstance(parameters, ReadSingleParameter):
231
+ if parameters.identifier is IdentifierType.ID:
232
+ url = f"{self._config.url}/v1/{self.resource.identifiers[-1].slug}/{parameters.value}"
233
+ else:
234
+ url = f"{self._config.url}/v1/{self.resource.identifiers[-1].slug}/{parameters.identifier}/{parameters.value}"
235
+
236
+ params = parameters.to_query_params()
237
+
238
+ response = await http_client.get(
239
+ url, params=params, headers=headers, auth=auth
240
+ )
241
+
242
+ operation_timestamp = Timestamp.completed_now(executed_at)
243
+
244
+ if response.is_error:
245
+ raise MaleoExceptionFactory.from_httpx(
246
+ response,
247
+ operation_type=OperationType.REQUEST,
248
+ application_context=self._application_context,
249
+ operation_id=operation_id,
250
+ operation_context=operation_context,
251
+ operation_action=resource_operation_action,
252
+ operation_timestamp=operation_timestamp,
253
+ connection_context=connection_context,
254
+ authentication=None,
255
+ authorization=authorization,
256
+ impersonation=impersonation,
257
+ logger=self._logger,
258
+ )
259
+
260
+ if isinstance(parameters, ReadMultipleParameter):
261
+ validated_response = MultipleDataResponse[
262
+ data_model_cls, StrictPagination, None
263
+ ].model_validate(response.json())
264
+ service_response = ReadMultipleDataResponse[
265
+ data_model_cls, StrictPagination, None
266
+ ].new(
267
+ data=validated_response.data,
268
+ pagination=validated_response.pagination,
269
+ )
270
+ ReadMultipleResourceOperation[data_model_cls, StrictPagination, None](
271
+ application_context=self._application_context,
272
+ id=operation_id,
273
+ context=operation_context,
274
+ action=resource_operation_action,
275
+ resource=MEDICAL_SERVICE_RESOURCE,
276
+ timestamp=operation_timestamp,
277
+ summary=f"Successfully retrieved multiple {granularity} medical services from microservice",
278
+ connection_context=connection_context,
279
+ authentication=None,
280
+ authorization=authorization,
281
+ impersonation=impersonation,
282
+ response=service_response,
283
+ ).log(self._logger, Level.INFO)
284
+ elif isinstance(parameters, ReadSingleParameter):
285
+ validated_response = SingleDataResponse[
286
+ data_model_cls, None
287
+ ].model_validate(response.json())
288
+ service_response = ReadSingleDataResponse[data_model_cls, None].new(
289
+ data=validated_response.data,
290
+ )
291
+ ReadSingleResourceOperation[data_model_cls, None](
292
+ application_context=self._application_context,
293
+ id=operation_id,
294
+ context=operation_context,
295
+ action=resource_operation_action,
296
+ resource=MEDICAL_SERVICE_RESOURCE,
297
+ timestamp=operation_timestamp,
298
+ summary=f"Successfully retrieved single {granularity} medical service from microservice",
299
+ connection_context=connection_context,
300
+ authentication=None,
301
+ authorization=authorization,
302
+ impersonation=impersonation,
303
+ response=service_response,
304
+ ).log(self._logger, Level.INFO)
305
+
306
+ return service_response # type: ignore