maleo-foundation 0.1.53__py3-none-any.whl → 0.1.55__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.
File without changes
@@ -0,0 +1,27 @@
1
+ from __future__ import annotations
2
+ from maleo_foundation.managers.client.base import ClientManager
3
+ from maleo_foundation.types import BaseTypes
4
+ from maleo_foundation.utils.logging import SimpleConfig
5
+ from maleo_foundation.client.services import (
6
+ MaleoFoundationTokenClientService,
7
+ MaleoFoundationServices
8
+ )
9
+
10
+ class MaleoFoundationClientManager(ClientManager):
11
+ def __init__(self, log_config:SimpleConfig, service_key:BaseTypes.OptionalString=None):
12
+ key = "maleo-foundation"
13
+ name = "MaleoFoundation"
14
+ super().__init__(key, name, log_config, service_key)
15
+ self._initialize_services()
16
+ self._logger.info("Client manager initialized successfully")
17
+
18
+ def _initialize_services(self):
19
+ super()._initialize_services()
20
+ token_service = MaleoFoundationTokenClientService(logger=self._logger)
21
+ self._services = MaleoFoundationServices(
22
+ token=token_service,
23
+ )
24
+
25
+ @property
26
+ def services(self) -> MaleoFoundationServices:
27
+ return self._services
@@ -0,0 +1,7 @@
1
+ from __future__ import annotations
2
+ from pydantic import Field
3
+ from maleo_foundation.managers.client.base import ClientServices
4
+ from maleo_foundation.client.services.token import MaleoFoundationTokenClientService
5
+
6
+ class MaleoFoundationServices(ClientServices):
7
+ token:MaleoFoundationTokenClientService = Field(..., description="Token's service")
@@ -0,0 +1,34 @@
1
+ import jwt
2
+ from maleo_foundation.models.schemas.token import BaseTokenSchemas
3
+ from maleo_foundation.models.transfers.general.token import BaseTokenGeneralTransfers
4
+ from maleo_foundation.models.transfers.parameters.token import BaseTokenParametersTransfers
5
+ from maleo_foundation.models.transfers.results.token import BaseTokenResultsTransfers
6
+ from maleo_foundation.expanded_types.token import BaseTokenResultsTypes
7
+ from maleo_foundation.managers.client.base import ClientService
8
+ from maleo_foundation.utils.exceptions import BaseExceptions
9
+
10
+ class MaleoFoundationTokenClientService(ClientService):
11
+ def encode(self, parameters:BaseTokenParametersTransfers.Encode) -> BaseTokenResultsTypes.Encode:
12
+ @BaseExceptions.service_exception_handler(
13
+ operation="encoding a payload into a token",
14
+ logger=self._logger,
15
+ fail_result_class=BaseTokenResultsTransfers.Fail
16
+ )
17
+ def _impl():
18
+ payload = BaseTokenGeneralTransfers.EncodePayload.model_validate(parameters.payload.model_dump()).model_dump(mode="json")
19
+ token = jwt.encode(payload=payload, key=parameters.key, algorithm="RS256")
20
+ data = BaseTokenSchemas.Token(token=token)
21
+ return BaseTokenResultsTransfers.Encode(data=data)
22
+ return _impl()
23
+
24
+ def decode(self, parameters:BaseTokenParametersTransfers.Decode) -> BaseTokenResultsTypes.Decode:
25
+ @BaseExceptions.service_exception_handler(
26
+ operation="decoding a token into a payload",
27
+ logger=self._logger,
28
+ fail_result_class=BaseTokenResultsTransfers.Fail
29
+ )
30
+ def _impl():
31
+ payload = jwt.decode(jwt=parameters.token, key=parameters.key, algorithms=["RS256"])
32
+ data = BaseTokenGeneralTransfers.DecodePayload.model_validate(payload)
33
+ return BaseTokenResultsTransfers.Decode(data=data)
34
+ return _impl()
@@ -1,21 +1,110 @@
1
- from maleo_foundation.utils.logging import ClientLogger
2
- from maleo_foundation.managers.service import ServiceManager
1
+ import httpx
2
+ from contextlib import asynccontextmanager
3
+ from pydantic import BaseModel, Field
4
+ from typing import AsyncGenerator
5
+ from maleo_foundation.types import BaseTypes
6
+ from maleo_foundation.utils.logging import ClientLogger, SimpleConfig
7
+
8
+ class URL(BaseModel):
9
+ base:str = Field(..., description="Base URL")
10
+
11
+ @property
12
+ def api(self) -> str:
13
+ return f"{self.base}/api"
14
+
15
+ class ClientHTTPControllerManager:
16
+ def __init__(self, url:str) -> None:
17
+ self._client = httpx.AsyncClient()
18
+ self._url = URL(base=url)
19
+
20
+ async def _client_handler(self) -> AsyncGenerator[httpx.AsyncClient, None]:
21
+ """Reusable generator for client handling."""
22
+ if self._client is None or (self._client is not None and self._client.is_closed):
23
+ self._client = httpx.AsyncClient()
24
+ yield self._client
25
+
26
+ async def inject_client(self) -> AsyncGenerator[httpx.AsyncClient, None]:
27
+ return self._client_handler()
28
+
29
+ @asynccontextmanager
30
+ async def get_client(self) -> AsyncGenerator[httpx.AsyncClient, None]:
31
+ """
32
+ Async context manager for manual HTTP client handling.
33
+ Supports `async with HTTPClientManager.get() as client:`
34
+ """
35
+ async for client in self._client_handler():
36
+ yield client
37
+
38
+ @property
39
+ def client(self) -> httpx.AsyncClient:
40
+ return self._client
41
+
42
+ @property
43
+ def url(self) -> URL:
44
+ return self._url
45
+
46
+ async def dispose(self) -> None:
47
+ await self._client.aclose()
48
+
49
+ class ClientControllerManagers(BaseModel):
50
+ http:ClientHTTPControllerManager = Field(..., description="HTTP Client Controller")
51
+
52
+ class Config:
53
+ arbitrary_types_allowed=True
54
+
55
+ class ClientHTTPController:
56
+ def __init__(self, manager:ClientHTTPControllerManager):
57
+ self._manager = manager
58
+
59
+ @property
60
+ def manager(self) -> ClientHTTPControllerManager:
61
+ return self._manager
62
+
63
+ class ClientServiceControllers(BaseModel):
64
+ http:ClientHTTPController = Field(..., description="HTTP Client Controller")
65
+
66
+ class Config:
67
+ arbitrary_types_allowed=True
68
+
69
+ class ClientControllers(BaseModel):
70
+ #* Reuse this class while also adding all controllers of the client
71
+ class Config:
72
+ arbitrary_types_allowed=True
73
+
74
+ class ClientService:
75
+ def __init__(self, logger:ClientLogger):
76
+ self._logger = logger
77
+
78
+ @property
79
+ def controllers(self) -> ClientServiceControllers:
80
+ raise NotImplementedError()
81
+
82
+ @property
83
+ def logger(self) -> ClientLogger:
84
+ return self._logger
85
+
86
+ class ClientServices(BaseModel):
87
+ #* Reuse this class while also adding all the services of the client
88
+ class Config:
89
+ arbitrary_types_allowed=True
3
90
 
4
91
  class ClientManager:
5
92
  def __init__(
6
93
  self,
7
94
  key:str,
8
95
  name:str,
9
- service_manager:ServiceManager
96
+ log_config:SimpleConfig,
97
+ service_key:BaseTypes.OptionalString=None
10
98
  ) -> None:
11
99
  self._key = key
12
100
  self._name = name
13
- self._service_manager = service_manager
101
+ self._log_config = log_config
102
+ self._service_key = service_key
14
103
  self._initialize_logger()
15
104
  self._logger.info("Initializing client manager")
16
105
 
17
106
  def _initialize_logger(self) -> None:
18
- self._logger = ClientLogger(client_key=self._key, service_key=self._service_manager.configs.service.key, **self._service_manager.log_config.model_dump())
107
+ self._logger = ClientLogger(client_key=self._key, service_key=self._service_key, **self._log_config.model_dump())
19
108
 
20
109
  @property
21
110
  def key(self) -> str:
@@ -25,14 +114,19 @@ class ClientManager:
25
114
  def name(self) -> str:
26
115
  return self._name
27
116
 
28
- @property
29
- def service_manager(self) -> ServiceManager:
30
- return self._service_manager
31
-
32
117
  @property
33
118
  def logger(self) -> ClientLogger:
34
119
  return self._logger
35
120
 
121
+ def _initialize_services(self) -> None:
122
+ #* Initialize services
123
+ #! This initialied an empty services. Extend this function in the actual class to initialize all services.
124
+ self._services = ClientServices()
125
+
126
+ @property
127
+ def services(self) -> ClientServices:
128
+ return self._services
129
+
36
130
  @property
37
131
  def credentials(self):
38
132
  raise NotImplementedError()
@@ -3,17 +3,18 @@ from google.auth import default
3
3
  from google.oauth2 import service_account
4
4
  from maleo_foundation.types import BaseTypes
5
5
  from maleo_foundation.managers.client.base import ClientManager
6
- from maleo_foundation.managers.service import ServiceManager
6
+ from maleo_foundation.utils.logging import SimpleConfig
7
7
 
8
8
  class GoogleClientManager(ClientManager):
9
9
  def __init__(
10
10
  self,
11
11
  key:str,
12
12
  name:str,
13
- service_manager:ServiceManager,
13
+ log_config:SimpleConfig,
14
+ service_key:BaseTypes.OptionalString=None,
14
15
  credentials_path:BaseTypes.OptionalString=None
15
16
  ) -> None:
16
- super().__init__(key, name, service_manager)
17
+ super().__init__(key, name, log_config, service_key)
17
18
  credentials_path = credentials_path or os.getenv("GOOGLE_CREDENTIALS_PATH")
18
19
  try:
19
20
  if credentials_path is not None:
@@ -3,18 +3,19 @@ from google.api_core.exceptions import NotFound
3
3
  from google.cloud import secretmanager
4
4
  from typing import Optional
5
5
  from maleo_foundation.types import BaseTypes
6
- from maleo_foundation.managers.service import ServiceManager
6
+ from maleo_foundation.utils.logging import SimpleConfig
7
7
  from .base import GoogleClientManager
8
8
 
9
9
  class GoogleSecretManager(GoogleClientManager):
10
10
  def __init__(
11
11
  self,
12
- service_manager:ServiceManager,
12
+ log_config:SimpleConfig,
13
+ service_key:BaseTypes.OptionalString=None,
13
14
  credentials_path:BaseTypes.OptionalString = None
14
15
  ) -> None:
15
16
  key = "google-secret-manager"
16
17
  name = "GoogleSecretManager"
17
- super().__init__(key, name, service_manager, credentials_path)
18
+ super().__init__(key, name, log_config, service_key, credentials_path)
18
19
  self._client = secretmanager.SecretManagerServiceClient(credentials=self._credentials)
19
20
  self._logger.info("Client manager initialized successfully")
20
21
 
@@ -2,19 +2,20 @@ import os
2
2
  from datetime import timedelta
3
3
  from google.cloud.storage import Bucket, Client
4
4
  from maleo_foundation.types import BaseTypes
5
- from maleo_foundation.managers.service import ServiceManager
5
+ from maleo_foundation.utils.logging import SimpleConfig
6
6
  from .base import GoogleClientManager
7
7
 
8
8
  class GoogleCloudStorage(GoogleClientManager):
9
9
  def __init__(
10
10
  self,
11
- service_manager:ServiceManager,
11
+ log_config:SimpleConfig,
12
+ service_key:BaseTypes.OptionalString=None,
12
13
  credentials_path:BaseTypes.OptionalString = None,
13
14
  bucket_name:BaseTypes.OptionalString = None
14
15
  ) -> None:
15
16
  key = "google-cloud-storage"
16
17
  name = "GoogleCloudStorage"
17
- super().__init__(key, name, service_manager, credentials_path)
18
+ super().__init__(key, name, log_config, service_key, credentials_path)
18
19
  self._client = Client(credentials=self._credentials)
19
20
  self._bucket_name = bucket_name or os.getenv("GCS_BUCKET_NAME")
20
21
  if self._bucket_name is None:
@@ -1,96 +1,19 @@
1
- import httpx
2
- from contextlib import asynccontextmanager
3
1
  from pydantic import BaseModel, Field
4
- from typing import AsyncGenerator
5
- from maleo_foundation.utils.logging import ClientLogger
6
- from maleo_foundation.managers.client.base import ClientManager
2
+ from maleo_foundation.managers.client.base import ClientManager, ClientHTTPControllerManager, ClientControllerManagers, ClientHTTPController, ClientServiceControllers, ClientControllers
7
3
  from maleo_foundation.managers.service import ServiceManager
8
4
 
9
- class URL(BaseModel):
10
- base:str = Field(..., description="Base URL")
11
-
12
- @property
13
- def api(self) -> str:
14
- return f"{self.base}/api"
15
-
16
- class ClientHTTPControllerManager:
17
- def __init__(self, url:str) -> None:
18
- self._client = httpx.AsyncClient()
19
- self._url = URL(base=url)
20
-
21
- async def _client_handler(self) -> AsyncGenerator[httpx.AsyncClient, None]:
22
- """Reusable generator for client handling."""
23
- if self._client is None or (self._client is not None and self._client.is_closed):
24
- self._client = httpx.AsyncClient()
25
- yield self._client
26
-
27
- async def inject_client(self) -> AsyncGenerator[httpx.AsyncClient, None]:
28
- return self._client_handler()
29
-
30
- @asynccontextmanager
31
- async def get_client(self) -> AsyncGenerator[httpx.AsyncClient, None]:
32
- """
33
- Async context manager for manual HTTP client handling.
34
- Supports `async with HTTPClientManager.get() as client:`
35
- """
36
- async for client in self._client_handler():
37
- yield client
38
-
39
- @property
40
- def client(self) -> httpx.AsyncClient:
41
- return self._client
42
-
43
- @property
44
- def url(self) -> URL:
45
- return self._url
46
-
47
- async def dispose(self) -> None:
48
- await self._client.aclose()
49
-
50
- class ClientControllerManagers(BaseModel):
51
- http:ClientHTTPControllerManager = Field(..., description="HTTP Client Controller")
52
-
53
- class Config:
54
- arbitrary_types_allowed=True
55
-
56
- class ClientHTTPController:
5
+ class MaleoClientHTTPController(ClientHTTPController):
57
6
  def __init__(self, service_manager:ServiceManager, manager:ClientHTTPControllerManager):
58
7
  self._service_manager = service_manager
59
- self._manager = manager
8
+ super().__init__(manager)
60
9
 
61
10
  @property
62
11
  def service_manager(self) -> ServiceManager:
63
12
  return self._service_manager
64
13
 
65
- @property
66
- def manager(self) -> ClientHTTPControllerManager:
67
- return self._manager
68
-
69
- class ClientServiceControllers(BaseModel):
70
- http:ClientHTTPController = Field(..., description="HTTP Client Controller")
71
-
72
- class Config:
73
- arbitrary_types_allowed=True
74
-
75
- class ClientControllers(BaseModel):
76
- #* Reuse this class while also adding all controllers of the client
77
- class Config:
78
- arbitrary_types_allowed=True
14
+ class MaleoClientServiceControllers(ClientServiceControllers):
15
+ http:MaleoClientHTTPController = Field(..., description="Maleo's HTTP Client Controller")
79
16
 
80
- class ClientService:
81
- def __init__(self, logger:ClientLogger):
82
- self._logger = logger
83
-
84
- @property
85
- def controllers(self) -> ClientServiceControllers:
86
- raise NotImplementedError()
87
-
88
- @property
89
- def logger(self) -> ClientLogger:
90
- return self._logger
91
-
92
- class ClientServices(BaseModel):
93
- #* Reuse this class while also adding all the services of the client
94
17
  class Config:
95
18
  arbitrary_types_allowed=True
96
19
 
@@ -102,8 +25,8 @@ class MaleoClientManager(ClientManager):
102
25
  url:str,
103
26
  service_manager:ServiceManager
104
27
  ):
105
- super().__init__(key, name, service_manager)
106
28
  self._url = url
29
+ super().__init__(key, name, service_manager.log_config, service_manager.configs.service.key)
107
30
 
108
31
  def _initialize_controllers(self) -> None:
109
32
  #* Initialize managers
@@ -117,15 +40,6 @@ class MaleoClientManager(ClientManager):
117
40
  def controllers(self) -> ClientControllers:
118
41
  return self._controllers
119
42
 
120
- def _initialize_services(self) -> None:
121
- #* Initialize services
122
- #! This initialied an empty services. Extend this function in the actual class to initialize all services.
123
- self._services = ClientServices()
124
-
125
- @property
126
- def services(self) -> ClientServices:
127
- return self._services
128
-
129
43
  async def dispose(self) -> None:
130
44
  self._logger.info("Disposing client manager")
131
45
  await self._controller_managers.http.dispose()
@@ -65,15 +65,6 @@ class DatabaseConfigurations(BaseModel):
65
65
  port:int = Field(5432, description="Database's port")
66
66
  database:str = Field(..., description="Database")
67
67
 
68
- @model_validator(mode='before')
69
- @classmethod
70
- def populate_password(cls, values:Dict):
71
- env_value = os.getenv("DB_PASSWORD")
72
- if env_value is None:
73
- raise ValueError("'DB_PASSWORD' environmet variable must be set.")
74
- values["password"] = env_value
75
- return values
76
-
77
68
  @property
78
69
  def url(self) -> str:
79
70
  return f"postgresql://{self.username}:{self.password}@{self.host}:{self.port}/{self.database}"
@@ -6,16 +6,17 @@ from pydantic_settings import BaseSettings
6
6
  from pydantic import BaseModel, Field
7
7
  from sqlalchemy import MetaData
8
8
  from typing import Optional
9
+ from maleo_foundation.client.manager import MaleoFoundationClientManager
9
10
  from maleo_foundation.enums import BaseEnums
10
11
  from maleo_foundation.models.transfers.general.token import BaseTokenGeneralTransfers
11
12
  from maleo_foundation.models.transfers.parameters.token import BaseTokenParametersTransfers
12
13
  from maleo_foundation.managers.db import DatabaseConfigurations, DatabaseManager
14
+ from maleo_foundation.managers.client.google.secret import GoogleSecretManager
15
+ from maleo_foundation.managers.client.google.storage import GoogleCloudStorage
13
16
  from maleo_foundation.managers.middleware import MiddlewareConfigurations, BaseMiddlewareConfigurations, CORSMiddlewareConfigurations, GeneralMiddlewareConfigurations, MiddlewareLoggers, MiddlewareManager
14
17
  from maleo_foundation.middlewares.base import RequestProcessor
15
- from maleo_foundation.services.token import BaseTokenService
16
18
  from maleo_foundation.utils.exceptions import BaseExceptions
17
19
  from maleo_foundation.utils.loaders.json import JSONLoader
18
- from maleo_foundation.utils.loaders.key import KeyLoader
19
20
  from maleo_foundation.utils.loaders.yaml import YAMLLoader
20
21
  from maleo_foundation.utils.logging import SimpleConfig, ServiceLogger, MiddlewareLogger
21
22
  from maleo_foundation.utils.mergers import BaseMergers
@@ -24,12 +25,8 @@ class Settings(BaseSettings):
24
25
  ENVIRONMENT:BaseEnums.EnvironmentType = Field(..., description="Environment")
25
26
  GOOGLE_CREDENTIALS_PATH:str = Field("credentials/maleo-google-service-account.json", description="Internal credential's file path")
26
27
  INTERNAL_CREDENTIALS_PATH:str = Field("credentials/maleo-internal-service-account.json", description="Internal credential's file path")
27
- PRIVATE_KEY_PATH:str = Field("keys/maleo-private-key.pem", description="Maleo's private key path")
28
- PUBLIC_KEY_PATH:str = Field("keys/maleo-public-key.pem", description="Maleo's public key path")
29
- KEY_PASSWORD:str = Field(..., description="Maleo key's password")
30
28
  STATIC_CONFIGURATIONS_PATH:str = Field("configs/static.yaml", description="Maleo's static configurations path")
31
29
  RUNTIME_CONFIGURATIONS_PATH:str = Field("configs/runtime.yaml", description="Service's runtime configurations path")
32
- DB_PASSWORD:str = Field(..., description="Database's password")
33
30
 
34
31
  class Keys(BaseModel):
35
32
  password:str = Field(..., description="Key's password")
@@ -77,7 +74,7 @@ class ServiceConfigurations(BaseModel):
77
74
  class RuntimeConfigurations(BaseModel):
78
75
  service:ServiceConfigurations = Field(..., description="Service's configurations")
79
76
  middleware:MiddlewareRuntimeConfigurations = Field(..., description="Middleware's runtime configurations")
80
- database:DatabaseConfigurations = Field(..., description="Database's configurations")
77
+ database:str = Field(..., description="Database's name")
81
78
 
82
79
  class Config:
83
80
  arbitrary_types_allowed=True
@@ -148,6 +145,26 @@ class Loggers(BaseModel):
148
145
  class Config:
149
146
  arbitrary_types_allowed=True
150
147
 
148
+ class GoogleClientManagers(BaseModel):
149
+ secret:GoogleSecretManager = Field(..., description="Google secret manager's client manager")
150
+ storage:GoogleCloudStorage = Field(..., description="Google cloud storage's client manager")
151
+
152
+ class Config:
153
+ arbitrary_types_allowed=True
154
+
155
+ class MaleoClientManagers(BaseModel):
156
+ foundation:MaleoFoundationClientManager = Field(..., description="MaleoFoundation's client manager")
157
+
158
+ class Config:
159
+ arbitrary_types_allowed=True
160
+
161
+ class ClientManagers(BaseModel):
162
+ google:GoogleClientManagers = Field(..., description="Google's client managers")
163
+ maleo:MaleoClientManagers = Field(..., description="Maleo's client managers")
164
+
165
+ class Config:
166
+ arbitrary_types_allowed=True
167
+
151
168
  class ServiceManager:
152
169
  def __init__(
153
170
  self,
@@ -156,19 +173,21 @@ class ServiceManager:
156
173
  settings:Optional[Settings] = None
157
174
  ):
158
175
  self._db_metadata = db_metadata #* Declare DB Metadata
159
-
160
- #* Initialize settings
161
- if settings is None:
162
- self._settings = Settings()
163
- else:
164
- self._settings = settings
165
-
166
- self._load_configs()
167
176
  self._log_config = log_config #* Declare log config
168
- self._initialize_loggers()
177
+ self._settings = settings if settings is not None else Settings() #* Initialize settings
178
+ #* Disable google cloud logging if environment is local
179
+ if self._settings.ENVIRONMENT == "local":
180
+ self._log_config.google_cloud_logging = None
169
181
  self._load_credentials()
170
- self._parse_keys()
182
+ self._load_configs()
183
+ self._initialize_secret_manager()
184
+ #* Declare environment for configurations and client
185
+ environment = BaseEnums.EnvironmentType.STAGING if self._settings.ENVIRONMENT == BaseEnums.EnvironmentType.LOCAL else self._settings.ENVIRONMENT
186
+ self._initialize_configs(environment=environment)
187
+ self._initialize_keys()
188
+ self._initialize_loggers()
171
189
  self._initialize_db()
190
+ self._initialize_clients(environment=environment)
172
191
 
173
192
  @property
174
193
  def log_config(self) -> SimpleConfig:
@@ -178,18 +197,53 @@ class ServiceManager:
178
197
  def settings(self) -> Settings:
179
198
  return self._settings
180
199
 
200
+ def _load_credentials(self) -> None:
201
+ #* Load google credentials
202
+ data = JSONLoader.load(self._settings.GOOGLE_CREDENTIALS_PATH)
203
+ google = GoogleCredentials.model_validate(data)
204
+ #* Load internal credentials
205
+ data = JSONLoader.load(self._settings.INTERNAL_CREDENTIALS_PATH)
206
+ internal = InternalCredentials.model_validate(data)
207
+ self._credentials = Credentials(google=google, internal=internal)
208
+
209
+ @property
210
+ def credentials(self) -> Credentials:
211
+ return self._credentials
212
+
181
213
  def _load_configs(self) -> None:
182
214
  static_configurations = YAMLLoader.load(self._settings.STATIC_CONFIGURATIONS_PATH)
183
215
  self._static_configs = StaticConfigurations.model_validate(static_configurations)
184
216
  runtime_configurations = YAMLLoader.load(self._settings.RUNTIME_CONFIGURATIONS_PATH)
185
217
  self._runtime_configs = RuntimeConfigurations.model_validate(runtime_configurations)
186
- merged_configs = BaseMergers.deep_merge(self._static_configs.model_dump(), self._runtime_configs.model_dump())
218
+
219
+ def _initialize_secret_manager(self) -> None:
220
+ self._secret_manager = GoogleSecretManager(log_config=self._log_config, service_key=self._runtime_configs.service.key, credentials_path=self._settings.INTERNAL_CREDENTIALS_PATH)
221
+
222
+ @property
223
+ def secret_manager(self) -> None:
224
+ return self._secret_manager
225
+
226
+ def _initialize_configs(self, environment:BaseEnums.EnvironmentType) -> None:
227
+ password = self._secret_manager.get(name=f"maleo-db-password-{environment}")
228
+ host = self._secret_manager.get(name=f"maleo-db-host-{environment}")
229
+ database = DatabaseConfigurations(password=password, host=host)
230
+ merged_configs = BaseMergers.deep_merge(self._static_configs.model_dump(), self._runtime_configs.model_dump(exclude={"database"}), {"database": database.model_dump()})
187
231
  self._configs = Configurations.model_validate(merged_configs)
188
232
 
189
233
  @property
190
234
  def configs(self) -> Configurations:
191
235
  return self._configs
192
236
 
237
+ def _initialize_keys(self) -> None:
238
+ password = self._secret_manager.get(name="maleo-key-password")
239
+ private = self._secret_manager.get(name="maleo-private-key")
240
+ public = self._secret_manager.get(name="maleo-public-key")
241
+ self._keys = Keys(password=password, private=private, public=public)
242
+
243
+ @property
244
+ def keys(self) -> Keys:
245
+ return self._keys
246
+
193
247
  def _initialize_loggers(self) -> None:
194
248
  #* Service's loggers
195
249
  application = ServiceLogger(type=BaseEnums.LoggerType.APPLICATION, service_key=self._configs.service.key, **self._log_config.model_dump())
@@ -204,45 +258,32 @@ class ServiceManager:
204
258
  def loggers(self) -> Loggers:
205
259
  return self._loggers
206
260
 
207
- def _load_credentials(self) -> None:
208
- #* Load google credentials
209
- data = JSONLoader.load(self._settings.GOOGLE_CREDENTIALS_PATH)
210
- google = GoogleCredentials.model_validate(data)
211
- #* Load internal credentials
212
- data = JSONLoader.load(self._settings.INTERNAL_CREDENTIALS_PATH)
213
- internal = InternalCredentials.model_validate(data)
214
- self._credentials = Credentials(google=google, internal=internal)
261
+ def _initialize_db(self) -> None:
262
+ self._database = DatabaseManager(metadata=self._db_metadata, logger=self._loggers.database, url=self._configs.database.url)
215
263
 
216
264
  @property
217
- def credentials(self) -> Credentials:
218
- return self._credentials
265
+ def database(self) -> DatabaseManager:
266
+ return self._database
219
267
 
220
- def _parse_keys(self) -> None:
221
- #* Parse private key
222
- key_type = BaseEnums.KeyType.PRIVATE
223
- private = KeyLoader.load_rsa(
224
- type=key_type,
225
- path=self._settings.PRIVATE_KEY_PATH,
226
- password=self._settings.KEY_PASSWORD
227
- )
228
- #* Parse public key
229
- key_type = BaseEnums.KeyType.PUBLIC
230
- public = KeyLoader.load_rsa(
231
- type=key_type,
232
- path=self._settings.PUBLIC_KEY_PATH
233
- )
234
- self._keys = Keys(password=self._settings.KEY_PASSWORD, private=private, public=public)
268
+ def _initialize_clients(self, environment:BaseEnums.EnvironmentType) -> None:
269
+ secret = self._secret_manager
270
+ storage = GoogleCloudStorage(log_config=self._log_config, service_key=self._runtime_configs.service.key, bucket_name=f"maleo-suite-{environment}", credentials_path=self._settings.INTERNAL_CREDENTIALS_PATH)
271
+ self._google_clients = GoogleClientManagers(secret=secret, storage=storage)
272
+ foundation = MaleoFoundationClientManager(log_config=self._log_config, service_key=self._runtime_configs.service.key)
273
+ self._maleo_clients = MaleoClientManagers(foundation=foundation)
274
+ self._clients = ClientManagers(google=self._google_clients, maleo=self._maleo_clients)
235
275
 
236
276
  @property
237
- def keys(self) -> Keys:
238
- return self._keys
277
+ def google_clients(self) -> GoogleClientManagers:
278
+ self._google_clients
239
279
 
240
- def _initialize_db(self) -> None:
241
- self._database = DatabaseManager(metadata=self._db_metadata, logger=self._loggers.database, url=self._configs.database.url)
280
+ @property
281
+ def maleo_clients(self) -> MaleoClientManagers:
282
+ self._maleo_clients
242
283
 
243
284
  @property
244
- def database(self) -> DatabaseManager:
245
- return self._database
285
+ def clients(self) -> ClientManagers:
286
+ self._clients
246
287
 
247
288
  @property
248
289
  def token(self) -> str:
@@ -252,14 +293,10 @@ class ServiceManager:
252
293
  u_e=self._credentials.internal.email,
253
294
  u_ut=self._credentials.internal.user_type
254
295
  )
255
- parameters = BaseTokenParametersTransfers.Encode(
256
- key=self.keys.private,
257
- password=self.keys.password,
258
- payload=payload
259
- )
260
- result = BaseTokenService.encode(parameters=parameters)
296
+ parameters = BaseTokenParametersTransfers.Encode(key=self._keys.private, password=self._keys.password, payload=payload)
297
+ result = self._clients.maleo.foundation.services.token.encode(parameters=parameters)
261
298
  if not result.success:
262
- raise ValueError("Failed generating token")
299
+ return ""
263
300
  return result.data.token
264
301
 
265
302
  def create_app(self, router:APIRouter, lifespan:Optional[Lifespan[AppType]] = None, request_processor:Optional[RequestProcessor] = None) -> FastAPI:
@@ -0,0 +1,14 @@
1
+ from pydantic import BaseModel, Field
2
+
3
+ class BaseSignatureSchemas:
4
+ class Key(BaseModel):
5
+ key:str = Field(..., description="Key")
6
+
7
+ class Message(BaseModel):
8
+ message:str = Field(..., description="Message")
9
+
10
+ class Signature(BaseModel):
11
+ signature:str = Field(..., description="Signature")
12
+
13
+ class IsValid(BaseModel):
14
+ is_valid:bool = Field(..., description="Is valid signature")
@@ -43,7 +43,7 @@ class GoogleCloudLogging:
43
43
  class SimpleConfig(BaseModel):
44
44
  dir:str = Field(..., description="Log's directory")
45
45
  level:BaseEnums.LoggerLevel = Field(BaseEnums.LoggerLevel.INFO, description="Log's level")
46
- google_cloud_logging:GoogleCloudLogging = Field(default_factory=GoogleCloudLogging, description="Google cloud logging")
46
+ google_cloud_logging:Optional[GoogleCloudLogging] = Field(default_factory=GoogleCloudLogging, description="Google cloud logging")
47
47
 
48
48
  class Config:
49
49
  arbitrary_types_allowed=True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maleo_foundation
3
- Version: 0.1.53
3
+ Version: 0.1.55
4
4
  Summary: Foundation package for Maleo
5
5
  Author-email: Agra Bima Yuda <agra@nexmedis.com>
6
6
  License: MIT
@@ -4,6 +4,10 @@ maleo_foundation/constants.py,sha256=aBmEfWlBqZxi0k-n6h2NM1YRLOjMnheEiLyQcjP-zCQ
4
4
  maleo_foundation/enums.py,sha256=uvwl3dl2r6BoJMEbtSETiLoyJubHup9Lc7VOg7w7zQo,2943
5
5
  maleo_foundation/extended_types.py,sha256=pIKt-_9tby4rmune3fmWcCW_mohaNRh_1lywBmdc-L4,301
6
6
  maleo_foundation/types.py,sha256=aKXnIgEhYGSfFqNMGLc4qIKGkINBRpkOo9R9cb2CbwI,2414
7
+ maleo_foundation/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ maleo_foundation/client/manager.py,sha256=hF5Uiv93yHmno8ec4ukCDrpTh2apUabMeYZNVgSbxZM,1035
9
+ maleo_foundation/client/services/__init__.py,sha256=ur502vxzT2FxhkZ7F0c7RjOGYAYEqmwRzz3pQsrAM8M,347
10
+ maleo_foundation/client/services/token.py,sha256=KJcA6aTW12JovrbBf0KoKMDgOopz-mZ_SmCRHhWLS_k,1894
7
11
  maleo_foundation/expanded_types/__init__.py,sha256=lm_r7rxlLA0sgSTGQBMR9ZbZbVDpD7Te-UYb3oRVi1g,364
8
12
  maleo_foundation/expanded_types/client.py,sha256=To0kRXp3QTmuSu5rWKaCiTsMK9qkYiyYKYbHfw-y1fY,2396
9
13
  maleo_foundation/expanded_types/general.py,sha256=bjIBREYTS73tvS-Key7P7db82a2HHlSJ1XBAvKuYmT0,826
@@ -11,16 +15,16 @@ maleo_foundation/expanded_types/query.py,sha256=0yUG-JIVsanzB7KAkrRz_OsrhP6J0bRq
11
15
  maleo_foundation/expanded_types/service.py,sha256=q8jpKdbCbLWwH1UPQavKpVE14rC5rveduk2cFWzuhGw,2416
12
16
  maleo_foundation/expanded_types/token.py,sha256=4fRTJw6W5MYq71NksNrWNi7qYHQ4_lQwfu9WxwrMipc,355
13
17
  maleo_foundation/managers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- maleo_foundation/managers/db.py,sha256=lIOGE2qVofnJNqRJKaxFQ6Md3Lg5RB-oGqfZN-85diA,5522
18
+ maleo_foundation/managers/db.py,sha256=Pn5EZ-c1Hy6-BihN7KokHJWmBIt3Ty96fZ0zF-srtF4,5208
15
19
  maleo_foundation/managers/middleware.py,sha256=7CDXPMb28AR7J72TWOeKFxOlMypKezEtO9mr53a88B0,4032
16
- maleo_foundation/managers/service.py,sha256=0T3dHcpGdkvT0YuTvPssRR8_wDkHTPW-VI8yUl9iY80,14928
20
+ maleo_foundation/managers/service.py,sha256=P4-vEcLznfsH0JbHmpNcihQdw2_lmhTsoc4G7wJ8JCM,17296
17
21
  maleo_foundation/managers/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- maleo_foundation/managers/client/base.py,sha256=Z7_ANKbrlnShoZeSpP6N9Y0JLquDWG2FAedMvceYtt0,1120
19
- maleo_foundation/managers/client/maleo.py,sha256=xxzUERrpFQKWrOMxPi8t3zH0z3MliBii2cvXaRQunGI,4290
22
+ maleo_foundation/managers/client/base.py,sha256=qfWu_wxoPSSzgZwuTEwRiXERg60diAkz65Qk3fnQej4,3972
23
+ maleo_foundation/managers/client/maleo.py,sha256=G6C0rn_5c1MEmnoZkJbyXptfoDEofgC5BwLzfQC4NEk,1886
20
24
  maleo_foundation/managers/client/google/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
- maleo_foundation/managers/client/google/base.py,sha256=0_4MYc-clsnSS2hjwwe-DNaycmcwsoUeF9mm21GLpbI,1202
22
- maleo_foundation/managers/client/google/secret.py,sha256=BNRE-VnD3GTgRtUQg2zzaitYHZ_yThTl7wRKPngqW-U,3067
23
- maleo_foundation/managers/client/google/storage.py,sha256=d2ysrFOHAfKXWbM9u9XCxstMJgS8twSiZUshpGBfwg8,2308
25
+ maleo_foundation/managers/client/google/base.py,sha256=j3W18Pmcu9jJ5wK12bbWBI6r8cVt5f7QmGU9uIJgKrU,1249
26
+ maleo_foundation/managers/client/google/secret.py,sha256=Uh01RoOp8QOIvu8X4AGJzOJRlrfAeXHO8ZFvmKo7A-E,3114
27
+ maleo_foundation/managers/client/google/storage.py,sha256=MPuVpLTl0QJhlBOqpxv5UtD3ANO1WCCE1sRrfHnlCZM,2355
24
28
  maleo_foundation/middlewares/__init__.py,sha256=bqE2EIFC3rWcR2AwFPR0fk2kSFfeTRzgA24GbnuT5RA,3697
25
29
  maleo_foundation/middlewares/authentication.py,sha256=mpJ4WJ25zw4SGvgpeJE9eSV3-AtK5IJtN2U8Dh9rmMk,3132
26
30
  maleo_foundation/middlewares/base.py,sha256=iGc_4JZYxE0k47Dty4aFOvpgXjQY_W_4tgqYndhq3V8,10991
@@ -32,6 +36,7 @@ maleo_foundation/models/schemas/__init__.py,sha256=Xj8Ahsqyra-fmEaVcGPok5GOOsPQl
32
36
  maleo_foundation/models/schemas/general.py,sha256=hEQQPcddxMsJXMb36nqItIAfp3pqUyJOlaD7nXkNM2I,3609
33
37
  maleo_foundation/models/schemas/parameter.py,sha256=K47z2NzmTEhUiOfRiRLyRPXoQurbWsKBL7ObXAxIWRY,2100
34
38
  maleo_foundation/models/schemas/result.py,sha256=V3dljS2AdtWW4Pf8YsnQuiCylN1bZtEY1AtYC7okWuI,1747
39
+ maleo_foundation/models/schemas/signature.py,sha256=32ECoksXCVRloTFNcb9ne3IAi5F6e6MuDniCj76ppmQ,420
35
40
  maleo_foundation/models/schemas/token.py,sha256=u71kPXJyCxqn_INK05MSNFhQr9MaLfQM-icYc536xik,551
36
41
  maleo_foundation/models/transfers/__init__.py,sha256=oJLJ3Geeme6vBw7R2Dhvdvg4ziVvzEYAGJaP-tm_90w,299
37
42
  maleo_foundation/models/transfers/general/__init__.py,sha256=0yW67vJvKgJmZ9htteOVatG7mb-YEpHF62dpwH2g_Bk,146
@@ -58,7 +63,7 @@ maleo_foundation/utils/__init__.py,sha256=SRPEVoqjZoO6W8rtF_Ti8VIangg6Auwm6eHbZM
58
63
  maleo_foundation/utils/controller.py,sha256=ECzPzpw36zBAjKcWcDbUAhIJGbc6UpeypdUUX6ipXBg,6396
59
64
  maleo_foundation/utils/exceptions.py,sha256=LPPcU-6_3NbRIBZg2Nr2Ac5HF1qZJbHbMVnwfIfZg6g,3702
60
65
  maleo_foundation/utils/extractor.py,sha256=SZXVYDHWGaA-Dd1BUydwF2HHdZqexEielS4CjL0Ceng,814
61
- maleo_foundation/utils/logging.py,sha256=cO9QLui0W9CVtQZOj_lfyuggdFaaffHkrOS12fl0i5I,8042
66
+ maleo_foundation/utils/logging.py,sha256=bBi73GTwRK8Ll4m5vSNHGymXUrbRsSNQYZ1vF7Iq1z8,8052
62
67
  maleo_foundation/utils/mergers.py,sha256=DniUu3Ot4qkYH_YSw4uD1cn9cfirum4S_Opp8fMkQwA,702
63
68
  maleo_foundation/utils/query.py,sha256=ODQ3adOYQNj5E2cRW9ytbjBz56nEDcnfq8mQ6YZbCCM,4375
64
69
  maleo_foundation/utils/formatter/__init__.py,sha256=iKf5YCbEdg1qKnFHyKqqcQbqAqEeRUf8mhI3v3dQoj8,78
@@ -67,7 +72,7 @@ maleo_foundation/utils/loaders/__init__.py,sha256=Dnuv7BWyglSddnbsFb96s-b3KaW7UK
67
72
  maleo_foundation/utils/loaders/json.py,sha256=NsXLq3VZSgzmEf99tV1VtrmiudWdQ8Pzh_hI4Rm0cM8,397
68
73
  maleo_foundation/utils/loaders/key.py,sha256=GZ4h1ONfp6Xx8-E8AWoGP4ajAZrwPhZRtidjn_u82Qg,2562
69
74
  maleo_foundation/utils/loaders/yaml.py,sha256=jr8v3BlgmRCMTzdNgKhIYt1tnubaJXcDSSGkKVR8pbw,362
70
- maleo_foundation-0.1.53.dist-info/METADATA,sha256=kbspfEHcLNmIwhVZ9VJvqTU3IJcCR3VC4TWlY2aF2NQ,3354
71
- maleo_foundation-0.1.53.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
72
- maleo_foundation-0.1.53.dist-info/top_level.txt,sha256=_iBos3F_bhEOdjOnzeiEYSrCucasc810xXtLBXI8cQc,17
73
- maleo_foundation-0.1.53.dist-info/RECORD,,
75
+ maleo_foundation-0.1.55.dist-info/METADATA,sha256=PtkqUBr25XaRh8S_Lw63cZmOtbo9xiUupcwD71DNjeQ,3354
76
+ maleo_foundation-0.1.55.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
77
+ maleo_foundation-0.1.55.dist-info/top_level.txt,sha256=_iBos3F_bhEOdjOnzeiEYSrCucasc810xXtLBXI8cQc,17
78
+ maleo_foundation-0.1.55.dist-info/RECORD,,