maleo-foundation 0.1.37__py3-none-any.whl → 0.1.39__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.
@@ -5,9 +5,9 @@ from fastapi.exceptions import RequestValidationError
5
5
  from starlette.exceptions import HTTPException
6
6
  from starlette.types import Lifespan, AppType
7
7
  from pydantic_settings import BaseSettings
8
- from pydantic import BaseModel, Field
8
+ from pydantic import BaseModel, Field, model_validator
9
9
  from sqlalchemy import MetaData
10
- from typing import Optional, Type
10
+ from typing import Dict, Optional, Type
11
11
  from maleo_foundation.enums import BaseEnums
12
12
  from maleo_foundation.models.transfers.general.token import BaseTokenGeneralTransfers
13
13
  from maleo_foundation.models.transfers.parameters.token import BaseTokenParametersTransfers
@@ -20,7 +20,8 @@ from maleo_foundation.middlewares.base import RequestProcessor
20
20
  from maleo_foundation.services.token import BaseTokenService
21
21
  from maleo_foundation.types import BaseTypes
22
22
  from maleo_foundation.utils.exceptions import BaseExceptions
23
- from maleo_foundation.utils.keyloader import BaseKeyLoaders
23
+ from maleo_foundation.utils.loaders.json import JSONLoader
24
+ from maleo_foundation.utils.loaders.key import KeyLoader
24
25
  from maleo_foundation.utils.logging import GoogleCloudLogging, ServiceLogger, MiddlewareLogger
25
26
 
26
27
  class LogConfig(BaseModel):
@@ -38,6 +39,7 @@ class Settings(BaseSettings):
38
39
  PUBLIC_KEY_PATH:str = Field("/keys/maleo-public-key.pem", description="Maleo's public key path")
39
40
  KEY_PASSWORD:str = Field(..., description="Maleo key's password")
40
41
  CONFIGURATIONS_PATH:str = Field(..., description="Service's configuration file path")
42
+ DB_PASSWORD:str = Field(..., description="Database's password")
41
43
 
42
44
  class Keys(BaseModel):
43
45
  password:str = Field(..., description="Key's password")
@@ -78,11 +80,24 @@ class ServiceConfigurations(BaseModel):
78
80
 
79
81
  class DatabaseConfigurations(BaseModel):
80
82
  username:str = Field("postgres", description="Database user's username")
83
+ password_env:str = Field("DB_PASSWORD", description="Database user's password .env")
81
84
  password:str = Field(..., description="Database user's password")
82
85
  host:str = Field(..., description="Database's host")
83
86
  port:int = Field(5432, description="Database's port")
84
87
  database:str = Field(..., description="Database")
85
88
 
89
+ @model_validator(mode='before')
90
+ @classmethod
91
+ def populate_password(cls, values:Dict):
92
+ env_name = values.get("password_env")
93
+ if not env_name:
94
+ raise ValueError("password_env is required to fetch password from environment.")
95
+ env_value = os.getenv(env_name)
96
+ if env_value is None:
97
+ raise ValueError(f"'{env_name}' must be set.")
98
+ values["password"] = env_value
99
+ return values
100
+
86
101
  @property
87
102
  def url(self) -> str:
88
103
  return f"postgresql://{self.username}:{self.password}@{self.host}:{self.port}/{self.database}"
@@ -254,9 +269,8 @@ class ServiceManager:
254
269
  return self._settings
255
270
 
256
271
  def _load_configs(self) -> None:
257
- with open(self._settings.CONFIGURATIONS_PATH) as f:
258
- data = json.load(f)
259
- self._configs = Configurations.model_validate(data)
272
+ data = JSONLoader.load(self._settings.CONFIGURATIONS_PATH)
273
+ self._configs = Configurations.model_validate(data)
260
274
 
261
275
  @property
262
276
  def configs(self) -> Configurations:
@@ -278,13 +292,11 @@ class ServiceManager:
278
292
 
279
293
  def _load_credentials(self) -> None:
280
294
  #* Load google credentials
281
- with open(self._settings.GOOGLE_CREDENTIALS_PATH) as f:
282
- data = json.load(f)
283
- google = GoogleCredentials.model_validate(data)
295
+ data = JSONLoader.load(self._settings.GOOGLE_CREDENTIALS_PATH)
296
+ google = GoogleCredentials.model_validate(data)
284
297
  #* Load internal credentials
285
- with open(self._settings.INTERNAL_CREDENTIALS_PATH) as f:
286
- data = json.load(f)
287
- internal = InternalCredentials.model_validate(data)
298
+ data = JSONLoader.load(self._settings.INTERNAL_CREDENTIALS_PATH)
299
+ internal = InternalCredentials.model_validate(data)
288
300
  self._credentials = Credentials(google=google, internal=internal)
289
301
 
290
302
  @property
@@ -294,14 +306,14 @@ class ServiceManager:
294
306
  def _parse_keys(self) -> None:
295
307
  #* Parse private key
296
308
  key_type = BaseEnums.KeyType.PRIVATE
297
- private = BaseKeyLoaders.load_rsa(
309
+ private = KeyLoader.load_rsa(
298
310
  type=key_type,
299
311
  path=self._settings.PRIVATE_KEY_PATH,
300
312
  password=self._settings.KEY_PASSWORD
301
313
  )
302
314
  #* Parse public key
303
315
  key_type = BaseEnums.KeyType.PUBLIC
304
- public = BaseKeyLoaders.load_rsa(
316
+ public = KeyLoader.load_rsa(
305
317
  type=key_type,
306
318
  path=self._settings.PUBLIC_KEY_PATH
307
319
  )
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
  from .formatter import BaseFormatter
3
3
  from .exceptions import BaseExceptions
4
4
  from .extractor import BaseExtractors
5
- from .keyloader import BaseKeyLoaders
5
+ from .loaders import BaseLoaders
6
6
  from .controller import BaseControllerUtils
7
7
  from .query import BaseQueryUtils
8
8
 
@@ -10,6 +10,6 @@ class BaseUtils:
10
10
  Formatter = BaseFormatter
11
11
  Exceptions = BaseExceptions
12
12
  Extractors = BaseExtractors
13
- KeyLoader = BaseKeyLoaders
13
+ Loaders = BaseLoaders
14
14
  Controller = BaseControllerUtils
15
15
  Query = BaseQueryUtils
@@ -0,0 +1,9 @@
1
+ from __future__ import annotations
2
+ from .json import JSONLoader
3
+ from .key import KeyLoader
4
+ from .yaml import YAMLLoader
5
+
6
+ class BaseLoaders:
7
+ Json = JSONLoader
8
+ Key = KeyLoader
9
+ Yaml = YAMLLoader
@@ -0,0 +1,14 @@
1
+ import json
2
+ from typing import Dict, List, Union, Any
3
+ from pathlib import Path
4
+
5
+ class JSONLoader:
6
+ @staticmethod
7
+ def load(path:Union[Path, str]) -> Union[Dict[str, Any], List[Any]]:
8
+ file_path = Path(path)
9
+
10
+ if not file_path.is_file():
11
+ raise FileNotFoundError(f"File not found: {file_path}")
12
+
13
+ with open(file_path, 'r') as f:
14
+ return json.load(f)
@@ -1,13 +1,13 @@
1
- import pathlib
2
1
  from cryptography.hazmat.primitives import serialization
2
+ from pathlib import Path
3
3
  from typing import Optional, Union
4
4
  from maleo_foundation.enums import BaseEnums
5
5
 
6
- class BaseKeyLoaders:
6
+ class KeyLoader:
7
7
  @staticmethod
8
8
  def load_rsa(
9
9
  type:BaseEnums.KeyType,
10
- path: Union[str, pathlib.Path],
10
+ path: Union[str, Path],
11
11
  password:Optional[Union[str, bytes]] = None,
12
12
  format:BaseEnums.KeyFormatType = BaseEnums.KeyFormatType.STRING,
13
13
  ) -> Union[bytes, str]:
@@ -15,7 +15,7 @@ class BaseKeyLoaders:
15
15
  Load an RSA private or public key strictly from a file.
16
16
 
17
17
  Args:
18
- path (str | pathlib.Path): Path to the PEM file.
18
+ path (str | Path): Path to the PEM file.
19
19
  password (str | bytes | None): Password for encrypted private keys (optional).
20
20
 
21
21
  Returns:
@@ -24,7 +24,7 @@ class BaseKeyLoaders:
24
24
  if not isinstance(type, BaseEnums.KeyType):
25
25
  raise TypeError("Invalid key type")
26
26
 
27
- file_path = pathlib.Path(path)
27
+ file_path = Path(path)
28
28
 
29
29
  if not file_path.is_file():
30
30
  raise FileNotFoundError(f"Key file not found: {file_path}")
@@ -0,0 +1,14 @@
1
+ import yaml
2
+ from pathlib import Path
3
+ from typing import Dict, Union
4
+
5
+ class YAMLLoader:
6
+ @staticmethod
7
+ def load(path:Union[Path, str]) -> Dict:
8
+ file_path = Path(path)
9
+
10
+ if not file_path.is_file():
11
+ raise FileNotFoundError(f"File not found: {file_path}")
12
+
13
+ with file_path.open("r") as f:
14
+ return yaml.safe_load(f)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maleo_foundation
3
- Version: 0.1.37
3
+ Version: 0.1.39
4
4
  Summary: Foundation package for Maleo
5
5
  Author-email: Agra Bima Yuda <agra@nexmedis.com>
6
6
  License: MIT
@@ -13,7 +13,7 @@ maleo_foundation/expanded_types/token.py,sha256=4fRTJw6W5MYq71NksNrWNi7qYHQ4_lQw
13
13
  maleo_foundation/managers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  maleo_foundation/managers/db.py,sha256=ZN0b43OgqQtk2WHKMJQ0E2TeaSEyVJ0-l4FEkrSG0Qo,4645
15
15
  maleo_foundation/managers/middleware.py,sha256=7CDXPMb28AR7J72TWOeKFxOlMypKezEtO9mr53a88B0,4032
16
- maleo_foundation/managers/service.py,sha256=-xsghwPtqV95YcktytV7Zba_E38JkmwUPlHXcLppfkQ,20413
16
+ maleo_foundation/managers/service.py,sha256=XTbsV11JEGqfiHJwra5MSJ1l7rqP3IUTvMtLwnJZ5yM,21005
17
17
  maleo_foundation/managers/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
18
  maleo_foundation/managers/client/base.py,sha256=lYREmEoTLShlPPXOKKiAopjefJ8nIWHCi7IvWkXXKeY,1465
19
19
  maleo_foundation/managers/client/maleo.py,sha256=NibYGdiN3EXUw5nx-tL48QAZym14GcA4BDZihGJNQ-g,4254
@@ -54,16 +54,19 @@ maleo_foundation/models/transfers/results/service/controllers/__init__.py,sha256
54
54
  maleo_foundation/models/transfers/results/service/controllers/rest.py,sha256=wCuFyOTQkuBs2cqjPsWnPy0XIsCfMqGByhrSy57qp7Y,1107
55
55
  maleo_foundation/services/__init__.py,sha256=Ho5zJSA89xdGFKIwOdzjmd8sm23cIuwrqYAxCEBBTIU,120
56
56
  maleo_foundation/services/token.py,sha256=ZqRqOdGUnaSIam6-JHVdAW1UST-2EDtcVN0fpbPmXY4,1638
57
- maleo_foundation/utils/__init__.py,sha256=eEnPPeA6la0mu7535EFEKUB02C1IO_R8JgYcohvf1qU,471
57
+ maleo_foundation/utils/__init__.py,sha256=KoERe8U2ERGZeAKUNBPW_itk7g9YpH7v7_mD9_i050o,461
58
58
  maleo_foundation/utils/controller.py,sha256=ECzPzpw36zBAjKcWcDbUAhIJGbc6UpeypdUUX6ipXBg,6396
59
59
  maleo_foundation/utils/exceptions.py,sha256=LPPcU-6_3NbRIBZg2Nr2Ac5HF1qZJbHbMVnwfIfZg6g,3702
60
60
  maleo_foundation/utils/extractor.py,sha256=SZXVYDHWGaA-Dd1BUydwF2HHdZqexEielS4CjL0Ceng,814
61
- maleo_foundation/utils/keyloader.py,sha256=TOKgKLqvUV27MYkej9d_MQB9O8bOJ_WzaXlqHorkmpo,2581
62
61
  maleo_foundation/utils/logging.py,sha256=MwvZmZSA8SIdfq-knEvpYIgqnSpHcyHrZY9TVHWVHJA,9023
63
62
  maleo_foundation/utils/query.py,sha256=ODQ3adOYQNj5E2cRW9ytbjBz56nEDcnfq8mQ6YZbCCM,4375
64
63
  maleo_foundation/utils/formatter/__init__.py,sha256=iKf5YCbEdg1qKnFHyKqqcQbqAqEeRUf8mhI3v3dQoj8,78
65
64
  maleo_foundation/utils/formatter/case.py,sha256=TmvvlfzGdC_omMTB5vAa40TZBxQ3hnr-SYeo0M52Rlg,1352
66
- maleo_foundation-0.1.37.dist-info/METADATA,sha256=G4M-2SvG4uuTt1hiIP7g0UnQmI4-SQUWbxb_OGm5tjc,3190
67
- maleo_foundation-0.1.37.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
68
- maleo_foundation-0.1.37.dist-info/top_level.txt,sha256=_iBos3F_bhEOdjOnzeiEYSrCucasc810xXtLBXI8cQc,17
69
- maleo_foundation-0.1.37.dist-info/RECORD,,
65
+ maleo_foundation/utils/loaders/__init__.py,sha256=Dnuv7BWyglSddnbsFb96s-b3KaW7UK1uLsMZfZ8zVi8,203
66
+ maleo_foundation/utils/loaders/json.py,sha256=NsXLq3VZSgzmEf99tV1VtrmiudWdQ8Pzh_hI4Rm0cM8,397
67
+ maleo_foundation/utils/loaders/key.py,sha256=GZ4h1ONfp6Xx8-E8AWoGP4ajAZrwPhZRtidjn_u82Qg,2562
68
+ maleo_foundation/utils/loaders/yaml.py,sha256=jr8v3BlgmRCMTzdNgKhIYt1tnubaJXcDSSGkKVR8pbw,362
69
+ maleo_foundation-0.1.39.dist-info/METADATA,sha256=DDXV3R3FbXZHl3RgmRVm380Xf4CFog-qdb8Kddf9ndM,3190
70
+ maleo_foundation-0.1.39.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
71
+ maleo_foundation-0.1.39.dist-info/top_level.txt,sha256=_iBos3F_bhEOdjOnzeiEYSrCucasc810xXtLBXI8cQc,17
72
+ maleo_foundation-0.1.39.dist-info/RECORD,,