maleo-foundation 0.3.70__py3-none-any.whl → 0.3.72__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.
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
+ from typing import Optional
3
+ from maleo_foundation.enums import BaseEnums
2
4
  from maleo_foundation.managers.client.base import ClientManager
3
- from maleo_foundation.types import BaseTypes
4
5
  from maleo_foundation.utils.logging import SimpleConfig
5
6
  from maleo_foundation.client.services.encryption import (
6
7
  MaleoFoundationAESEncryptionClientService,
@@ -23,11 +24,16 @@ from maleo_foundation.client.services import (
23
24
 
24
25
  class MaleoFoundationClientManager(ClientManager):
25
26
  def __init__(
26
- self, log_config: SimpleConfig, service_key: BaseTypes.OptionalString = None
27
+ self,
28
+ log_config: SimpleConfig,
29
+ service_environment: Optional[BaseEnums.EnvironmentType] = None,
30
+ service_key: Optional[BaseEnums.Service] = None,
27
31
  ) -> None:
28
32
  key = "maleo-foundation"
29
33
  name = "MaleoFoundation"
30
- super().__init__(key, name, log_config, service_key)
34
+ super().__init__(
35
+ key, name, log_config, service_environment, service_key, service_environment
36
+ )
31
37
  self._initialize_services()
32
38
  self._logger.info("Client manager initialized successfully")
33
39
 
@@ -0,0 +1,25 @@
1
+ from google.cloud.pubsub_v1.subscriber.message import Message
2
+ from typing import Awaitable, Callable, Optional, Union
3
+ from maleo_foundation.models.transfers.results.service.controllers.rest import (
4
+ BaseServiceRESTControllerResults,
5
+ )
6
+
7
+
8
+ class ControllerTypes:
9
+ # * REST controller types
10
+ SyncRESTController = Callable[..., BaseServiceRESTControllerResults]
11
+ OptionalSyncRESTController = Optional[
12
+ Callable[..., BaseServiceRESTControllerResults]
13
+ ]
14
+ AsyncRESTController = Callable[..., Awaitable[BaseServiceRESTControllerResults]]
15
+ OptionalAsyncRESTController = Optional[
16
+ Callable[..., Awaitable[BaseServiceRESTControllerResults]]
17
+ ]
18
+ RESTController = Union[SyncRESTController, AsyncRESTController]
19
+ OptionalRESTController = Optional[RESTController]
20
+
21
+ # * Message controller types
22
+ SyncMessageController = Callable[[str, Message], bool]
23
+ AsyncMessageController = Callable[[str, Message], Awaitable[bool]]
24
+ MessageController = Union[SyncMessageController, AsyncMessageController]
25
+ OptionalMessageController = Optional[MessageController]
@@ -1,8 +1,9 @@
1
1
  import httpx
2
+ import os
2
3
  from contextlib import asynccontextmanager
3
4
  from pydantic import BaseModel, ConfigDict, Field
4
- from typing import AsyncGenerator, Generator
5
- from maleo_foundation.types import BaseTypes
5
+ from typing import AsyncGenerator, Generator, Optional
6
+ from maleo_foundation.enums import BaseEnums
6
7
  from maleo_foundation.utils.logging import ClientLogger, SimpleConfig
7
8
 
8
9
 
@@ -107,18 +108,43 @@ class ClientManager:
107
108
  key: str,
108
109
  name: str,
109
110
  log_config: SimpleConfig,
110
- service_key: BaseTypes.OptionalString = None,
111
+ service_environment: Optional[BaseEnums.EnvironmentType] = None,
112
+ service_key: Optional[BaseEnums.Service] = None,
113
+ environment: Optional[BaseEnums.EnvironmentType] = None,
111
114
  ) -> None:
112
115
  self._key = key
113
116
  self._name = name
114
117
  self._log_config = log_config
115
- self._service_key = service_key
118
+
119
+ # Ensure environment exists
120
+ actual_service_environment = service_environment or os.getenv("ENVIRONMENT")
121
+ if actual_service_environment is None:
122
+ raise ValueError(
123
+ "ENVIRONMENT environment variable must be set if 'service_environment' is set to None"
124
+ )
125
+ else:
126
+ self._service_environment = BaseEnums.EnvironmentType(
127
+ actual_service_environment
128
+ )
129
+
130
+ # Ensure service_key exists
131
+ actual_service_key = service_key or os.getenv("SERVICE_KEY")
132
+ if actual_service_key is None:
133
+ raise ValueError(
134
+ "SERVICE_KEY environment variable must be set if 'service_key' is set to None"
135
+ )
136
+ else:
137
+ self._service_key = BaseEnums.Service(actual_service_key)
138
+
139
+ self._environment = environment
140
+
116
141
  self._initialize_logger()
117
- self._logger.info("Initializing client manager")
142
+ self._logger.info(f"Initializing {self._name} client manager")
118
143
 
119
144
  def _initialize_logger(self) -> None:
120
145
  self._logger = ClientLogger(
121
146
  client_key=self._key,
147
+ environment=self._service_environment,
122
148
  service_key=self._service_key,
123
149
  **self._log_config.model_dump(),
124
150
  )
@@ -131,6 +157,12 @@ class ClientManager:
131
157
  def name(self) -> str:
132
158
  return self._name
133
159
 
160
+ @property
161
+ def environment(self) -> BaseEnums.EnvironmentType:
162
+ if self._environment is None:
163
+ raise ValueError("Environment has not been initialized.")
164
+ return self._environment
165
+
134
166
  @property
135
167
  def logger(self) -> ClientLogger:
136
168
  return self._logger
@@ -1,7 +1,7 @@
1
1
  from google.oauth2.service_account import Credentials
2
2
  from pathlib import Path
3
3
  from typing import Optional, Union
4
- from maleo_foundation.types import BaseTypes
4
+ from maleo_foundation.enums import BaseEnums
5
5
  from maleo_foundation.managers.client.base import ClientManager
6
6
  from maleo_foundation.utils.loaders.credential.google import GoogleCredentialsLoader
7
7
  from maleo_foundation.utils.logging import SimpleConfig
@@ -13,11 +13,15 @@ class GoogleClientManager(ClientManager):
13
13
  key: str,
14
14
  name: str,
15
15
  log_config: SimpleConfig,
16
- service_key: BaseTypes.OptionalString = None,
16
+ service_environment: Optional[BaseEnums.EnvironmentType] = None,
17
+ service_key: Optional[BaseEnums.Service] = None,
18
+ environment: Optional[BaseEnums.EnvironmentType] = None,
17
19
  credentials: Optional[Credentials] = None,
18
20
  credentials_path: Optional[Union[Path, str]] = None,
19
21
  ) -> None:
20
- super().__init__(key, name, log_config, service_key)
22
+ super().__init__(
23
+ key, name, log_config, service_environment, service_key, environment
24
+ )
21
25
  if (credentials is not None and credentials_path is not None) or (
22
26
  credentials is None and credentials_path is None
23
27
  ):
@@ -4,7 +4,7 @@ from google.cloud import secretmanager
4
4
  from google.oauth2.service_account import Credentials
5
5
  from pathlib import Path
6
6
  from typing import Optional, Union
7
- from maleo_foundation.types import BaseTypes
7
+ from maleo_foundation.enums import BaseEnums
8
8
  from maleo_foundation.utils.logging import SimpleConfig
9
9
  from .base import GoogleClientManager
10
10
 
@@ -13,14 +13,23 @@ class GoogleSecretManager(GoogleClientManager):
13
13
  def __init__(
14
14
  self,
15
15
  log_config: SimpleConfig,
16
- service_key: BaseTypes.OptionalString = None,
16
+ service_environment: Optional[BaseEnums.EnvironmentType] = None,
17
+ service_key: Optional[BaseEnums.Service] = None,
18
+ environment: Optional[BaseEnums.EnvironmentType] = None,
17
19
  credentials: Optional[Credentials] = None,
18
20
  credentials_path: Optional[Union[Path, str]] = None,
19
21
  ) -> None:
20
22
  key = "google-secret-manager"
21
23
  name = "GoogleSecretManager"
22
24
  super().__init__(
23
- key, name, log_config, service_key, credentials, credentials_path
25
+ key,
26
+ name,
27
+ log_config,
28
+ service_environment,
29
+ service_key,
30
+ environment,
31
+ credentials,
32
+ credentials_path,
24
33
  )
25
34
  self._client = secretmanager.SecretManagerServiceClient(
26
35
  credentials=self._credentials
@@ -15,7 +15,9 @@ class GoogleCloudStorage(GoogleClientManager):
15
15
  def __init__(
16
16
  self,
17
17
  log_config: SimpleConfig,
18
- service_key: BaseTypes.OptionalString = None,
18
+ service_environment: Optional[BaseEnums.EnvironmentType] = None,
19
+ service_key: Optional[BaseEnums.Service] = None,
20
+ environment: Optional[BaseEnums.EnvironmentType] = None,
19
21
  credentials: Optional[Credentials] = None,
20
22
  credentials_path: Optional[Union[Path, str]] = None,
21
23
  bucket_name: BaseTypes.OptionalString = None,
@@ -24,7 +26,14 @@ class GoogleCloudStorage(GoogleClientManager):
24
26
  key = "google-cloud-storage"
25
27
  name = "GoogleCloudStorage"
26
28
  super().__init__(
27
- key, name, log_config, service_key, credentials, credentials_path
29
+ key,
30
+ name,
31
+ log_config,
32
+ service_environment,
33
+ service_key,
34
+ environment,
35
+ credentials,
36
+ credentials_path,
28
37
  )
29
38
  self._client = Client(credentials=self._credentials)
30
39
  self._bucket_name = bucket_name or os.getenv("GCS_BUCKET_NAME")
@@ -5,36 +5,37 @@ from google.cloud.pubsub_v1.subscriber.futures import StreamingPullFuture
5
5
  from google.cloud.pubsub_v1.subscriber.message import Message
6
6
  from google.oauth2.service_account import Credentials
7
7
  from pathlib import Path
8
- from pydantic import BaseModel
9
- from typing import Awaitable, Callable, Dict, List, Optional, Union, cast
8
+ from typing import Dict, List, Optional, Union, cast
9
+ from maleo_foundation.controller_types import ControllerTypes
10
+ from maleo_foundation.enums import BaseEnums
10
11
  from maleo_foundation.managers.client.google.base import GoogleClientManager
11
-
12
- SyncController = Callable[[str, Message], bool]
13
- AsyncController = Callable[[str, Message], Awaitable[bool]]
14
- Controller = Union[SyncController, AsyncController]
15
- OptionalController = Optional[Controller]
16
-
17
-
18
- class SubscriptionConfigurations(BaseModel):
19
- subscription_name: str
20
- max_messages: int = 10
21
- ack_deadline: int = 10
22
- controller: OptionalController = None
12
+ from maleo_foundation.models.transfers.general.configurations.pubsub.subscription import (
13
+ ExtendedSubscriptionConfigurations,
14
+ )
23
15
 
24
16
 
25
17
  class SubscriptionManager(GoogleClientManager):
26
18
  def __init__(
27
19
  self,
28
- subscriptions: List[SubscriptionConfigurations],
20
+ subscriptions: List[ExtendedSubscriptionConfigurations],
29
21
  log_config,
30
- service_key: Optional[str] = None,
22
+ service_environment: Optional[BaseEnums.EnvironmentType] = None,
23
+ service_key: Optional[BaseEnums.Service] = None,
24
+ environment: Optional[BaseEnums.EnvironmentType] = None,
31
25
  credentials: Optional[Credentials] = None,
32
26
  credentials_path: Optional[Union[Path, str]] = None,
33
27
  ):
34
28
  key = "google-subscription-manager"
35
29
  name = "GoogleSubscriptionManager"
36
30
  super().__init__(
37
- key, name, log_config, service_key, credentials, credentials_path
31
+ key,
32
+ name,
33
+ log_config,
34
+ service_environment,
35
+ service_key,
36
+ environment,
37
+ credentials,
38
+ credentials_path,
38
39
  )
39
40
  self.subscriber = pubsub_v1.SubscriberClient(credentials=self._credentials)
40
41
  self.subscriptions = subscriptions
@@ -42,19 +43,28 @@ class SubscriptionManager(GoogleClientManager):
42
43
  self.loop: Optional[asyncio.AbstractEventLoop] = None
43
44
 
44
45
  async def _handle_async_controller(
45
- self, controller: AsyncController, subscription_name: str, message: Message
46
+ self,
47
+ controller: ControllerTypes.AsyncMessageController,
48
+ subscription_name: str,
49
+ message: Message,
46
50
  ) -> None:
47
51
  success = await controller(subscription_name, message)
48
52
  message.ack() if success else message.nack()
49
53
 
50
54
  def _handle_sync_controller(
51
- self, controller: SyncController, subscription_name: str, message: Message
55
+ self,
56
+ controller: ControllerTypes.SyncMessageController,
57
+ subscription_name: str,
58
+ message: Message,
52
59
  ) -> None:
53
60
  success = controller(subscription_name, message)
54
61
  message.ack() if success else message.nack()
55
62
 
56
63
  def _message_callback(
57
- self, controller: OptionalController, subscription_name: str, message: Message
64
+ self,
65
+ controller: ControllerTypes.OptionalMessageController,
66
+ subscription_name: str,
67
+ message: Message,
58
68
  ):
59
69
  # If controller is not given, conduct default message processing
60
70
  if controller is None:
@@ -68,13 +78,17 @@ class SubscriptionManager(GoogleClientManager):
68
78
  raise RuntimeError("Event loop not set in SubscriptionManager")
69
79
  asyncio.run_coroutine_threadsafe(
70
80
  self._handle_async_controller(
71
- cast(AsyncController, controller), subscription_name, message
81
+ cast(ControllerTypes.AsyncMessageController, controller),
82
+ subscription_name,
83
+ message,
72
84
  ),
73
85
  self.loop,
74
86
  )
75
87
  else:
76
88
  self._handle_sync_controller(
77
- cast(SyncController, controller), subscription_name, message
89
+ cast(ControllerTypes.SyncMessageController, controller),
90
+ subscription_name,
91
+ message,
78
92
  )
79
93
 
80
94
  def _default_message_processing(
@@ -94,18 +108,18 @@ class SubscriptionManager(GoogleClientManager):
94
108
  message.nack()
95
109
 
96
110
  async def _start_subscription_listener(
97
- self, config: SubscriptionConfigurations
111
+ self, config: ExtendedSubscriptionConfigurations
98
112
  ) -> None:
99
113
  if self.credentials.project_id is None:
100
114
  raise ValueError("Project ID must be set in credentials")
101
115
  subscription_path = self.subscriber.subscription_path(
102
- self.credentials.project_id, config.subscription_name
116
+ self.credentials.project_id, config.id
103
117
  )
104
118
  flow_control = pubsub_v1.types.FlowControl(max_messages=config.max_messages)
105
119
  future = self.subscriber.subscribe(
106
120
  subscription_path,
107
121
  callback=lambda message: self._message_callback(
108
- config.controller, config.subscription_name, message
122
+ config.controller, config.id, message
109
123
  ),
110
124
  flow_control=flow_control,
111
125
  await_callbacks_on_shutdown=True,
@@ -117,7 +131,7 @@ class SubscriptionManager(GoogleClientManager):
117
131
  if not isinstance(e, asyncio.CancelledError):
118
132
  self._logger.error(
119
133
  "Listener error for subscription '%s': %s",
120
- config.subscription_name,
134
+ config.id,
121
135
  e,
122
136
  exc_info=True,
123
137
  )
@@ -74,7 +74,9 @@ class MaleoClientManager(ClientManager):
74
74
  key,
75
75
  name,
76
76
  service_manager.log_config,
77
- service_manager.configurations.service.key,
77
+ service_manager.settings.ENVIRONMENT,
78
+ service_manager.settings.SERVICE_KEY,
79
+ environment,
78
80
  )
79
81
  self._environment = environment
80
82
 
@@ -82,10 +84,6 @@ class MaleoClientManager(ClientManager):
82
84
  def service_manager(self) -> ServiceManager:
83
85
  return self._service_manager
84
86
 
85
- @property
86
- def environment(self) -> BaseEnums.EnvironmentType:
87
- return self._environment
88
-
89
87
  def _initialize_controllers(self) -> None:
90
88
  # * Initialize managers
91
89
  http_controller_manager = ClientHTTPControllerManager(url=self._url)
@@ -9,9 +9,13 @@ from maleo_foundation.utils.logging import SimpleConfig
9
9
 
10
10
 
11
11
  class CredentialManager:
12
- def __init__(self, settings: Settings, log_config: SimpleConfig):
13
- self.settings = settings
12
+ def __init__(
13
+ self,
14
+ log_config: SimpleConfig,
15
+ settings: Settings,
16
+ ):
14
17
  self.log_config = log_config
18
+ self.settings = settings
15
19
  self._initialize()
16
20
 
17
21
  def _load_google_credentials(self) -> None:
@@ -51,16 +51,14 @@ class ServiceManager:
51
51
  self,
52
52
  db_metadata: MetaData,
53
53
  log_config: SimpleConfig,
54
- settings: Optional[Settings] = None,
54
+ settings: Settings,
55
55
  additional_topics_configurations: Optional[
56
56
  AdditionalTopicsConfigurations
57
57
  ] = None,
58
58
  ):
59
59
  self._db_metadata = db_metadata # * Declare DB Metadata
60
60
  self._log_config = log_config # * Declare log config
61
- self._settings = (
62
- settings if settings is not None else Settings() # type: ignore
63
- ) # * Initialize settings
61
+ self._settings = settings # * Initialize settings
64
62
 
65
63
  # * Disable google cloud logging if environment is local
66
64
  if self._settings.ENVIRONMENT == "local":
@@ -134,22 +132,34 @@ class ServiceManager:
134
132
 
135
133
  def _initialize_loggers(self) -> None:
136
134
  application = ApplicationLogger(
137
- service_key=self.configurations.service.key, **self._log_config.model_dump()
135
+ environment=self.settings.ENVIRONMENT,
136
+ service_key=self.settings.SERVICE_KEY,
137
+ **self._log_config.model_dump(),
138
138
  )
139
139
  cache = CacheLogger(
140
- service_key=self.configurations.service.key, **self._log_config.model_dump()
140
+ environment=self.settings.ENVIRONMENT,
141
+ service_key=self.settings.SERVICE_KEY,
142
+ **self._log_config.model_dump(),
141
143
  )
142
144
  database = DatabaseLogger(
143
- service_key=self.configurations.service.key, **self._log_config.model_dump()
145
+ environment=self.settings.ENVIRONMENT,
146
+ service_key=self.settings.SERVICE_KEY,
147
+ **self._log_config.model_dump(),
144
148
  )
145
149
  middleware = MiddlewareLogger(
146
- service_key=self.configurations.service.key, **self._log_config.model_dump()
150
+ environment=self.settings.ENVIRONMENT,
151
+ service_key=self.settings.SERVICE_KEY,
152
+ **self._log_config.model_dump(),
147
153
  )
148
154
  repository = RepositoryLogger(
149
- service_key=self.configurations.service.key, **self._log_config.model_dump()
155
+ environment=self.settings.ENVIRONMENT,
156
+ service_key=self.settings.SERVICE_KEY,
157
+ **self._log_config.model_dump(),
150
158
  )
151
159
  service = ServiceLogger(
152
- service_key=self.configurations.service.key, **self._log_config.model_dump()
160
+ environment=self.settings.ENVIRONMENT,
161
+ service_key=self.settings.SERVICE_KEY,
162
+ **self._log_config.model_dump(),
153
163
  )
154
164
  self._loggers = Loggers(
155
165
  application=application,
@@ -166,8 +176,8 @@ class ServiceManager:
166
176
 
167
177
  async def _clear_cache(self) -> None:
168
178
  prefixes = [
169
- self.configurations.service.key,
170
- f"google-cloud-storage:{self.configurations.service.key}",
179
+ self.settings.SERVICE_KEY,
180
+ f"google-cloud-storage:{self.settings.SERVICE_KEY}",
171
181
  ]
172
182
  for prefix in prefixes:
173
183
  async for key in self._redis.scan_iter(f"{prefix}*"):
@@ -243,7 +253,9 @@ class ServiceManager:
243
253
 
244
254
  def _initialize_foundation(self) -> None:
245
255
  self._foundation = MaleoFoundationClientManager(
246
- log_config=self._log_config, service_key=self._settings.SERVICE_KEY
256
+ log_config=self._log_config,
257
+ service_environment=self._settings.ENVIRONMENT,
258
+ service_key=self._settings.SERVICE_KEY,
247
259
  )
248
260
 
249
261
  @property
@@ -8,6 +8,12 @@ from maleo_foundation.types import BaseTypes
8
8
 
9
9
 
10
10
  class BaseGeneralSchemas:
11
+ class ServiceContext(BaseModel):
12
+ key: BaseEnums.Service = Field(..., description="Service's key")
13
+ environment: BaseEnums.EnvironmentType = Field(
14
+ ..., description="Service's environment"
15
+ )
16
+
11
17
  class DateFilter(BaseModel):
12
18
  name: str = Field(..., description="Column name.")
13
19
  from_date: BaseTypes.OptionalDatetime = Field(None, description="From date.")
@@ -95,12 +101,6 @@ class BaseGeneralSchemas:
95
101
 
96
102
  return self
97
103
 
98
- class OperationServiceContext(BaseModel):
99
- key: BaseEnums.Service = Field(..., description="Service's key")
100
- environment: BaseEnums.EnvironmentType = Field(
101
- ..., description="Service's environment"
102
- )
103
-
104
104
  class OperationTimestamps(BaseModel):
105
105
  started_at: BaseTypes.OptionalDatetime = Field(
106
106
  None, description="Started at timestamp (Optional)"
@@ -139,12 +139,8 @@ class BaseGeneralSchemas:
139
139
 
140
140
  class DatabaseOperationResult(BaseModel):
141
141
  data_id: int = Field(..., ge=1, description="Data's ID")
142
- old_data: BaseTypes.OptionalStringToAnyDict = Field(
143
- None, description="Old data"
144
- )
145
- new_data: BaseTypes.OptionalStringToAnyDict = Field(
146
- None, description="New data"
147
- )
142
+ old_data: BaseTypes.OptionalAny = Field(None, description="Old data")
143
+ new_data: BaseTypes.OptionalAny = Field(None, description="New data")
148
144
 
149
145
  @model_validator(mode="after")
150
146
  def validate_data(self) -> Self:
@@ -7,7 +7,7 @@ class MaleoClientConfigurations(BaseModel):
7
7
  environment: BaseEnums.EnvironmentType = Field(
8
8
  ..., description="Client's environment"
9
9
  )
10
- key: str = Field(..., description="Client's key")
10
+ key: BaseEnums.Service = Field(..., description="Client's key")
11
11
  name: str = Field(..., description="Client's name")
12
12
  url: str = Field(..., description="Client's URL")
13
13
 
@@ -0,0 +1,16 @@
1
+ from pydantic import BaseModel, ConfigDict, Field
2
+ from maleo_foundation.controller_types import ControllerTypes
3
+
4
+
5
+ class SubscriptionConfigurations(BaseModel):
6
+ model_config = ConfigDict(arbitrary_types_allowed=True)
7
+
8
+ id: str = Field(..., description="Subscription's ID")
9
+ max_messages: int = Field(10, description="Subscription's Max messages")
10
+ ack_deadline: int = Field(10, description="Subscription's ACK deadline")
11
+
12
+
13
+ class ExtendedSubscriptionConfigurations(SubscriptionConfigurations):
14
+ controller: ControllerTypes.OptionalMessageController = Field(
15
+ None, description="Optional message controller"
16
+ )
@@ -1,8 +1,9 @@
1
1
  from pydantic import BaseModel, Field
2
+ from maleo_foundation.enums import BaseEnums
2
3
 
3
4
 
4
5
  class ServiceConfigurations(BaseModel):
5
- key: str = Field(..., description="Service's key")
6
+ key: BaseEnums.Service = Field(..., description="Service's key")
6
7
  name: str = Field(..., description="Service's name")
7
8
  host: str = Field(..., description="Service's host")
8
9
  port: int = Field(..., description="Service's port")
@@ -10,7 +10,7 @@ class Operation(BaseModel):
10
10
  request_context: RequestContext = Field(..., description="Request context")
11
11
  authentication: Authentication = Field(..., description="Authentication")
12
12
  authorization: Optional[Authorization] = Field(None, description="Authorization")
13
- service: BaseGeneralSchemas.OperationServiceContext = Field(
13
+ service: BaseGeneralSchemas.ServiceContext = Field(
14
14
  ..., description="Service's context"
15
15
  )
16
16
  timestamps: BaseGeneralSchemas.OperationTimestamps = Field(
@@ -34,7 +34,7 @@ class DatabaseOperation(BaseModel):
34
34
  request_context: RequestContext = Field(..., description="Request context")
35
35
  authentication: Authentication = Field(..., description="Authentication")
36
36
  authorization: Optional[Authorization] = Field(None, description="Authorization")
37
- service: BaseGeneralSchemas.OperationServiceContext = Field(
37
+ service: BaseGeneralSchemas.ServiceContext = Field(
38
38
  ..., description="Service's context"
39
39
  )
40
40
  timestamps: BaseGeneralSchemas.OperationTimestamps = Field(
@@ -7,7 +7,7 @@ from maleo_foundation.types import BaseTypes
7
7
 
8
8
  class Settings(BaseSettings):
9
9
  ENVIRONMENT: BaseEnums.EnvironmentType = Field(..., description="Environment")
10
- SERVICE_KEY: str = Field(..., description="Service's key")
10
+ SERVICE_KEY: BaseEnums.Service = Field(..., description="Service's key")
11
11
  ROOT_PATH: str = Field("", description="Application's root path")
12
12
  GOOGLE_CREDENTIALS_PATH: str = Field(
13
13
  "/credentials/maleo-google-service-account.json",
@@ -4,6 +4,7 @@ from httpx import RequestError
4
4
  from pydantic import ValidationError
5
5
  from typing import Optional
6
6
  from maleo_foundation.enums import BaseEnums
7
+ from maleo_foundation.models.transfers.general.request import RequestContext
7
8
  from maleo_foundation.models.transfers.results.client.service import (
8
9
  BaseClientServiceResultsTransfers,
9
10
  )
@@ -30,10 +31,16 @@ class BaseClientExceptions:
30
31
  fail_result_class: type[
31
32
  BaseClientServiceResultsTransfers.Fail
32
33
  ] = BaseClientServiceResultsTransfers.Fail,
34
+ request_context: Optional[RequestContext] = None,
33
35
  ) -> BaseClientServiceResultsTransfers.Fail:
34
36
  if logger:
37
+ log_string = f"{category} occurred while {summary}: '{str(e)}'"
38
+ if request_context is not None:
39
+ log_string = (
40
+ f"Request | ID: {request_context.request_id} - {log_string}"
41
+ )
35
42
  logger.error(
36
- f"{category} occurred while {summary}: '{str(e)}'",
43
+ log_string,
37
44
  exc_info=True,
38
45
  )
39
46
  return fail_result_class(
@@ -77,6 +84,12 @@ class BaseClientExceptions:
77
84
  def decorator(func):
78
85
  @wraps(func)
79
86
  async def wrapper(*args, **kwargs):
87
+ # Search for RequestContext in args and kwargs
88
+ request_context: Optional[RequestContext] = None
89
+ for arg in list(args) + list(kwargs.values()):
90
+ if isinstance(arg, RequestContext):
91
+ request_context = arg
92
+ break
80
93
  try:
81
94
  return await func(*args, **kwargs)
82
95
  except ValidationError as e:
@@ -96,6 +109,7 @@ class BaseClientExceptions:
96
109
  status_update_type=status_update_type,
97
110
  logger=logger,
98
111
  fail_result_class=fail_result_class,
112
+ request_context=request_context,
99
113
  )
100
114
  except RequestError as e:
101
115
  return BaseClientExceptions._exception_handler(
@@ -114,6 +128,7 @@ class BaseClientExceptions:
114
128
  status_update_type=status_update_type,
115
129
  logger=logger,
116
130
  fail_result_class=fail_result_class,
131
+ request_context=request_context,
117
132
  )
118
133
  except Exception as e:
119
134
  return BaseClientExceptions._exception_handler(
@@ -132,6 +147,7 @@ class BaseClientExceptions:
132
147
  status_update_type=status_update_type,
133
148
  logger=logger,
134
149
  fail_result_class=fail_result_class,
150
+ request_context=request_context,
135
151
  )
136
152
 
137
153
  return wrapper
@@ -159,6 +175,12 @@ class BaseClientExceptions:
159
175
  def decorator(func):
160
176
  @wraps(func)
161
177
  def wrapper(*args, **kwargs):
178
+ # Search for RequestContext in args and kwargs
179
+ request_context: Optional[RequestContext] = None
180
+ for arg in list(args) + list(kwargs.values()):
181
+ if isinstance(arg, RequestContext):
182
+ request_context = arg
183
+ break
162
184
  try:
163
185
  return func(*args, **kwargs)
164
186
  except ValidationError as e:
@@ -178,6 +200,7 @@ class BaseClientExceptions:
178
200
  status_update_type=status_update_type,
179
201
  logger=logger,
180
202
  fail_result_class=fail_result_class,
203
+ request_context=request_context,
181
204
  )
182
205
  except RequestError as e:
183
206
  return BaseClientExceptions._exception_handler(
@@ -196,6 +219,7 @@ class BaseClientExceptions:
196
219
  status_update_type=status_update_type,
197
220
  logger=logger,
198
221
  fail_result_class=fail_result_class,
222
+ request_context=request_context,
199
223
  )
200
224
  except Exception as e:
201
225
  return BaseClientExceptions._exception_handler(
@@ -214,6 +238,7 @@ class BaseClientExceptions:
214
238
  status_update_type=status_update_type,
215
239
  logger=logger,
216
240
  fail_result_class=fail_result_class,
241
+ request_context=request_context,
217
242
  )
218
243
 
219
244
  return wrapper
@@ -4,6 +4,7 @@ from pydantic import ValidationError
4
4
  from sqlalchemy.exc import SQLAlchemyError
5
5
  from typing import Optional
6
6
  from maleo_foundation.enums import BaseEnums
7
+ from maleo_foundation.models.transfers.general.request import RequestContext
7
8
  from maleo_foundation.models.transfers.results.service.general import (
8
9
  BaseServiceGeneralResultsTransfers,
9
10
  )
@@ -30,10 +31,16 @@ class BaseServiceExceptions:
30
31
  fail_result_class: type[
31
32
  BaseServiceGeneralResultsTransfers.Fail
32
33
  ] = BaseServiceGeneralResultsTransfers.Fail,
34
+ request_context: Optional[RequestContext] = None,
33
35
  ) -> BaseServiceGeneralResultsTransfers.Fail:
34
- if logger:
36
+ if logger is not None:
37
+ log_string = f"{category} occurred while {summary}: '{str(e)}'"
38
+ if request_context is not None:
39
+ log_string = (
40
+ f"Request | ID: {request_context.request_id} - {log_string}"
41
+ )
35
42
  logger.error(
36
- f"{category} occurred while {summary}: '{str(e)}'",
43
+ log_string,
37
44
  exc_info=True,
38
45
  )
39
46
  return fail_result_class(
@@ -77,6 +84,12 @@ class BaseServiceExceptions:
77
84
  def decorator(func):
78
85
  @wraps(func)
79
86
  async def wrapper(*args, **kwargs):
87
+ # Search for RequestContext in args and kwargs
88
+ request_context: Optional[RequestContext] = None
89
+ for arg in list(args) + list(kwargs.values()):
90
+ if isinstance(arg, RequestContext):
91
+ request_context = arg
92
+ break
80
93
  try:
81
94
  return await func(*args, **kwargs)
82
95
  except ValidationError as e:
@@ -96,6 +109,7 @@ class BaseServiceExceptions:
96
109
  status_update_type=status_update_type,
97
110
  logger=logger,
98
111
  fail_result_class=fail_result_class,
112
+ request_context=request_context,
99
113
  )
100
114
  except SQLAlchemyError as e:
101
115
  return BaseServiceExceptions._exception_handler(
@@ -114,6 +128,7 @@ class BaseServiceExceptions:
114
128
  status_update_type=status_update_type,
115
129
  logger=logger,
116
130
  fail_result_class=fail_result_class,
131
+ request_context=request_context,
117
132
  )
118
133
  except Exception as e:
119
134
  return BaseServiceExceptions._exception_handler(
@@ -132,6 +147,7 @@ class BaseServiceExceptions:
132
147
  status_update_type=status_update_type,
133
148
  logger=logger,
134
149
  fail_result_class=fail_result_class,
150
+ request_context=request_context,
135
151
  )
136
152
 
137
153
  return wrapper
@@ -159,6 +175,12 @@ class BaseServiceExceptions:
159
175
  def decorator(func):
160
176
  @wraps(func)
161
177
  def wrapper(*args, **kwargs):
178
+ # Search for RequestContext in args and kwargs
179
+ request_context: Optional[RequestContext] = None
180
+ for arg in list(args) + list(kwargs.values()):
181
+ if isinstance(arg, RequestContext):
182
+ request_context = arg
183
+ break
162
184
  try:
163
185
  return func(*args, **kwargs)
164
186
  except ValidationError as e:
@@ -178,6 +200,7 @@ class BaseServiceExceptions:
178
200
  status_update_type=status_update_type,
179
201
  logger=logger,
180
202
  fail_result_class=fail_result_class,
203
+ request_context=request_context,
181
204
  )
182
205
  except SQLAlchemyError as e:
183
206
  return BaseServiceExceptions._exception_handler(
@@ -196,6 +219,7 @@ class BaseServiceExceptions:
196
219
  status_update_type=status_update_type,
197
220
  logger=logger,
198
221
  fail_result_class=fail_result_class,
222
+ request_context=request_context,
199
223
  )
200
224
  except Exception as e:
201
225
  return BaseServiceExceptions._exception_handler(
@@ -214,6 +238,7 @@ class BaseServiceExceptions:
214
238
  status_update_type=status_update_type,
215
239
  logger=logger,
216
240
  fail_result_class=fail_result_class,
241
+ request_context=request_context,
217
242
  )
218
243
 
219
244
  return wrapper
@@ -57,21 +57,33 @@ class SimpleConfig(BaseModel):
57
57
  class BaseLogger(logging.Logger):
58
58
  def __init__(
59
59
  self,
60
- dir: str,
61
60
  type: BaseEnums.LoggerType,
62
- service_key: BaseTypes.OptionalString = None,
61
+ dir: str,
62
+ environment: Optional[BaseEnums.EnvironmentType] = None,
63
+ service_key: Optional[BaseEnums.Service] = None,
63
64
  client_key: BaseTypes.OptionalString = None,
64
65
  level: BaseEnums.LoggerLevel = BaseEnums.LoggerLevel.INFO,
65
66
  google_cloud_logging: Optional[GoogleCloudLogging] = None,
66
67
  ):
67
68
  self._type = type # * Declare logger type
68
69
 
69
- # * Ensure service_key exists
70
- self._service_key = service_key or os.getenv("SERVICE_KEY")
71
- if self._service_key is None:
70
+ # Ensure environment exists
71
+ actual_environment = environment or os.getenv("ENVIRONMENT")
72
+ if actual_environment is None:
73
+ raise ValueError(
74
+ "ENVIRONMENT environment variable must be set if 'environment' is set to None"
75
+ )
76
+ else:
77
+ self._environment = BaseEnums.EnvironmentType(actual_environment)
78
+
79
+ # Ensure service_key exists
80
+ actual_service_key = service_key or os.getenv("SERVICE_KEY")
81
+ if actual_service_key is None:
72
82
  raise ValueError(
73
83
  "SERVICE_KEY environment variable must be set if 'service_key' is set to None"
74
84
  )
85
+ else:
86
+ self._service_key = BaseEnums.Service(actual_service_key)
75
87
 
76
88
  self._client_key = client_key # * Declare client key
77
89
 
@@ -82,10 +94,11 @@ class BaseLogger(logging.Logger):
82
94
  )
83
95
 
84
96
  # * Define logger name
97
+ base_name = f"{self._environment} - {self._service_key} - {self._type}"
85
98
  if self._type == BaseEnums.LoggerType.CLIENT:
86
- self._name = f"{self._service_key} - {self._type} - {self._client_key}"
99
+ self._name = f"{base_name} - {self._client_key}"
87
100
  else:
88
- self._name = f"{self._service_key} - {self._type}"
101
+ self._name = base_name
89
102
 
90
103
  super().__init__(self._name, level) # * Init the superclass's logger
91
104
 
@@ -111,7 +124,9 @@ class BaseLogger(logging.Logger):
111
124
  )
112
125
  self.addHandler(cloud_logging_handler)
113
126
  else:
114
- self.info("Cloud logging is not configured.")
127
+ self.warning(
128
+ "Cloud logging is not configured. Will not add cloud loggin handler"
129
+ )
115
130
 
116
131
  # * Define log directory
117
132
  if self._type == BaseEnums.LoggerType.CLIENT:
@@ -164,13 +179,15 @@ class ApplicationLogger(BaseLogger):
164
179
  def __init__(
165
180
  self,
166
181
  dir: str,
167
- service_key: BaseTypes.OptionalString = None,
182
+ environment: Optional[BaseEnums.EnvironmentType] = None,
183
+ service_key: Optional[BaseEnums.Service] = None,
168
184
  level: BaseEnums.LoggerLevel = BaseEnums.LoggerLevel.INFO,
169
185
  google_cloud_logging: Optional[GoogleCloudLogging] = None,
170
186
  ):
171
187
  super().__init__(
172
- dir=dir,
173
188
  type=BaseEnums.LoggerType.APPLICATION,
189
+ dir=dir,
190
+ environment=environment,
174
191
  service_key=service_key,
175
192
  client_key=None,
176
193
  level=level,
@@ -182,13 +199,15 @@ class CacheLogger(BaseLogger):
182
199
  def __init__(
183
200
  self,
184
201
  dir: str,
185
- service_key: BaseTypes.OptionalString = None,
202
+ environment: Optional[BaseEnums.EnvironmentType] = None,
203
+ service_key: Optional[BaseEnums.Service] = None,
186
204
  level: BaseEnums.LoggerLevel = BaseEnums.LoggerLevel.INFO,
187
205
  google_cloud_logging: Optional[GoogleCloudLogging] = None,
188
206
  ):
189
207
  super().__init__(
190
208
  dir=dir,
191
209
  type=BaseEnums.LoggerType.CACHE,
210
+ environment=environment,
192
211
  service_key=service_key,
193
212
  client_key=None,
194
213
  level=level,
@@ -201,13 +220,15 @@ class ClientLogger(BaseLogger):
201
220
  self,
202
221
  dir: str,
203
222
  client_key: str,
204
- service_key: BaseTypes.OptionalString = None,
223
+ environment: Optional[BaseEnums.EnvironmentType] = None,
224
+ service_key: Optional[BaseEnums.Service] = None,
205
225
  level: BaseEnums.LoggerLevel = BaseEnums.LoggerLevel.INFO,
206
226
  google_cloud_logging: Optional[GoogleCloudLogging] = None,
207
227
  ):
208
228
  super().__init__(
209
- dir=dir,
210
229
  type=BaseEnums.LoggerType.CLIENT,
230
+ dir=dir,
231
+ environment=environment,
211
232
  service_key=service_key,
212
233
  client_key=client_key,
213
234
  level=level,
@@ -219,13 +240,15 @@ class DatabaseLogger(BaseLogger):
219
240
  def __init__(
220
241
  self,
221
242
  dir: str,
222
- service_key: BaseTypes.OptionalString = None,
243
+ environment: Optional[BaseEnums.EnvironmentType] = None,
244
+ service_key: Optional[BaseEnums.Service] = None,
223
245
  level=BaseEnums.LoggerLevel.INFO,
224
246
  google_cloud_logging=None,
225
247
  ):
226
248
  super().__init__(
227
- dir=dir,
228
249
  type=BaseEnums.LoggerType.DATABASE,
250
+ dir=dir,
251
+ environment=environment,
229
252
  service_key=service_key,
230
253
  client_key=None,
231
254
  level=level,
@@ -237,13 +260,15 @@ class MiddlewareLogger(BaseLogger):
237
260
  def __init__(
238
261
  self,
239
262
  dir: str,
240
- service_key: BaseTypes.OptionalString = None,
263
+ environment: Optional[BaseEnums.EnvironmentType] = None,
264
+ service_key: Optional[BaseEnums.Service] = None,
241
265
  level=BaseEnums.LoggerLevel.INFO,
242
266
  google_cloud_logging=None,
243
267
  ):
244
268
  super().__init__(
245
- dir=dir,
246
269
  type=BaseEnums.LoggerType.MIDDLEWARE,
270
+ dir=dir,
271
+ environment=environment,
247
272
  service_key=service_key,
248
273
  client_key=None,
249
274
  level=level,
@@ -255,13 +280,15 @@ class RepositoryLogger(BaseLogger):
255
280
  def __init__(
256
281
  self,
257
282
  dir: str,
258
- service_key: BaseTypes.OptionalString = None,
283
+ environment: Optional[BaseEnums.EnvironmentType] = None,
284
+ service_key: Optional[BaseEnums.Service] = None,
259
285
  level: BaseEnums.LoggerLevel = BaseEnums.LoggerLevel.INFO,
260
286
  google_cloud_logging: Optional[GoogleCloudLogging] = None,
261
287
  ):
262
288
  super().__init__(
263
- dir=dir,
264
289
  type=BaseEnums.LoggerType.REPOSITORY,
290
+ dir=dir,
291
+ environment=environment,
265
292
  service_key=service_key,
266
293
  client_key=None,
267
294
  level=level,
@@ -273,13 +300,15 @@ class ServiceLogger(BaseLogger):
273
300
  def __init__(
274
301
  self,
275
302
  dir: str,
276
- service_key: BaseTypes.OptionalString = None,
303
+ environment: Optional[BaseEnums.EnvironmentType] = None,
304
+ service_key: Optional[BaseEnums.Service] = None,
277
305
  level: BaseEnums.LoggerLevel = BaseEnums.LoggerLevel.INFO,
278
306
  google_cloud_logging: Optional[GoogleCloudLogging] = None,
279
307
  ):
280
308
  super().__init__(
281
- dir=dir,
282
309
  type=BaseEnums.LoggerType.SERVICE,
310
+ dir=dir,
311
+ environment=environment,
283
312
  service_key=service_key,
284
313
  client_key=None,
285
314
  level=level,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maleo_foundation
3
- Version: 0.3.70
3
+ Version: 0.3.72
4
4
  Summary: Foundation package for Maleo
5
5
  Author-email: Agra Bima Yuda <agra@nexmedis.com>
6
6
  License: MIT
@@ -2,12 +2,13 @@ maleo_foundation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
2
2
  maleo_foundation/authentication.py,sha256=2Y2py-teDSO_YTFdZiPtuYhC8r3qIzn7CKyLNN8b2NQ,2727
3
3
  maleo_foundation/authorization.py,sha256=8P1hleBYRv8kda4uQcbHVujHVAlI92YV1Flfzf-oJEU,285
4
4
  maleo_foundation/constants.py,sha256=cgW2TjXYEdQRoYCL3fMk3r5B2Yr-Av67CaEAdY5SZ6o,1529
5
+ maleo_foundation/controller_types.py,sha256=Q7kAjUenQ-7QgXdsVLLWKfvEl1_s7r_QfOoftDXT6lc,1097
5
6
  maleo_foundation/enums.py,sha256=5ft9F3CcLM2lwDNGVVNFZRwol1Y_BLYJcxi3yPjsS7Y,6277
6
7
  maleo_foundation/extended_types.py,sha256=oOAYc5f89WcPt5OWEaNdeceENHiPVr4KDhdttg6bA_w,305
7
8
  maleo_foundation/rest_controller_result.py,sha256=uZxBxZ5hB98q1B4hNyRigHcO0560NYfUjq8L662aOPw,2172
8
9
  maleo_foundation/types.py,sha256=Tq50KOISbnsMslVGBCqlY77lRAQZa-UUFDGqqwRglow,2466
9
10
  maleo_foundation/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- maleo_foundation/client/manager.py,sha256=5Ww2CNbKOT4nifI8roO77xlBrxIKCTCUEJHCNbRjGX4,2729
11
+ maleo_foundation/client/manager.py,sha256=BENie7uqg4iku3rGmM6vq6LOoXrYAbGqwW09irS23PE,2914
11
12
  maleo_foundation/client/services/__init__.py,sha256=srDKoa3zRt-PvfHcXlFJbwagT0O3wwicL3qbMb3Odug,1104
12
13
  maleo_foundation/client/services/key.py,sha256=2OzlBygNsAW9WkTxHkQNneAy5jvrzXuxHvN-E5mBkxY,7856
13
14
  maleo_foundation/client/services/signature.py,sha256=c9uWHDjUsONlA9vwU_EBetsmUNc97qsHf4OfBzyi0MQ,6362
@@ -33,19 +34,19 @@ maleo_foundation/expanded_types/encryption/rsa.py,sha256=LJhZ6mnE4OB1eZnNTg21fv1
33
34
  maleo_foundation/managers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
35
  maleo_foundation/managers/cache.py,sha256=hML8vi2MXO2m2HeqB4eE6Ed4kl1iVXgEfpkB9tixs1Q,277
35
36
  maleo_foundation/managers/configuration.py,sha256=JmJFvKB6xCPwb8iYpwuNMpdcHfwPJYLFgXYcWwewMj8,1740
36
- maleo_foundation/managers/credential.py,sha256=um1M45deBEzTVfsUcpAtKEp3Rb_dH1qQrr8abkG_GeU,3057
37
+ maleo_foundation/managers/credential.py,sha256=ZQFae0cdERVtTZ2OGUgC8W6lI1RIlm2vjsAnqf2R234,3088
37
38
  maleo_foundation/managers/db.py,sha256=y0rQIg-vohhFUtck3v1LCdXov7XYjy9PFiCsVtcg8VI,6496
38
39
  maleo_foundation/managers/middleware.py,sha256=Uglwt4X3MauKtBvbPTyHl0-32od3IN6AYYUtiUCoV9I,2464
39
- maleo_foundation/managers/service.py,sha256=N8Dy0ppSdHIE3NXqmbwcXEIqgtMxnLHs8isVdKJbWAg,12398
40
+ maleo_foundation/managers/service.py,sha256=8oYBSi-qierlXdVhWoXcY1HwcKEsXmOOiWygRLm2vNM,12710
40
41
  maleo_foundation/managers/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
- maleo_foundation/managers/client/base.py,sha256=iM5xZjLm5VQqqpiYcba-rifW0LgkVd-gRTE6XwdOFqY,4369
42
- maleo_foundation/managers/client/maleo.py,sha256=aNh3I9EsxeD2rqx5WaXbZ5fjyyXVzvppHJiC98jJYfM,3163
42
+ maleo_foundation/managers/client/base.py,sha256=j48JYpcTzaGJPZzQAixPVCJtAB9EqDVxx-51hVGgw2k,5631
43
+ maleo_foundation/managers/client/maleo.py,sha256=ACZC-gvc36pwrqvEmEKeBDKAOAAqoRfuCXeAa6KrGBQ,3128
43
44
  maleo_foundation/managers/client/google/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
- maleo_foundation/managers/client/google/base.py,sha256=MUxGM3wtzdMkbghMdyQkRQ-AI_pG2qpTxq2n69kMF-A,1544
45
+ maleo_foundation/managers/client/google/base.py,sha256=azp4dqmKJyLCNv7uCS93kIs6jWZTbq1cU6mww6RN3FY,1741
45
46
  maleo_foundation/managers/client/google/parameter.py,sha256=emBgc1qCQcnETKYvwv35EqARjdO9igD0-F-Xuxx-fyU,1410
46
- maleo_foundation/managers/client/google/secret.py,sha256=75q32U-kcTljVb19MZQQ5sOVOnf1HkquyK8nIoyeMrY,5014
47
- maleo_foundation/managers/client/google/storage.py,sha256=uUc3RGu5PyGOKrObP-ub2Vpztqidu5BUADUrRTMxy7E,6569
48
- maleo_foundation/managers/client/google/subscription.py,sha256=KLXneM39r8Uzvevir_jL7s9-q4iSakNUkD_I66JGbng,5365
47
+ maleo_foundation/managers/client/google/secret.py,sha256=fwqeVL0uyefuZrySpvP9PJ8u-0YuAxZ3Nd9nA6A4UlI,5274
48
+ maleo_foundation/managers/client/google/storage.py,sha256=k-y0LrgjVVUX4PbGLOgBUOt0BEiQKXoHH-U3KtG5Kc4,6829
49
+ maleo_foundation/managers/client/google/subscription.py,sha256=0a9T1jh0CGyLb9CyBiixdZYxmCzdg0X15VYebqYt5M4,5686
49
50
  maleo_foundation/middlewares/authentication.py,sha256=b4dPkLKFqJBmhWKEvynTLe45Wax8jCcPq0luIlU_id0,4189
50
51
  maleo_foundation/middlewares/base.py,sha256=ZXMJTiuDBa6sIbgD_g1MhhlMkszsYkt3Ocl4boPtbEU,16825
51
52
  maleo_foundation/middlewares/cors.py,sha256=1QgRXOcURuEhBYMerclqbECgtAE4CFo0EhB4gJXu8Yg,2294
@@ -54,7 +55,7 @@ maleo_foundation/models/responses.py,sha256=WNAz67ewOyWV0oHyiB_BF_-sfaoDF-FVzcwg
54
55
  maleo_foundation/models/table.py,sha256=k0-OtahF2KRmvFUL8TborT6PoIhGsyoVrPJBKGg1QbU,1855
55
56
  maleo_foundation/models/schemas/__init__.py,sha256=tmjBCyG4uMRjiTbnbhIjZaR8q7zk0_J_CqnRzsSfoBQ,279
56
57
  maleo_foundation/models/schemas/encryption.py,sha256=S86FGlcBhyGxxZ5ObNSHTjSDwBUlUtLOMoCAKd5wE34,687
57
- maleo_foundation/models/schemas/general.py,sha256=5oQyGc2ZvaIysPnqRCC_KGtyOHmV_kRThwFs_9ZJ9OU,10071
58
+ maleo_foundation/models/schemas/general.py,sha256=q-ENf4Jn8H6tylQt6WKdLybYYXZATig8YBEWkroWVtQ,9994
58
59
  maleo_foundation/models/schemas/hash.py,sha256=jthDmu_VTBydffPruAIAiR8l0Xs6IrlgTptaP42zr1M,447
59
60
  maleo_foundation/models/schemas/key.py,sha256=LSEDQpaCxavwp5je2O-ZNyOPtrFW_lXDywF9LK-An1w,622
60
61
  maleo_foundation/models/schemas/parameter.py,sha256=OE1hg100lEa2IlGlT2Zz6PJ-OcC-6ZfDzsTOeJvvEig,3907
@@ -67,21 +68,22 @@ maleo_foundation/models/transfers/general/credentials.py,sha256=t6OhQb3DyGSfBpbq
67
68
  maleo_foundation/models/transfers/general/data.py,sha256=_J-Y5X2Nx8D1lpaR9ctpm54kUbxR7Vy00hO103uXtxE,1408
68
69
  maleo_foundation/models/transfers/general/database.py,sha256=VQYnZa8dYrqucSQdzkaPSrzLd4SJnpU8LPytUrWErO0,1245
69
70
  maleo_foundation/models/transfers/general/key.py,sha256=QV_kcxAlnrupBcGQK8tqz9FVYbivxwhgIsrmW7XDdME,845
70
- maleo_foundation/models/transfers/general/operation.py,sha256=M3DraArkFhgjNvA1StWfyS7W0Jhy3hIcdUWUYXlt7Do,2143
71
+ maleo_foundation/models/transfers/general/operation.py,sha256=T804JNy9cjLwgNTNkILLF1JSBu_laUECYBqUN2zEESY,2125
71
72
  maleo_foundation/models/transfers/general/request.py,sha256=W2aKxo0lQ-kV-4XpQEzxxa-odwLlGfOulh_wQKgcz9o,1920
72
- maleo_foundation/models/transfers/general/settings.py,sha256=1QkPq6GP33S5R718be3XBz0BCtApAuxlL-x21EZ2Xmo,1609
73
+ maleo_foundation/models/transfers/general/settings.py,sha256=LOlPVB8ns8NAIVHKVYv13jtlUbkuPHHOwyMqFes0T30,1623
73
74
  maleo_foundation/models/transfers/general/signature.py,sha256=TCTIy928EeBBeFLlyQ3_NozpR9FUcWXPQKIYIwyj66k,308
74
75
  maleo_foundation/models/transfers/general/token.py,sha256=aF7IXEYS4EnWtWquZexnrXcJBOl5M1lneo7yu7IiKYg,5022
75
76
  maleo_foundation/models/transfers/general/configurations/__init__.py,sha256=JG910HvVlFvE406Jku0fdOVYUHjedIsflyqCPafXF_Y,1666
76
77
  maleo_foundation/models/transfers/general/configurations/database.py,sha256=4j465vki3bCNGogrJLmMmF1uEXc-sUfyhwMeuaR5JyM,706
77
78
  maleo_foundation/models/transfers/general/configurations/middleware.py,sha256=gBm7yv-PYOPcv-u6SXq8cMWfuuo9LwPSXuqoJ4uw9h0,1761
78
- maleo_foundation/models/transfers/general/configurations/service.py,sha256=1sDBwJYvO7tlKz9YH7eIkfMPWmUqRkx7aW-EMw8tpBQ,306
79
+ maleo_foundation/models/transfers/general/configurations/service.py,sha256=9ls5So7P50gE0T0HjlskDMooL0RO3VmQl_N0H8HwutU,365
79
80
  maleo_foundation/models/transfers/general/configurations/cache/__init__.py,sha256=eCEeFFP4jN9FWFHWLadAnP1NoJH4CJQm7WRnXhmHUh0,264
80
81
  maleo_foundation/models/transfers/general/configurations/cache/redis.py,sha256=SNnI7hm8giKfR2Kp5sD_fmxo4Q5fkRCdi9zMKwTKPCs,1331
81
82
  maleo_foundation/models/transfers/general/configurations/client/__init__.py,sha256=1w17i9CH4bSQ40o8rwIew2F_id25XklFqI1YPowcHvQ,356
82
- maleo_foundation/models/transfers/general/configurations/client/maleo.py,sha256=0Hk6no800DdaAlv0SZ1OqVGxbp4LtJz1cJ0ZNbBejK4,2063
83
+ maleo_foundation/models/transfers/general/configurations/client/maleo.py,sha256=GkfRvpgcVlSoLNHhMMvf1g42w9Xf73gD5aBIsYukYJo,2077
83
84
  maleo_foundation/models/transfers/general/configurations/pubsub/__init__.py,sha256=BJqB2lxd7iFbm__3VKWPclE6ub_FMIVbhaO7yc2KzSU,505
84
85
  maleo_foundation/models/transfers/general/configurations/pubsub/publisher.py,sha256=hDBkq__mbALJgiX1cOYi0V-3JitfoEOexjGAEbsJgo0,1596
86
+ maleo_foundation/models/transfers/general/configurations/pubsub/subscription.py,sha256=WZJlySm6exDw84OKxsCY0SCDCepBsBb84Ydy0jL9GKg,633
85
87
  maleo_foundation/models/transfers/parameters/__init__.py,sha256=HiV7hPn8rUaN7XeOwC_VugYQ4QQO7kbZ0fsp11GDznQ,355
86
88
  maleo_foundation/models/transfers/parameters/client.py,sha256=2V1XvhSmIDDZL7MFVpD_dR5jWIoydQnFW67n9z6rRMA,4041
87
89
  maleo_foundation/models/transfers/parameters/general.py,sha256=NUFsrrfByN9OX9QLYc2Bn0LpNPoxrKBuZae-IVhOiyo,791
@@ -117,7 +119,7 @@ maleo_foundation/utils/cache.py,sha256=PWNef00iA2m0g3boR7JbzrJQIRITf5nKgdCmMs3s6
117
119
  maleo_foundation/utils/client.py,sha256=KDkIEqGX6Tw07Z5HHW4HrG8IWUVkErlqnVijXnpWZGQ,2940
118
120
  maleo_foundation/utils/controller.py,sha256=S69NluxjGCB_toAu3JDLi_izE0-x2ARE_7YK3V8T1Q0,7413
119
121
  maleo_foundation/utils/extractor.py,sha256=an9bKvwIniVvUCk0fSetUL_8VGBk_MNEtB2pwgkYb4k,2369
120
- maleo_foundation/utils/logging.py,sha256=sOQbvrLdlp1Vwx7y14YitzHx4IHh5iYaCt9WvdrapUI,9141
122
+ maleo_foundation/utils/logging.py,sha256=1M1_UJHdcRDxg31aJx4A33xiSPyPok9NQyyO8CtqZhw,10500
121
123
  maleo_foundation/utils/merger.py,sha256=UGiuH0EUQJu0WlS1xdPUuvnsNknd3k0DODjdiOTiBdI,704
122
124
  maleo_foundation/utils/query.py,sha256=mAoXadZuWx_ic6Z4VQ9K4GZxYgSNzpNS94W6xxqeFyg,8312
123
125
  maleo_foundation/utils/repository.py,sha256=fZqmApZUG9KqwrfURvyAIw_-7Y9EsLngoAoNcjJphtQ,2951
@@ -126,9 +128,9 @@ maleo_foundation/utils/dependencies/__init__.py,sha256=jJOo4uCTPiEvpgecsl4JEhKzu
126
128
  maleo_foundation/utils/dependencies/auth.py,sha256=3Z0b-Xi5PAKRKlbv-ZIT46YrQFkjiS7NhSDWZTOWm8I,650
127
129
  maleo_foundation/utils/dependencies/context.py,sha256=pw18j6LZgHdJQVKCvRH71mFZ_li8jP_wIgbtBMLXpxQ,271
128
130
  maleo_foundation/utils/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
129
- maleo_foundation/utils/exceptions/client.py,sha256=gGA7BWf2Fel33lYqMd2LJVvt1x0HO0OqbopAJCcYnbY,9665
131
+ maleo_foundation/utils/exceptions/client.py,sha256=adQ_ByuwpW_fswMBClXSUbvKblyfSLlnG4OMkX38X-w,10998
130
132
  maleo_foundation/utils/exceptions/request.py,sha256=p6rfya7HuqlfrvxFZm3KgTf95mPkQ6QCBlLyhiRfGtw,1600
131
- maleo_foundation/utils/exceptions/service.py,sha256=bhUvZb3rTx2UYwyVxbNjtKw7aru3UIVZptzTlGGk65g,9698
133
+ maleo_foundation/utils/exceptions/service.py,sha256=f7sa31YZ85xV6f6avRhas4YfryF_0DswehrOsbEIrL0,11043
132
134
  maleo_foundation/utils/formatter/__init__.py,sha256=qzn45FGoZeArJYmgFpdzKe-jp3yREGSrPfc4a-iZHe4,80
133
135
  maleo_foundation/utils/formatter/case.py,sha256=VsDTkKVZgN5b5O4Q6hkEzIDTf635FHS2BF_eY-NNngQ,1359
134
136
  maleo_foundation/utils/loaders/__init__.py,sha256=aBVS-zCBdb9t4Keh5cFJ4Vqv5lFHthJoHTaGPVjnvnU,284
@@ -138,7 +140,7 @@ maleo_foundation/utils/loaders/credential/__init__.py,sha256=g-cAxkTE2EtHaG8Tv52
138
140
  maleo_foundation/utils/loaders/credential/google.py,sha256=GCJl-bsKSSxoE_ERAkIzRrRNIbIEeqYOhHwzFuBr0mk,6576
139
141
  maleo_foundation/utils/loaders/key/__init__.py,sha256=RfqIbUxkdlx1xrbzJZPD_JHiRFNFLRuQs8JoUPCGCv4,108
140
142
  maleo_foundation/utils/loaders/key/rsa.py,sha256=UXcP0rr4QVacTsHLNQuU05wcow5CHWz-JW-zsVxlbPs,4121
141
- maleo_foundation-0.3.70.dist-info/METADATA,sha256=PXvEbtQEC5YtlzpyPkCPKB1dEcLxaSrEdmFtGaAkmfY,4150
142
- maleo_foundation-0.3.70.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
143
- maleo_foundation-0.3.70.dist-info/top_level.txt,sha256=_iBos3F_bhEOdjOnzeiEYSrCucasc810xXtLBXI8cQc,17
144
- maleo_foundation-0.3.70.dist-info/RECORD,,
143
+ maleo_foundation-0.3.72.dist-info/METADATA,sha256=PA8--eQwofJ8-IX0KJCTlh5LCtx81uLthof_u5BIjbI,4150
144
+ maleo_foundation-0.3.72.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
145
+ maleo_foundation-0.3.72.dist-info/top_level.txt,sha256=_iBos3F_bhEOdjOnzeiEYSrCucasc810xXtLBXI8cQc,17
146
+ maleo_foundation-0.3.72.dist-info/RECORD,,