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