maleo-foundation 0.1.52__tar.gz → 0.1.54__tar.gz

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.
Files changed (84) hide show
  1. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/PKG-INFO +1 -1
  2. maleo_foundation-0.1.54/maleo_foundation/client/manager.py +27 -0
  3. maleo_foundation-0.1.54/maleo_foundation/client/services/__init__.py +7 -0
  4. maleo_foundation-0.1.54/maleo_foundation/client/services/token.py +34 -0
  5. maleo_foundation-0.1.52/maleo_foundation/managers/client/maleo.py → maleo_foundation-0.1.54/maleo_foundation/managers/client/base.py +34 -22
  6. maleo_foundation-0.1.54/maleo_foundation/managers/client/google/__init__.py +0 -0
  7. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/managers/client/google/base.py +4 -3
  8. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/managers/client/google/secret.py +4 -3
  9. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/managers/client/google/storage.py +4 -3
  10. maleo_foundation-0.1.54/maleo_foundation/managers/client/maleo.py +30 -0
  11. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/managers/db.py +0 -9
  12. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/managers/service.py +93 -56
  13. maleo_foundation-0.1.54/maleo_foundation/models/schemas/signature.py +14 -0
  14. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/utils/logging.py +1 -1
  15. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation.egg-info/PKG-INFO +1 -1
  16. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation.egg-info/SOURCES.txt +5 -0
  17. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/pyproject.toml +1 -1
  18. maleo_foundation-0.1.52/maleo_foundation/managers/client/base.py +0 -42
  19. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/README.md +0 -0
  20. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/__init__.py +0 -0
  21. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/authentication.py +0 -0
  22. {maleo_foundation-0.1.52/maleo_foundation/managers → maleo_foundation-0.1.54/maleo_foundation/client}/__init__.py +0 -0
  23. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/constants.py +0 -0
  24. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/enums.py +0 -0
  25. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/expanded_types/__init__.py +0 -0
  26. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/expanded_types/client.py +0 -0
  27. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/expanded_types/general.py +0 -0
  28. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/expanded_types/query.py +0 -0
  29. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/expanded_types/service.py +0 -0
  30. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/expanded_types/token.py +0 -0
  31. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/extended_types.py +0 -0
  32. {maleo_foundation-0.1.52/maleo_foundation/managers/client → maleo_foundation-0.1.54/maleo_foundation/managers}/__init__.py +0 -0
  33. {maleo_foundation-0.1.52/maleo_foundation/managers/client/google → maleo_foundation-0.1.54/maleo_foundation/managers/client}/__init__.py +0 -0
  34. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/managers/middleware.py +0 -0
  35. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/middlewares/__init__.py +0 -0
  36. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/middlewares/authentication.py +0 -0
  37. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/middlewares/base.py +0 -0
  38. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/middlewares/cors.py +0 -0
  39. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/__init__.py +0 -0
  40. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/responses.py +0 -0
  41. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/schemas/__init__.py +0 -0
  42. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/schemas/general.py +0 -0
  43. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/schemas/parameter.py +0 -0
  44. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/schemas/result.py +0 -0
  45. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/schemas/token.py +0 -0
  46. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/table.py +0 -0
  47. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/__init__.py +0 -0
  48. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/general/__init__.py +0 -0
  49. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/general/token.py +0 -0
  50. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/parameters/__init__.py +0 -0
  51. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/parameters/client.py +0 -0
  52. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/parameters/general.py +0 -0
  53. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/parameters/service.py +0 -0
  54. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/parameters/token.py +0 -0
  55. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/results/__init__.py +0 -0
  56. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/results/client/__init__.py +0 -0
  57. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/results/client/controllers/__init__.py +0 -0
  58. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/results/client/controllers/http.py +0 -0
  59. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/results/client/service.py +0 -0
  60. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/results/service/__init__.py +0 -0
  61. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/results/service/controllers/__init__.py +0 -0
  62. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/results/service/controllers/rest.py +0 -0
  63. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/results/service/general.py +0 -0
  64. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/results/service/query.py +0 -0
  65. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/models/transfers/results/token.py +0 -0
  66. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/services/__init__.py +0 -0
  67. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/services/token.py +0 -0
  68. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/types.py +0 -0
  69. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/utils/__init__.py +0 -0
  70. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/utils/controller.py +0 -0
  71. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/utils/exceptions.py +0 -0
  72. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/utils/extractor.py +0 -0
  73. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/utils/formatter/__init__.py +0 -0
  74. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/utils/formatter/case.py +0 -0
  75. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/utils/loaders/__init__.py +0 -0
  76. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/utils/loaders/json.py +0 -0
  77. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/utils/loaders/key.py +0 -0
  78. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/utils/loaders/yaml.py +0 -0
  79. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/utils/mergers.py +0 -0
  80. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation/utils/query.py +0 -0
  81. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation.egg-info/dependency_links.txt +0 -0
  82. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation.egg-info/requires.txt +0 -0
  83. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/maleo_foundation.egg-info/top_level.txt +0 -0
  84. {maleo_foundation-0.1.52 → maleo_foundation-0.1.54}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maleo_foundation
3
- Version: 0.1.52
3
+ Version: 0.1.54
4
4
  Summary: Foundation package for Maleo
5
5
  Author-email: Agra Bima Yuda <agra@nexmedis.com>
6
6
  License: MIT
@@ -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()
@@ -2,8 +2,8 @@ import httpx
2
2
  from contextlib import asynccontextmanager
3
3
  from pydantic import BaseModel, Field
4
4
  from typing import AsyncGenerator
5
- from maleo_foundation.utils.logging import ClientLogger
6
- from maleo_foundation.managers.client.base import ClientManager
5
+ from maleo_foundation.types import BaseTypes
6
+ from maleo_foundation.utils.logging import ClientLogger, SimpleConfig
7
7
  from maleo_foundation.managers.service import ServiceManager
8
8
 
9
9
  class URL(BaseModel):
@@ -20,6 +20,8 @@ class ClientHTTPControllerManager:
20
20
 
21
21
  async def _client_handler(self) -> AsyncGenerator[httpx.AsyncClient, None]:
22
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()
23
25
  yield self._client
24
26
 
25
27
  async def inject_client(self) -> AsyncGenerator[httpx.AsyncClient, None]:
@@ -92,28 +94,35 @@ class ClientServices(BaseModel):
92
94
  class Config:
93
95
  arbitrary_types_allowed=True
94
96
 
95
- class MaleoClientManager(ClientManager):
97
+ class ClientManager:
96
98
  def __init__(
97
99
  self,
98
100
  key:str,
99
101
  name:str,
100
- url:str,
101
- service_manager:ServiceManager
102
- ):
103
- super().__init__(key, name, service_manager)
104
- self._url = url
105
-
106
- def _initialize_controllers(self) -> None:
107
- #* Initialize managers
108
- http_controller_manager = ClientHTTPControllerManager(url=self._url)
109
- self._controller_managers = ClientControllerManagers(http=http_controller_manager)
110
- #* Initialize controllers
111
- #! This initialied an empty controllers. Extend this function in the actual class to initialize all controllers.
112
- self._controllers = ClientControllers()
102
+ log_config:SimpleConfig,
103
+ service_key:BaseTypes.OptionalString=None
104
+ ) -> None:
105
+ self._key = key
106
+ self._name = name
107
+ self._log_config = log_config
108
+ self._service_key = service_key
109
+ self._initialize_logger()
110
+ self._logger.info("Initializing client manager")
111
+
112
+ def _initialize_logger(self) -> None:
113
+ self._logger = ClientLogger(client_key=self._key, service_key=self._service_key, **self._log_config.model_dump())
113
114
 
114
115
  @property
115
- def controllers(self) -> ClientControllers:
116
- return self._controllers
116
+ def key(self) -> str:
117
+ return self._key
118
+
119
+ @property
120
+ def name(self) -> str:
121
+ return self._name
122
+
123
+ @property
124
+ def logger(self) -> ClientLogger:
125
+ return self._logger
117
126
 
118
127
  def _initialize_services(self) -> None:
119
128
  #* Initialize services
@@ -124,7 +133,10 @@ class MaleoClientManager(ClientManager):
124
133
  def services(self) -> ClientServices:
125
134
  return self._services
126
135
 
127
- async def dispose(self) -> None:
128
- self._logger.info("Disposing client manager")
129
- await self._controller_managers.http.dispose()
130
- self._logger.info("Client manager disposed successfully")
136
+ @property
137
+ def credentials(self):
138
+ raise NotImplementedError()
139
+
140
+ @property
141
+ def client(self):
142
+ 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:
@@ -0,0 +1,30 @@
1
+ from maleo_foundation.managers.client.base import ClientManager, ClientHTTPControllerManager, ClientControllerManagers, ClientControllers, ClientServices
2
+ from maleo_foundation.managers.service import ServiceManager
3
+
4
+ class MaleoClientManager(ClientManager):
5
+ def __init__(
6
+ self,
7
+ key:str,
8
+ name:str,
9
+ url:str,
10
+ service_manager:ServiceManager
11
+ ):
12
+ super().__init__(key, name, service_manager)
13
+ self._url = url
14
+
15
+ def _initialize_controllers(self) -> None:
16
+ #* Initialize managers
17
+ http_controller_manager = ClientHTTPControllerManager(url=self._url)
18
+ self._controller_managers = ClientControllerManagers(http=http_controller_manager)
19
+ #* Initialize controllers
20
+ #! This initialied an empty controllers. Extend this function in the actual class to initialize all controllers.
21
+ self._controllers = ClientControllers()
22
+
23
+ @property
24
+ def controllers(self) -> ClientControllers:
25
+ return self._controllers
26
+
27
+ async def dispose(self) -> None:
28
+ self._logger.info("Disposing client manager")
29
+ await self._controller_managers.http.dispose()
30
+ self._logger.info("Client manager disposed successfully")
@@ -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.52
3
+ Version: 0.1.54
4
4
  Summary: Foundation package for Maleo
5
5
  Author-email: Agra Bima Yuda <agra@nexmedis.com>
6
6
  License: MIT
@@ -11,6 +11,10 @@ maleo_foundation.egg-info/SOURCES.txt
11
11
  maleo_foundation.egg-info/dependency_links.txt
12
12
  maleo_foundation.egg-info/requires.txt
13
13
  maleo_foundation.egg-info/top_level.txt
14
+ maleo_foundation/client/__init__.py
15
+ maleo_foundation/client/manager.py
16
+ maleo_foundation/client/services/__init__.py
17
+ maleo_foundation/client/services/token.py
14
18
  maleo_foundation/expanded_types/__init__.py
15
19
  maleo_foundation/expanded_types/client.py
16
20
  maleo_foundation/expanded_types/general.py
@@ -39,6 +43,7 @@ maleo_foundation/models/schemas/__init__.py
39
43
  maleo_foundation/models/schemas/general.py
40
44
  maleo_foundation/models/schemas/parameter.py
41
45
  maleo_foundation/models/schemas/result.py
46
+ maleo_foundation/models/schemas/signature.py
42
47
  maleo_foundation/models/schemas/token.py
43
48
  maleo_foundation/models/transfers/__init__.py
44
49
  maleo_foundation/models/transfers/general/__init__.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "maleo_foundation"
7
- version = "0.1.52"
7
+ version = "0.1.54"
8
8
  description = "Foundation package for Maleo"
9
9
  authors = [
10
10
  { name = "Agra Bima Yuda", email = "agra@nexmedis.com" }
@@ -1,42 +0,0 @@
1
- from maleo_foundation.utils.logging import ClientLogger
2
- from maleo_foundation.managers.service import ServiceManager
3
-
4
- class ClientManager:
5
- def __init__(
6
- self,
7
- key:str,
8
- name:str,
9
- service_manager:ServiceManager
10
- ) -> None:
11
- self._key = key
12
- self._name = name
13
- self._service_manager = service_manager
14
- self._initialize_logger()
15
- self._logger.info("Initializing client manager")
16
-
17
- 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())
19
-
20
- @property
21
- def key(self) -> str:
22
- return self._key
23
-
24
- @property
25
- def name(self) -> str:
26
- return self._name
27
-
28
- @property
29
- def service_manager(self) -> ServiceManager:
30
- return self._service_manager
31
-
32
- @property
33
- def logger(self) -> ClientLogger:
34
- return self._logger
35
-
36
- @property
37
- def credentials(self):
38
- raise NotImplementedError()
39
-
40
- @property
41
- def client(self):
42
- raise NotImplementedError()