maleo-metadata-client 0.0.3__py3-none-any.whl → 0.0.5__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.

@@ -1,379 +1,353 @@
1
1
  import json
2
2
  from copy import deepcopy
3
- from Crypto.PublicKey.RSA import RsaKey
4
3
  from datetime import datetime, timezone
5
- from redis.asyncio.client import Redis
6
- from typing import Dict, List, Literal, Optional, Union, overload
4
+ from typing import Literal, Union, overload
7
5
  from uuid import UUID
8
- from maleo.soma.authorization import BearerAuth
9
- from maleo.soma.dtos.configurations.cache.redis import RedisCacheNamespaces
10
- from maleo.soma.enums.cardinality import Cardinality
11
- from maleo.soma.enums.environment import Environment
12
- from maleo.soma.enums.expiration import Expiration
13
- from maleo.soma.enums.logging import LogLevel
14
- from maleo.soma.enums.operation import OperationTarget
15
- from maleo.soma.managers.client.maleo import MaleoClientService
16
- from maleo.soma.managers.client.http import HTTPClientManager
17
- from maleo.soma.managers.credential import CredentialManager
18
- from maleo.soma.schemas.authentication import OptionalAuthentication
19
- from maleo.soma.schemas.data import DataPair
20
- from maleo.soma.schemas.operation.context import (
21
- OperationContextSchema,
22
- OperationOriginSchema,
23
- OperationLayerSchema,
24
- OperationTargetSchema,
25
- )
26
- from maleo.soma.schemas.operation.resource import (
27
- ReadSingleResourceOperationSchema,
28
- ReadMultipleResourceOperationSchema,
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.blood_type import RESOURCE
14
+ from maleo.metadata.dtos.blood_type import (
15
+ ReadMultipleParameter,
16
+ ReadSingleParameter,
17
+ BasicBloodTypeData,
18
+ StandardBloodTypeData,
19
+ FullBloodTypeData,
29
20
  )
30
- from maleo.soma.schemas.operation.resource.action import ReadResourceOperationAction
31
- from maleo.soma.schemas.operation.resource.result import (
32
- ReadSingleResourceOperationResult,
33
- ReadMultipleResourceOperationResult,
21
+ from maleo.metadata.enums.blood_type import Granularity
22
+ from maleo.metadata.utils.blood_type import get_data_model
23
+ from maleo.schemas.connection import ConnectionContext
24
+ from maleo.schemas.exception.factory import Factory as MaleoExceptionFactory
25
+ from maleo.schemas.mixins.filter import convert as convert_filter
26
+ from maleo.schemas.mixins.sort import convert as convert_sort
27
+ from maleo.schemas.operation.action.resource import ReadResourceOperationAction
28
+ from maleo.schemas.operation.enums import OperationType, Target
29
+ from maleo.schemas.operation.mixins import Timestamp
30
+ from maleo.schemas.operation.resource import (
31
+ ReadMultipleResourceOperation,
32
+ ReadSingleResourceOperation,
34
33
  )
35
- from maleo.soma.schemas.operation.timestamp import OperationTimestamp
36
- from maleo.soma.schemas.pagination import FlexiblePagination
37
- from maleo.soma.schemas.parameter.general import ReadSingleQueryParameterSchema
38
- from maleo.soma.schemas.request import RequestContext
39
- from maleo.soma.schemas.response import (
40
- SingleDataResponseSchema,
41
- MultipleDataResponseSchema,
34
+ from maleo.schemas.pagination import StrictPagination
35
+ from maleo.schemas.response import (
36
+ MultipleDataResponse,
37
+ ReadMultipleDataResponse,
38
+ SingleDataResponse,
39
+ ReadSingleDataResponse,
42
40
  )
43
- from maleo.soma.schemas.service import ServiceContext
44
- from maleo.soma.utils.cache import build_key
45
- from maleo.soma.utils.logging import ClientLogger
46
- from maleo.soma.utils.merger import merge_dicts
47
- from maleo.soma.utils.token import reencode
48
- from maleo.metadata.constants.blood_type import RESOURCE
49
- from maleo.metadata.schemas.data.blood_type import BloodTypeDataSchema
50
- from maleo.metadata.schemas.parameter.client.blood_type import (
51
- ReadMultipleParameter,
52
- ReadMultipleQueryParameter,
41
+ from maleo.schemas.security.authorization import (
42
+ OptionalAnyAuthorization,
43
+ AnyAuthorization,
44
+ Factory as AuthorizationFactory,
53
45
  )
54
- from maleo.metadata.schemas.parameter.general.blood_type import ReadSingleParameter
46
+ from maleo.schemas.security.impersonation import OptionalImpersonation
47
+ from maleo.types.dict import OptionalStringToStringDict
48
+ from maleo.utils.merger import merge_dicts
55
49
 
56
50
 
57
- class BloodTypeClientService(MaleoClientService):
58
- def __init__(
59
- self,
60
- environment: Environment,
61
- key: str,
62
- url: str,
63
- operation_origin: OperationOriginSchema,
64
- logger: ClientLogger,
65
- credential_manager: CredentialManager,
66
- http_client_manager: HTTPClientManager,
67
- private_key: RsaKey,
68
- redis: Redis,
69
- redis_namespaces: RedisCacheNamespaces,
70
- service_context: ServiceContext,
71
- ):
72
- super().__init__(
73
- environment,
74
- key,
75
- url,
76
- operation_origin,
77
- logger,
78
- credential_manager,
79
- http_client_manager,
80
- private_key,
81
- redis,
82
- redis_namespaces,
83
- service_context,
84
- )
85
- self._namespace = self._redis_namespaces.create(
86
- self._key,
87
- RESOURCE.aggregate(),
88
- origin=self._CACHE_ORIGIN,
89
- layer=self._CACHE_LAYER,
90
- )
91
- self._default_operation_context = OperationContextSchema(
92
- origin=self._operation_origin,
93
- layer=OperationLayerSchema(type=self._OPERATION_LAYER_TYPE, details=None),
94
- target=OperationTargetSchema(
95
- type=self._OPERATION_TARGET_TYPE, details=None
96
- ),
97
- )
51
+ class BloodTypeClientService(MaleoClientService[MaleoMetadataClientConfig]):
52
+ resource = RESOURCE
98
53
 
99
54
  @overload
100
55
  async def read(
101
56
  self,
102
57
  cardinality: Literal[Cardinality.MULTIPLE],
58
+ granularity: Literal[Granularity.BASIC],
59
+ *,
60
+ operation_id: UUID,
61
+ resource_operation_action: ReadResourceOperationAction,
62
+ connection_context: ConnectionContext,
63
+ authorization: OptionalAnyAuthorization = None,
64
+ impersonation: OptionalImpersonation = None,
65
+ parameters: ReadMultipleParameter,
66
+ headers: OptionalStringToStringDict = None,
67
+ ) -> ReadMultipleDataResponse[BasicBloodTypeData, StrictPagination, None]: ...
68
+ @overload
69
+ async def read(
70
+ self,
71
+ cardinality: Literal[Cardinality.MULTIPLE],
72
+ granularity: Literal[Granularity.STANDARD],
73
+ *,
74
+ operation_id: UUID,
75
+ resource_operation_action: ReadResourceOperationAction,
76
+ connection_context: ConnectionContext,
77
+ authorization: AnyAuthorization,
78
+ impersonation: OptionalImpersonation = None,
79
+ parameters: ReadMultipleParameter,
80
+ headers: OptionalStringToStringDict = None,
81
+ ) -> ReadMultipleDataResponse[StandardBloodTypeData, StrictPagination, None]: ...
82
+ @overload
83
+ async def read(
84
+ self,
85
+ cardinality: Literal[Cardinality.MULTIPLE],
86
+ granularity: Literal[Granularity.FULL],
103
87
  *,
104
88
  operation_id: UUID,
105
- request_context: RequestContext,
106
- authentication: OptionalAuthentication,
89
+ resource_operation_action: ReadResourceOperationAction,
90
+ connection_context: ConnectionContext,
91
+ authorization: AnyAuthorization,
92
+ impersonation: OptionalImpersonation = None,
107
93
  parameters: ReadMultipleParameter,
108
- headers: Optional[Dict[str, str]] = None,
109
- ) -> ReadMultipleResourceOperationResult[
110
- BloodTypeDataSchema, FlexiblePagination, None
111
- ]: ...
94
+ headers: OptionalStringToStringDict = None,
95
+ ) -> ReadMultipleDataResponse[FullBloodTypeData, StrictPagination, None]: ...
96
+ @overload
97
+ async def read(
98
+ self,
99
+ cardinality: Literal[Cardinality.SINGLE],
100
+ granularity: Literal[Granularity.BASIC],
101
+ *,
102
+ operation_id: UUID,
103
+ resource_operation_action: ReadResourceOperationAction,
104
+ connection_context: ConnectionContext,
105
+ authorization: OptionalAnyAuthorization = None,
106
+ impersonation: OptionalImpersonation = None,
107
+ parameters: ReadSingleParameter,
108
+ headers: OptionalStringToStringDict = None,
109
+ ) -> ReadSingleDataResponse[BasicBloodTypeData, None]: ...
112
110
  @overload
113
111
  async def read(
114
112
  self,
115
113
  cardinality: Literal[Cardinality.SINGLE],
114
+ granularity: Literal[Granularity.STANDARD],
116
115
  *,
117
116
  operation_id: UUID,
118
- request_context: RequestContext,
119
- authentication: OptionalAuthentication,
117
+ resource_operation_action: ReadResourceOperationAction,
118
+ connection_context: ConnectionContext,
119
+ authorization: AnyAuthorization,
120
+ impersonation: OptionalImpersonation = None,
120
121
  parameters: ReadSingleParameter,
121
- headers: Optional[Dict[str, str]] = None,
122
- ) -> ReadSingleResourceOperationResult[BloodTypeDataSchema, None]: ...
122
+ headers: OptionalStringToStringDict = None,
123
+ ) -> ReadSingleDataResponse[StandardBloodTypeData, None]: ...
124
+ @overload
125
+ async def read(
126
+ self,
127
+ cardinality: Literal[Cardinality.SINGLE],
128
+ granularity: Literal[Granularity.FULL],
129
+ *,
130
+ operation_id: UUID,
131
+ resource_operation_action: ReadResourceOperationAction,
132
+ connection_context: ConnectionContext,
133
+ authorization: AnyAuthorization,
134
+ impersonation: OptionalImpersonation = None,
135
+ parameters: ReadSingleParameter,
136
+ headers: OptionalStringToStringDict = None,
137
+ ) -> ReadSingleDataResponse[FullBloodTypeData, None]: ...
123
138
  async def read(
124
139
  self,
125
140
  cardinality: Cardinality,
141
+ granularity: Granularity,
126
142
  *,
127
143
  operation_id: UUID,
128
- request_context: RequestContext,
129
- authentication: OptionalAuthentication,
144
+ resource_operation_action: ReadResourceOperationAction,
145
+ connection_context: ConnectionContext,
146
+ authorization: OptionalAnyAuthorization = None,
147
+ impersonation: OptionalImpersonation = None,
130
148
  parameters: Union[ReadMultipleParameter, ReadSingleParameter],
131
- headers: Optional[Dict[str, str]] = None,
149
+ headers: OptionalStringToStringDict = None,
132
150
  ) -> Union[
133
- ReadMultipleResourceOperationResult[
134
- BloodTypeDataSchema, FlexiblePagination, None
135
- ],
136
- ReadSingleResourceOperationResult[BloodTypeDataSchema, None],
151
+ ReadMultipleDataResponse[BasicBloodTypeData, StrictPagination, None],
152
+ ReadMultipleDataResponse[StandardBloodTypeData, StrictPagination, None],
153
+ ReadMultipleDataResponse[FullBloodTypeData, StrictPagination, None],
154
+ ReadSingleDataResponse[BasicBloodTypeData, None],
155
+ ReadSingleDataResponse[StandardBloodTypeData, None],
156
+ ReadSingleDataResponse[FullBloodTypeData, None],
137
157
  ]:
138
- operation_action = ReadResourceOperationAction()
139
- executed_at = datetime.now(tz=timezone.utc)
158
+ redis_client = self._redis.manager.client.get(Connection.ASYNC)
159
+ data_model_cls = get_data_model(granularity)
140
160
 
141
- # Get function identifier
142
- func = self.__class__
143
- module, qualname = func.__module__, func.__qualname__
161
+ executed_at = datetime.now(tz=timezone.utc)
144
162
 
145
163
  # Define arguments being used in this function
146
- positional_arguments = [cardinality]
164
+ positional_arguments = [cardinality, granularity]
147
165
  keyword_arguments = {
148
- "authentication": authentication.model_dump(
149
- mode="json",
150
- exclude={
151
- "credentials": {
152
- "token": {
153
- "payload": {
154
- "iat_dt",
155
- "iat",
156
- "exp_dt",
157
- "exp",
158
- }
159
- }
160
- }
161
- },
166
+ "authorization": (
167
+ authorization.model_dump(mode="json")
168
+ if authorization is not None
169
+ else None
162
170
  ),
163
171
  "parameters": parameters.model_dump(mode="json"),
164
172
  }
165
173
 
166
174
  # Define full function string
167
- function = f"{qualname}({json.dumps(positional_arguments)}|{json.dumps(keyword_arguments)})"
175
+ ext = f"({json.dumps(positional_arguments)}|{json.dumps(keyword_arguments)})"
168
176
 
169
- # Define full cache key
170
- cache_key = build_key(module, function, namespace=self._namespace)
177
+ # Define full cache_key
178
+ cache_key = build_cache_key(ext, namespace=self._namespace)
171
179
 
172
180
  if parameters.use_cache:
173
- operation_context = deepcopy(self._default_operation_context)
174
- operation_context.target.type = OperationTarget.CACHE
175
-
176
- # Check redis for data
177
- result_str = await self._redis.get(cache_key)
181
+ # Initialize cache operation context
182
+ operation_context = deepcopy(self._operation_context)
183
+ operation_context.target.type = Target.CACHE
178
184
 
179
- if result_str is not None:
180
- completed_at = datetime.now(tz=timezone.utc)
185
+ redis_response_str = await redis_client.get(cache_key)
181
186
 
182
- if isinstance(parameters, ReadMultipleParameter):
183
- result = ReadMultipleResourceOperationResult[
184
- BloodTypeDataSchema, FlexiblePagination, None
185
- ].model_validate(json.loads(result_str))
186
- ReadMultipleResourceOperationSchema[
187
- OptionalAuthentication,
188
- BloodTypeDataSchema,
189
- FlexiblePagination,
190
- None,
187
+ if redis_response_str is not None:
188
+ operation_timestamp = Timestamp.completed_now(executed_at)
189
+ if cardinality is Cardinality.MULTIPLE:
190
+ response = ReadMultipleDataResponse[
191
+ data_model_cls, StrictPagination, None
192
+ ].model_validate_json(redis_response_str)
193
+ ReadMultipleResourceOperation[
194
+ data_model_cls, StrictPagination, None
191
195
  ](
192
- service_context=self._service_context,
196
+ application_context=self._application_context,
193
197
  id=operation_id,
194
198
  context=operation_context,
195
- timestamp=OperationTimestamp(
196
- executed_at=executed_at,
197
- completed_at=completed_at,
198
- duration=(completed_at - executed_at).total_seconds(),
199
- ),
200
- summary="Successfully retrieved multiple blood types from cache",
201
- request_context=request_context,
202
- authentication=authentication,
203
- action=operation_action,
204
- resource=RESOURCE,
205
- result=result,
199
+ action=resource_operation_action,
200
+ resource=self.resource,
201
+ timestamp=operation_timestamp,
202
+ summary=f"Successfully retrieved {cardinality} {granularity} blood types from cache",
203
+ connection_context=connection_context,
204
+ authentication=None,
205
+ authorization=authorization,
206
+ impersonation=impersonation,
207
+ response=response,
206
208
  ).log(
207
- self._logger, LogLevel.INFO
209
+ self._logger, Level.INFO
208
210
  )
209
- elif isinstance(parameters, ReadSingleParameter):
210
- result = ReadSingleResourceOperationResult[
211
- BloodTypeDataSchema, None
212
- ].model_validate(json.loads(result_str))
213
- ReadSingleResourceOperationSchema[
214
- OptionalAuthentication, BloodTypeDataSchema, None
215
- ](
216
- service_context=self._service_context,
211
+ elif cardinality is Cardinality.SINGLE:
212
+ response = ReadSingleDataResponse[
213
+ data_model_cls, None
214
+ ].model_validate_json(redis_response_str)
215
+ ReadSingleResourceOperation[data_model_cls, None](
216
+ application_context=self._application_context,
217
217
  id=operation_id,
218
218
  context=operation_context,
219
- timestamp=OperationTimestamp(
220
- executed_at=executed_at,
221
- completed_at=completed_at,
222
- duration=(completed_at - executed_at).total_seconds(),
223
- ),
224
- summary="Successfully retrieved single blood type from cache",
225
- request_context=request_context,
226
- authentication=authentication,
227
- action=operation_action,
228
- resource=RESOURCE,
229
- result=result,
230
- ).log(
231
- self._logger, LogLevel.INFO
232
- )
233
- return result
219
+ action=resource_operation_action,
220
+ resource=self.resource,
221
+ timestamp=operation_timestamp,
222
+ summary=f"Successfully retrieved {cardinality} {granularity} blood type(s) from cache",
223
+ connection_context=connection_context,
224
+ authentication=None,
225
+ authorization=authorization,
226
+ impersonation=impersonation,
227
+ response=response,
228
+ ).log(self._logger, Level.INFO)
229
+
230
+ return response # type: ignore
231
+
232
+ operation_context = deepcopy(self._operation_context)
233
+ operation_context.target.type = Target.MICROSERVICE
234
234
 
235
- operation_context = deepcopy(self._default_operation_context)
236
235
  async with self._http_client_manager.get() as http_client:
237
- # Create headers
238
236
  base_headers = {
239
- "content-type": "application/json",
240
- "x-operation-id": str(operation_id),
237
+ Header.CONTENT_TYPE.value: "application/json",
238
+ Header.X_OPERATION_ID.value: str(operation_id),
241
239
  }
240
+ if impersonation is not None:
241
+ base_headers[Header.X_USER_ID.value] = str(impersonation.user_id)
242
+ if impersonation.organization_id is not None:
243
+ base_headers[Header.X_ORGANIZATION_ID.value] = str(
244
+ impersonation.organization_id
245
+ )
246
+
242
247
  if headers is not None:
243
248
  headers = merge_dicts(base_headers, headers)
244
249
  else:
245
250
  headers = base_headers
246
251
 
247
- # Create auth
248
- token = None
249
- if authentication.credentials.token is not None:
250
- try:
251
- token = reencode(
252
- payload=authentication.credentials.token.payload,
253
- key=self._private_key,
254
- )
255
- except Exception:
256
- pass
257
-
258
- auth = BearerAuth(token) if token is not None else None
252
+ if authorization is not None:
253
+ auth = AuthorizationFactory.httpx_auth(
254
+ scheme=authorization.scheme, authorization=authorization.credentials
255
+ )
256
+ else:
257
+ auth = None
259
258
 
260
259
  if isinstance(parameters, ReadMultipleParameter):
261
- # Define URL
262
- url = f"{self._url}/v1/{RESOURCE.identifiers[0].url_slug}/"
263
-
264
- # Parse parameters to query params
265
- params = ReadMultipleQueryParameter.model_validate(
266
- parameters.model_dump()
267
- ).model_dump(
268
- exclude={"sort_columns", "date_filters"}, exclude_none=True
260
+ url = f"{self._config.url}/v1/{self.resource.identifiers[0].slug}/"
261
+ parameters.date_filters
262
+ params = parameters.model_dump(
263
+ mode="json",
264
+ include={
265
+ "ids",
266
+ "uuids",
267
+ "statuses",
268
+ "keys",
269
+ "names",
270
+ "search",
271
+ "page",
272
+ "limit",
273
+ "granularity",
274
+ "use_cache",
275
+ },
269
276
  )
277
+ params["filters"] = convert_filter(parameters.date_filters)
278
+ params["sorts"] = convert_sort(parameters.sort_columns)
270
279
  elif isinstance(parameters, ReadSingleParameter):
271
- # Define URL
272
- url = f"{self._url}/v1/{RESOURCE.identifiers[0].url_slug}/{parameters.identifier}/{parameters.value}"
273
-
274
- # Parse parameters to query params
275
- params = ReadSingleQueryParameterSchema.model_validate(
276
- parameters.model_dump()
277
- ).model_dump(exclude_none=True)
280
+ url = f"{self._config.url}/v1/{self.resource.identifiers[0].slug}/{parameters.identifier}/{parameters.value}"
281
+ params = parameters.model_dump(
282
+ mode="json", include={"granularity", "use_cache"}
283
+ )
278
284
 
279
- # Send request and wait for response
280
285
  response = await http_client.get(
281
- url=url, params=params, headers=headers, auth=auth
286
+ url, params=params, headers=headers, auth=auth
282
287
  )
283
288
 
284
- if response.is_success:
285
- completed_at = datetime.now(tz=timezone.utc)
286
-
287
- if isinstance(parameters, ReadMultipleParameter):
288
- validated_response = MultipleDataResponseSchema[
289
- BloodTypeDataSchema, FlexiblePagination, None
290
- ].model_validate(response.json())
291
- data = DataPair[List[BloodTypeDataSchema], None](
292
- old=validated_response.data,
293
- new=None,
294
- )
295
- result = ReadMultipleResourceOperationResult[
296
- BloodTypeDataSchema, FlexiblePagination, None
297
- ](
298
- data=data,
299
- pagination=validated_response.pagination,
300
- metadata=None,
301
- other=None,
302
- )
303
- ReadMultipleResourceOperationSchema[
304
- OptionalAuthentication,
305
- BloodTypeDataSchema,
306
- FlexiblePagination,
307
- None,
308
- ](
309
- service_context=self._service_context,
310
- id=operation_id,
311
- context=operation_context,
312
- timestamp=OperationTimestamp(
313
- executed_at=executed_at,
314
- completed_at=completed_at,
315
- duration=(completed_at - executed_at).total_seconds(),
316
- ),
317
- summary="Successfully retrieved multiple blood types from http request",
318
- request_context=request_context,
319
- authentication=authentication,
320
- action=operation_action,
321
- resource=RESOURCE,
322
- result=result,
323
- ).log(
324
- self._logger, level=LogLevel.INFO
325
- )
326
- elif isinstance(parameters, ReadSingleParameter):
327
- validated_response = SingleDataResponseSchema[
328
- BloodTypeDataSchema, None
329
- ].model_validate(response.json())
330
- data = DataPair[BloodTypeDataSchema, None](
331
- old=validated_response.data,
332
- new=None,
333
- )
334
- result = ReadSingleResourceOperationResult[
335
- BloodTypeDataSchema, None
336
- ](
337
- data=data,
338
- pagination=validated_response.pagination,
339
- metadata=None,
340
- other=None,
341
- )
342
- ReadSingleResourceOperationSchema[
343
- OptionalAuthentication, BloodTypeDataSchema, None
344
- ](
345
- service_context=self._service_context,
346
- id=operation_id,
347
- context=operation_context,
348
- timestamp=OperationTimestamp(
349
- executed_at=executed_at,
350
- completed_at=completed_at,
351
- duration=(completed_at - executed_at).total_seconds(),
352
- ),
353
- summary="Successfully retrieved single blood type from http request",
354
- request_context=request_context,
355
- authentication=authentication,
356
- action=operation_action,
357
- resource=RESOURCE,
358
- result=result,
359
- ).log(
360
- self._logger, level=LogLevel.INFO
361
- )
289
+ operation_timestamp = Timestamp.completed_now(executed_at)
362
290
 
363
- if parameters.use_cache:
364
- await self._redis.set(
365
- cache_key, result.model_dump_json(), Expiration.EXP_1MO.value
366
- )
291
+ if response.is_error:
292
+ raise MaleoExceptionFactory.from_httpx(
293
+ response,
294
+ operation_type=OperationType.REQUEST,
295
+ application_context=self._application_context,
296
+ operation_id=operation_id,
297
+ operation_context=operation_context,
298
+ operation_action=resource_operation_action,
299
+ operation_timestamp=operation_timestamp,
300
+ connection_context=connection_context,
301
+ authentication=None,
302
+ authorization=authorization,
303
+ impersonation=impersonation,
304
+ logger=self._logger,
305
+ )
367
306
 
368
- return result
307
+ if isinstance(parameters, ReadMultipleParameter):
308
+ validated_response = MultipleDataResponse[
309
+ data_model_cls, StrictPagination, None
310
+ ].model_validate(response.json())
311
+ service_response = ReadMultipleDataResponse[
312
+ data_model_cls, StrictPagination, None
313
+ ].new(
314
+ data=validated_response.data,
315
+ pagination=validated_response.pagination,
316
+ )
317
+ ReadMultipleResourceOperation[data_model_cls, StrictPagination, None](
318
+ application_context=self._application_context,
319
+ id=operation_id,
320
+ context=operation_context,
321
+ action=resource_operation_action,
322
+ resource=RESOURCE,
323
+ timestamp=operation_timestamp,
324
+ summary=f"Successfully retrieved multiple {granularity} blood types from microservice",
325
+ connection_context=connection_context,
326
+ authentication=None,
327
+ authorization=authorization,
328
+ impersonation=impersonation,
329
+ response=service_response,
330
+ ).log(self._logger, Level.INFO)
331
+ elif isinstance(parameters, ReadSingleParameter):
332
+ validated_response = SingleDataResponse[
333
+ data_model_cls, None
334
+ ].model_validate(response.json())
335
+ service_response = ReadSingleDataResponse[data_model_cls, None].new(
336
+ data=validated_response.data,
337
+ )
338
+ ReadSingleResourceOperation[data_model_cls, None](
339
+ application_context=self._application_context,
340
+ id=operation_id,
341
+ context=operation_context,
342
+ action=resource_operation_action,
343
+ resource=RESOURCE,
344
+ timestamp=operation_timestamp,
345
+ summary=f"Successfully retrieved single {granularity} blood type from microservice",
346
+ connection_context=connection_context,
347
+ authentication=None,
348
+ authorization=authorization,
349
+ impersonation=impersonation,
350
+ response=service_response,
351
+ ).log(self._logger, Level.INFO)
369
352
 
370
- self._raise_resource_http_request_error(
371
- response=response,
372
- operation_id=operation_id,
373
- operation_context=operation_context,
374
- executed_at=executed_at,
375
- operation_action=operation_action,
376
- request_context=request_context,
377
- authentication=authentication,
378
- resource=RESOURCE,
379
- )
353
+ return service_response # type: ignore