maleo-foundation 0.0.100__tar.gz → 0.1.2__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 (92) hide show
  1. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/PKG-INFO +1 -1
  2. maleo_foundation-0.1.2/maleo_foundation/clients/utils/logger.py +54 -0
  3. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/managers/client/base.py +1 -1
  4. maleo_foundation-0.1.2/maleo_foundation/managers/client/http.py +82 -0
  5. maleo_foundation-0.1.2/maleo_foundation/managers/client/maleo.py +112 -0
  6. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/managers/service.py +37 -4
  7. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/services/token.py +0 -14
  8. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/utils/logging.py +24 -1
  9. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation.egg-info/PKG-INFO +1 -1
  10. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation.egg-info/SOURCES.txt +1 -0
  11. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/pyproject.toml +1 -1
  12. maleo_foundation-0.0.100/maleo_foundation/clients/utils/logger.py +0 -54
  13. maleo_foundation-0.0.100/maleo_foundation/managers/client/http.py +0 -40
  14. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/README.md +0 -0
  15. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/__init__.py +0 -0
  16. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/clients/__init__.py +0 -0
  17. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/clients/general/__init__.py +0 -0
  18. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/clients/general/http.py +0 -0
  19. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/clients/google/__init__.py +0 -0
  20. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/clients/google/base.py +0 -0
  21. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/clients/google/cloud/__init__.py +0 -0
  22. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/clients/google/cloud/base.py +0 -0
  23. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/clients/google/cloud/logging.py +0 -0
  24. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/clients/google/cloud/secret.py +0 -0
  25. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/clients/google/cloud/storage.py +0 -0
  26. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/clients/google/secret.py +0 -0
  27. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/clients/google/storage.py +0 -0
  28. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/clients/utils/__init__.py +0 -0
  29. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/constants.py +0 -0
  30. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/db/__init__.py +0 -0
  31. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/db/engine.py +0 -0
  32. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/db/manager.py +0 -0
  33. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/db/session.py +0 -0
  34. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/db/table.py +0 -0
  35. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/enums.py +0 -0
  36. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/expanded_types/__init__.py +0 -0
  37. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/expanded_types/client.py +0 -0
  38. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/expanded_types/general.py +0 -0
  39. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/expanded_types/query.py +0 -0
  40. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/expanded_types/service.py +0 -0
  41. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/expanded_types/token.py +0 -0
  42. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/extended_types.py +0 -0
  43. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/managers/__init__.py +0 -0
  44. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/managers/client/__init__.py +0 -0
  45. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/managers/client/google/__init__.py +0 -0
  46. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/managers/client/google/base.py +0 -0
  47. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/managers/client/google/secret.py +0 -0
  48. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/managers/client/google/storage.py +0 -0
  49. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/managers/db.py +0 -0
  50. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/middlewares/__init__.py +0 -0
  51. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/middlewares/base.py +0 -0
  52. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/middlewares/cors.py +0 -0
  53. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/__init__.py +0 -0
  54. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/responses.py +0 -0
  55. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/schemas/__init__.py +0 -0
  56. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/schemas/general.py +0 -0
  57. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/schemas/parameter.py +0 -0
  58. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/schemas/result.py +0 -0
  59. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/schemas/token.py +0 -0
  60. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/__init__.py +0 -0
  61. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/general/__init__.py +0 -0
  62. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/general/token.py +0 -0
  63. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/parameters/__init__.py +0 -0
  64. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/parameters/client.py +0 -0
  65. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/parameters/general.py +0 -0
  66. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/parameters/service.py +0 -0
  67. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/parameters/token.py +0 -0
  68. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/results/__init__.py +0 -0
  69. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/results/client/__init__.py +0 -0
  70. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/results/client/controllers/__init__.py +0 -0
  71. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/results/client/controllers/http.py +0 -0
  72. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/results/client/service.py +0 -0
  73. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/results/service/__init__.py +0 -0
  74. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/results/service/controllers/__init__.py +0 -0
  75. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/results/service/controllers/rest.py +0 -0
  76. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/results/service/general.py +0 -0
  77. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/results/service/query.py +0 -0
  78. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/models/transfers/results/token.py +0 -0
  79. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/services/__init__.py +0 -0
  80. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/types.py +0 -0
  81. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/utils/__init__.py +0 -0
  82. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/utils/controller.py +0 -0
  83. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/utils/exceptions.py +0 -0
  84. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/utils/formatter/__init__.py +0 -0
  85. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/utils/formatter/case.py +0 -0
  86. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/utils/keyloader.py +0 -0
  87. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/utils/logger.py +0 -0
  88. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation/utils/query.py +0 -0
  89. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation.egg-info/dependency_links.txt +0 -0
  90. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation.egg-info/requires.txt +0 -0
  91. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/maleo_foundation.egg-info/top_level.txt +0 -0
  92. {maleo_foundation-0.0.100 → maleo_foundation-0.1.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maleo_foundation
3
- Version: 0.0.100
3
+ Version: 0.1.2
4
4
  Summary: Foundation package for Maleo
5
5
  Author-email: Agra Bima Yuda <agra@nexmedis.com>
6
6
  License: MIT
@@ -0,0 +1,54 @@
1
+ # from typing import Dict
2
+ # from maleo_foundation.enums import BaseEnums
3
+ # from maleo_foundation.types import BaseTypes
4
+ # from maleo_foundation.utils.logger import BaseLogger
5
+
6
+ # class ClientLoggerManager:
7
+ # _loggers:Dict[type, BaseLogger] = {}
8
+
9
+ # @classmethod
10
+ # def initialize(
11
+ # cls,
12
+ # base_dir:str,
13
+ # client_name:str,
14
+ # service_name:BaseTypes.OptionalString = None,
15
+ # level:BaseEnums.LoggerLevel = BaseEnums.LoggerLevel.INFO
16
+ # ) -> BaseLogger:
17
+ # """Initialize client logger if not already initialized."""
18
+ # if cls not in cls._loggers:
19
+ # cls._loggers[cls] = BaseLogger(
20
+ # base_dir=base_dir,
21
+ # type=BaseEnums.LoggerType.CLIENT,
22
+ # service_name=service_name,
23
+ # client_name=client_name,
24
+ # level=level
25
+ # )
26
+ # return cls._loggers[cls]
27
+
28
+ # @classmethod
29
+ # def get(cls) -> BaseLogger:
30
+ # """Return client logger (if exist) or raise Runtime Error"""
31
+ # if cls not in cls._loggers:
32
+ # raise RuntimeError("Logger has not been initialized. Call 'initialize' first.")
33
+ # return cls._loggers[cls]
34
+
35
+ # class MaleoFoundationLoggerManager(ClientLoggerManager):
36
+ # @classmethod
37
+ # def initialize(
38
+ # cls,
39
+ # base_dir:str,
40
+ # service_name:BaseTypes.OptionalString = None,
41
+ # level:BaseEnums.LoggerLevel = BaseEnums.LoggerLevel.INFO
42
+ # ) -> BaseLogger:
43
+ # """Initialize MaleoFoundation's client logger if not already initialized."""
44
+ # return super().initialize(
45
+ # base_dir=base_dir,
46
+ # client_name="MaleoFoundation",
47
+ # service_name=service_name,
48
+ # level=level
49
+ # )
50
+
51
+ # @classmethod
52
+ # def get(cls) -> BaseLogger:
53
+ # """Return client logger (if exist) or raise Runtime Error"""
54
+ # return super().get()
@@ -21,7 +21,7 @@ class ClientManager:
21
21
  return self._name
22
22
 
23
23
  @property
24
- def logger(self):
24
+ def logger(self) -> ClientLogger:
25
25
  return self._logger
26
26
 
27
27
  @property
@@ -0,0 +1,82 @@
1
+ import httpx
2
+ from contextlib import asynccontextmanager
3
+ from pydantic import BaseModel, Field
4
+ from typing import AsyncGenerator, Optional
5
+ from maleo_foundation.managers.client.base import ClientManager
6
+
7
+ class HTTPClientManager:
8
+ _client:Optional[httpx.AsyncClient] = None
9
+
10
+ @classmethod
11
+ def initialize(cls) -> None:
12
+ """Initialize the HTTP client if not already initialized."""
13
+ if cls._client is None:
14
+ cls._client = httpx.AsyncClient()
15
+
16
+ @classmethod
17
+ async def _client_handler(cls) -> AsyncGenerator[httpx.AsyncClient, None]:
18
+ """Reusable generator for client handling."""
19
+ if cls._client is None:
20
+ raise RuntimeError("Client has not been initialized. Call initialize first.")
21
+ yield cls._client
22
+
23
+ @classmethod
24
+ async def inject_client(cls) -> AsyncGenerator[httpx.AsyncClient, None]:
25
+ return cls._client_handler()
26
+
27
+ @classmethod
28
+ @asynccontextmanager
29
+ async def get_client(cls) -> AsyncGenerator[httpx.AsyncClient, None]:
30
+ """
31
+ Async context manager for manual HTTP client handling.
32
+ Supports `async with HTTPClientManager.get() as client:`
33
+ """
34
+ async for client in cls._client_handler():
35
+ yield client
36
+
37
+ @classmethod
38
+ def get_base_url(cls) -> str:
39
+ raise NotImplementedError()
40
+
41
+ @classmethod
42
+ async def dispose(cls) -> None:
43
+ """Dispose of the HTTP client and release any resources."""
44
+ if cls._client is not None:
45
+ await cls._client.aclose()
46
+ cls._client = None
47
+
48
+ class URL(BaseModel):
49
+ base:str = Field(..., "Base URL")
50
+
51
+ @property
52
+ def api(self) -> str:
53
+ return f"{self.base}/api"
54
+
55
+ class HTTPClientManagerV2(ClientManager):
56
+ def __init__(self, key, name, logs_dir, google_cloud_logging = None):
57
+ super().__init__(key, name, logs_dir, google_cloud_logging)
58
+ self._client = httpx.AsyncClient()
59
+
60
+ async def _client_handler(self) -> AsyncGenerator[httpx.AsyncClient, None]:
61
+ """Reusable generator for client handling."""
62
+ yield self._client
63
+
64
+ async def inject_client(self) -> AsyncGenerator[httpx.AsyncClient, None]:
65
+ return self._client_handler()
66
+
67
+ @asynccontextmanager
68
+ async def get_client(self) -> AsyncGenerator[httpx.AsyncClient, None]:
69
+ """
70
+ Async context manager for manual HTTP client handling.
71
+ Supports `async with HTTPClientManager.get() as client:`
72
+ """
73
+ async for client in self._client_handler():
74
+ yield client
75
+
76
+ @property
77
+ def client(self) -> httpx.AsyncClient:
78
+ return self._client
79
+
80
+ @property
81
+ def url(self) -> URL:
82
+ raise NotImplementedError()
@@ -0,0 +1,112 @@
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
7
+ from maleo_foundation.managers.client.base import ClientManager
8
+
9
+ class URL(BaseModel):
10
+ base:str = Field(..., "Base URL")
11
+
12
+ @property
13
+ def api(self) -> str:
14
+ return f"{self.base}/api"
15
+
16
+ class HTTPClientControllerManager:
17
+ def __init__(self, base_url:str) -> None:
18
+ self._client = httpx.AsyncClient()
19
+ self._url = URL(base=base_url)
20
+
21
+ async def _client_handler(self) -> AsyncGenerator[httpx.AsyncClient, None]:
22
+ """Reusable generator for client handling."""
23
+ yield self._client
24
+
25
+ async def inject_client(self) -> AsyncGenerator[httpx.AsyncClient, None]:
26
+ return self._client_handler()
27
+
28
+ @asynccontextmanager
29
+ async def get_client(self) -> AsyncGenerator[httpx.AsyncClient, None]:
30
+ """
31
+ Async context manager for manual HTTP client handling.
32
+ Supports `async with HTTPClientManager.get() as client:`
33
+ """
34
+ async for client in self._client_handler():
35
+ yield client
36
+
37
+ @property
38
+ def client(self) -> httpx.AsyncClient:
39
+ return self._client
40
+
41
+ @property
42
+ def url(self) -> URL:
43
+ return self._url
44
+
45
+ class ClientControllerManagers(BaseModel):
46
+ http:HTTPClientControllerManager = Field(..., description="HTTP Client Controller")
47
+
48
+ class Config:
49
+ arbitrary_types_allowed=True
50
+
51
+ class HTTPClientController:
52
+ def __init__(self, manager:HTTPClientControllerManager):
53
+ self._manager = manager
54
+
55
+ @property
56
+ def manager(self) -> HTTPClientControllerManager:
57
+ return self._manager
58
+
59
+ class ClientServiceControllers(BaseModel):
60
+ http:HTTPClientController = Field(..., description="HTTP Client Controller")
61
+
62
+ class Config:
63
+ arbitrary_types_allowed=True
64
+
65
+ class ClientControllers(BaseModel):
66
+ #* Reuse this class while also adding all controllers of the client
67
+ class Config:
68
+ arbitrary_types_allowed=True
69
+
70
+ class ClientService:
71
+ def __init__(self, controllers:ClientServiceControllers, logger:ClientLogger):
72
+ self._controllers = controllers
73
+ self._logger = logger
74
+
75
+ @property
76
+ def controllers(self) -> ClientServiceControllers:
77
+ return self._controllers
78
+
79
+ @property
80
+ def logger(self) -> ClientLogger:
81
+ return self._logger
82
+
83
+ class ClientServices(BaseModel):
84
+ #* Reuse this class while also adding all the services of the client
85
+ class Config:
86
+ arbitrary_types_allowed=True
87
+
88
+ class MaleoClientManager(ClientManager):
89
+ def __init__(self, key, name, logs_dir, google_cloud_logging = None, base_url:BaseTypes.OptionalString = None):
90
+ super().__init__(key, name, logs_dir, google_cloud_logging)
91
+ self._base_url = base_url
92
+
93
+ def _initialize_controllers(self) -> None:
94
+ #* Initialize managers
95
+ http_controller_manager = HTTPClientControllerManager(base_url=self._base_url)
96
+ self._controller_managers = ClientControllerManagers(http=http_controller_manager)
97
+ #* Initialize controllers
98
+ #! This initialied an empty controllers. Extend this function in the actual class to initialize all controllers.
99
+ self._controllers = ClientControllers()
100
+
101
+ @property
102
+ def controllers(self) -> ClientControllers:
103
+ raise self._controllers
104
+
105
+ def _initialize_services(self) -> None:
106
+ #* Initialize services
107
+ #! This initialied an empty services. Extend this function in the actual class to initialize all services.
108
+ self._services = ClientServices()
109
+
110
+ @property
111
+ def services(self) -> ClientServices:
112
+ return self._services
@@ -11,11 +11,12 @@ from maleo_foundation.models.transfers.parameters.token import BaseTokenParamete
11
11
  from maleo_foundation.managers.client.google.secret import GoogleSecretManager
12
12
  from maleo_foundation.managers.client.google.storage import GoogleCloudStorage
13
13
  from maleo_foundation.managers.client.http import HTTPClientManager
14
+ from maleo_foundation.managers.client.maleo import MaleoClientManager
14
15
  from maleo_foundation.managers.db import DatabaseManager
15
16
  from maleo_foundation.services.token import BaseTokenService
16
17
  from maleo_foundation.types import BaseTypes
17
18
  from maleo_foundation.utils.keyloader import load_key
18
- from maleo_foundation.utils.logging import GoogleCloudLogging, ServiceLogger
19
+ from maleo_foundation.utils.logging import GoogleCloudLogging, ServiceLogger, ClientLoggerManager
19
20
 
20
21
  class Settings(BaseSettings):
21
22
  GOOGLE_CREDENTIALS_PATH:str = Field("/creds/maleo-google-service-account.json", description="Internal credential's file path")
@@ -84,10 +85,13 @@ class Configurations(BaseModel):
84
85
  class Config:
85
86
  arbitrary_types_allowed=True
86
87
 
88
+ ClientLoggerManagers = Dict[str, ClientLoggerManager]
89
+
87
90
  class Loggers(BaseModel):
88
91
  application:ServiceLogger = Field(..., description="Application logger")
89
92
  database:ServiceLogger = Field(..., description="Database logger")
90
93
  middleware:ServiceLogger = Field(..., description="Middleware logger")
94
+ client:ClientLoggerManagers = Field(default_factory=dict, description="Client logger manager")
91
95
 
92
96
  class Config:
93
97
  arbitrary_types_allowed=True
@@ -99,9 +103,24 @@ class GoogleClientManagers(BaseModel):
99
103
  class Config:
100
104
  arbitrary_types_allowed=True
101
105
 
106
+ class MaleoClientManagers(BaseModel):
107
+ metadata:Optional[MaleoClientManager] = Field(None, description="MaleoMetadata client manager")
108
+ security:Optional[MaleoClientManager] = Field(None, description="MaleoSecurity client manager")
109
+ storage:Optional[MaleoClientManager] = Field(None, description="MaleoStorage client manager")
110
+ identity:Optional[MaleoClientManager] = Field(None, description="MaleoIdentity client manager")
111
+ access:Optional[MaleoClientManager] = Field(None, description="MaleoAccess client manager")
112
+ soapie:Optional[MaleoClientManager] = Field(None, description="MaleoSOAPIE client manager")
113
+ fhir:Optional[MaleoClientManager] = Field(None, description="MaleoFHIR client manager")
114
+ dicom:Optional[MaleoClientManager] = Field(None, description="MaleoDICOM client manager")
115
+ scribe:Optional[MaleoClientManager] = Field(None, description="MaleoScribe client manager")
116
+ cds:Optional[MaleoClientManager] = Field(None, description="MaleoCDS client manager")
117
+ imaging:Optional[MaleoClientManager] = Field(None, description="MaleoImaging client manager")
118
+ mcu:Optional[MaleoClientManager] = Field(None, description="MaleoMCU client manager")
119
+
102
120
  class ClientManagers(BaseModel):
103
121
  google:GoogleClientManagers = Field(..., description="Google client's managers")
104
122
  http:Type[HTTPClientManager] = Field(..., description="HTTP client's manager")
123
+ maleo:MaleoClientManagers = Field(..., description="Maleo client's managers")
105
124
 
106
125
  class Config:
107
126
  arbitrary_types_allowed=True
@@ -112,7 +131,9 @@ class ServiceManager:
112
131
  db_metadata:MetaData,
113
132
  base_dir:BaseTypes.OptionalString = None,
114
133
  settings:Optional[Settings] = None,
115
- google_cloud_logging:Optional[GoogleCloudLogging] = None
134
+ google_cloud_logging:Optional[GoogleCloudLogging] = None,
135
+ client_logger_managers:ClientLoggerManagers = {},
136
+ maleo_client_managers:Optional[MaleoClientManagers] = None
116
137
  ):
117
138
  self._db_metadata = db_metadata
118
139
 
@@ -138,10 +159,17 @@ class ServiceManager:
138
159
  else:
139
160
  self._google_cloud_logging = google_cloud_logging
140
161
 
162
+ self._client_logger_managers = client_logger_managers
141
163
  self._initialize_loggers()
142
164
  self._load_credentials()
143
165
  self._parse_keys()
144
166
  self._initialize_db()
167
+
168
+ #* Initialize maleo client managers
169
+ if maleo_client_managers is None:
170
+ self._maleo_client_managers = MaleoClientManagers()
171
+ else:
172
+ self._maleo_client_managers = maleo_client_managers
145
173
  self._initialize_clients()
146
174
 
147
175
  @property
@@ -169,7 +197,11 @@ class ServiceManager:
169
197
  application = ServiceLogger(logs_dir=self._logs_dir, type=BaseEnums.LoggerType.APPLICATION, google_cloud_logging=self._google_cloud_logging)
170
198
  database = ServiceLogger(logs_dir=self._logs_dir, type=BaseEnums.LoggerType.DATABASE, google_cloud_logging=self._google_cloud_logging)
171
199
  middleware = ServiceLogger(logs_dir=self._logs_dir, type=BaseEnums.LoggerType.MIDDLEWARE, google_cloud_logging=self._google_cloud_logging)
172
- self._loggers = Loggers(application=application, database=database, middleware=middleware)
200
+ client = self._client_logger_managers
201
+ for key, logger_manager in client.items():
202
+ application.info(f"Initializing logger manager for client '{key}'")
203
+ logger_manager.initialize(logs_dir=self._logs_dir ,client_key=key)
204
+ self._loggers = Loggers(application=application, database=database, middleware=middleware, client=client)
173
205
 
174
206
  @property
175
207
  def loggers(self) -> Loggers:
@@ -225,7 +257,7 @@ class ServiceManager:
225
257
  #* Initialize http clients
226
258
  self._http_client = HTTPClientManager
227
259
  self._http_client.initialize()
228
- self._clients = ClientManagers(google=self._google_clients, http=self._http_client)
260
+ self._clients = ClientManagers(google=self._google_clients, http=self._http_client, maleo=self._maleo_client_managers)
229
261
 
230
262
  @property
231
263
  def google_clients(self) -> GoogleClientManagers:
@@ -258,6 +290,7 @@ class ServiceManager:
258
290
  return result.data.token
259
291
 
260
292
  async def dispose(self) -> None:
293
+ self._loggers.application.info("Disposing service manager")
261
294
  if self._database is not None:
262
295
  self._database.dispose()
263
296
  self._database = None
@@ -1,8 +1,6 @@
1
1
  import jwt
2
2
  from cryptography.hazmat.primitives import serialization
3
3
  from cryptography.hazmat.backends import default_backend
4
- # from maleo_foundation.clients.utils.logger import MaleoFoundationLoggerManager
5
- # from maleo_foundation.utils.exceptions import BaseExceptions
6
4
  from maleo_foundation.models.transfers.general.token import BaseTokenGeneralTransfers
7
5
  from maleo_foundation.models.schemas.token import BaseTokenSchemas
8
6
  from maleo_foundation.models.transfers.parameters.token import BaseTokenParametersTransfers
@@ -11,11 +9,6 @@ from maleo_foundation.expanded_types.token import BaseTokenResultsTypes
11
9
 
12
10
  class BaseTokenService:
13
11
  @staticmethod
14
- # @BaseExceptions.service_exception_handler(
15
- # operation="encoding a payload",
16
- # logger_factory=MaleoFoundationLoggerManager.get,
17
- # fail_result_class=BaseTokenResultsTransfers.Fail
18
- # )
19
12
  def encode(parameters:BaseTokenParametersTransfers.Encode) -> BaseTokenResultsTypes.Encode:
20
13
  #* Serialize private key
21
14
  private_key_bytes = parameters.key.encode()
@@ -27,17 +20,10 @@ class BaseTokenService:
27
20
  payload = BaseTokenGeneralTransfers.EncodePayload.model_validate(parameters.payload.model_dump()).model_dump(mode="json")
28
21
  token = jwt.encode(payload=payload, key=private_key, algorithm="RS256")
29
22
  data = BaseTokenSchemas.Token(token=token)
30
- # MaleoFoundationLoggerManager.get().info("Payload successfully encoded")
31
23
  return BaseTokenResultsTransfers.Encode(data=data)
32
24
 
33
25
  @staticmethod
34
- # @BaseExceptions.service_exception_handler(
35
- # operation="decoding a token",
36
- # logger_factory=MaleoFoundationLoggerManager.get,
37
- # fail_result_class=BaseTokenResultsTransfers.Fail
38
- # )
39
26
  def decode(parameters:BaseTokenParametersTransfers.Decode) -> BaseTokenResultsTypes.Decode:
40
27
  payload = jwt.decode(jwt=parameters.token, key=parameters.key, algorithms=["RS256"])
41
28
  data = BaseTokenGeneralTransfers.DecodePayload.model_validate(payload)
42
- # MaleoFoundationLoggerManager.get().info("Token successfully decoded")
43
29
  return BaseTokenResultsTransfers.Decode(data=data)
@@ -179,4 +179,27 @@ class ClientLogger(BaseLogger):
179
179
  client_key=client_key,
180
180
  level=level,
181
181
  google_cloud_logging=google_cloud_logging
182
- )
182
+ )
183
+
184
+ class ClientLoggerManager:
185
+ _logger:Optional[ClientLogger] = None
186
+
187
+ @classmethod
188
+ def initialize(
189
+ cls,
190
+ logs_dir:str,
191
+ client_key:str,
192
+ service_key:BaseTypes.OptionalString = None,
193
+ level:BaseEnums.LoggerLevel = BaseEnums.LoggerLevel.INFO,
194
+ google_cloud_logging:Optional[GoogleCloudLogging] = None
195
+ ) -> None:
196
+ """Initialize client logger if not already initialized."""
197
+ if cls._logger is None:
198
+ cls.logger = ClientLogger(logs_dir=logs_dir, client_key=client_key, service_key=service_key, level=level, google_cloud_logging=google_cloud_logging)
199
+
200
+ @classmethod
201
+ def get(cls) -> ClientLogger:
202
+ """Return client logger (if exist) or raise Runtime Error"""
203
+ if cls._logger is None:
204
+ raise RuntimeError("Logger has not been initialized. Initialize it first.")
205
+ return cls._logger
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maleo_foundation
3
- Version: 0.0.100
3
+ Version: 0.1.2
4
4
  Summary: Foundation package for Maleo
5
5
  Author-email: Agra Bima Yuda <agra@nexmedis.com>
6
6
  License: MIT
@@ -41,6 +41,7 @@ maleo_foundation/managers/service.py
41
41
  maleo_foundation/managers/client/__init__.py
42
42
  maleo_foundation/managers/client/base.py
43
43
  maleo_foundation/managers/client/http.py
44
+ maleo_foundation/managers/client/maleo.py
44
45
  maleo_foundation/managers/client/google/__init__.py
45
46
  maleo_foundation/managers/client/google/base.py
46
47
  maleo_foundation/managers/client/google/secret.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "maleo_foundation"
7
- version = "0.0.100"
7
+ version = "0.1.2"
8
8
  description = "Foundation package for Maleo"
9
9
  authors = [
10
10
  { name = "Agra Bima Yuda", email = "agra@nexmedis.com" }
@@ -1,54 +0,0 @@
1
- from typing import Dict
2
- from maleo_foundation.enums import BaseEnums
3
- from maleo_foundation.types import BaseTypes
4
- from maleo_foundation.utils.logger import BaseLogger
5
-
6
- class ClientLoggerManager:
7
- _loggers:Dict[type, BaseLogger] = {}
8
-
9
- @classmethod
10
- def initialize(
11
- cls,
12
- base_dir:str,
13
- client_name:str,
14
- service_name:BaseTypes.OptionalString = None,
15
- level:BaseEnums.LoggerLevel = BaseEnums.LoggerLevel.INFO
16
- ) -> BaseLogger:
17
- """Initialize client logger if not already initialized."""
18
- if cls not in cls._loggers:
19
- cls._loggers[cls] = BaseLogger(
20
- base_dir=base_dir,
21
- type=BaseEnums.LoggerType.CLIENT,
22
- service_name=service_name,
23
- client_name=client_name,
24
- level=level
25
- )
26
- return cls._loggers[cls]
27
-
28
- @classmethod
29
- def get(cls) -> BaseLogger:
30
- """Return client logger (if exist) or raise Runtime Error"""
31
- if cls not in cls._loggers:
32
- raise RuntimeError("Logger has not been initialized. Call 'initialize' first.")
33
- return cls._loggers[cls]
34
-
35
- class MaleoFoundationLoggerManager(ClientLoggerManager):
36
- @classmethod
37
- def initialize(
38
- cls,
39
- base_dir:str,
40
- service_name:BaseTypes.OptionalString = None,
41
- level:BaseEnums.LoggerLevel = BaseEnums.LoggerLevel.INFO
42
- ) -> BaseLogger:
43
- """Initialize MaleoFoundation's client logger if not already initialized."""
44
- return super().initialize(
45
- base_dir=base_dir,
46
- client_name="MaleoFoundation",
47
- service_name=service_name,
48
- level=level
49
- )
50
-
51
- @classmethod
52
- def get(cls) -> BaseLogger:
53
- """Return client logger (if exist) or raise Runtime Error"""
54
- return super().get()
@@ -1,40 +0,0 @@
1
- import httpx
2
- from contextlib import asynccontextmanager
3
- from typing import AsyncGenerator, Optional
4
-
5
- class HTTPClientManager:
6
- _client:Optional[httpx.AsyncClient] = None
7
-
8
- @classmethod
9
- def initialize(cls) -> None:
10
- """Initialize the HTTP client if not already initialized."""
11
- if cls._client is None:
12
- cls._client = httpx.AsyncClient()
13
-
14
- @classmethod
15
- async def _client_handler(cls) -> AsyncGenerator[httpx.AsyncClient, None]:
16
- """Reusable generator for client handling."""
17
- if cls._client is None:
18
- raise RuntimeError("Client has not been initialized. Call initialize first.")
19
- yield cls._client
20
-
21
- @classmethod
22
- async def inject_client(cls) -> AsyncGenerator[httpx.AsyncClient, None]:
23
- return cls._client_handler()
24
-
25
- @classmethod
26
- @asynccontextmanager
27
- async def get_client(cls) -> AsyncGenerator[httpx.AsyncClient, None]:
28
- """
29
- Async context manager for manual HTTP client handling.
30
- Supports `async with HTTPClientManager.get() as client:`
31
- """
32
- async for client in cls._client_handler():
33
- yield client
34
-
35
- @classmethod
36
- async def dispose(cls) -> None:
37
- """Dispose of the HTTP client and release any resources."""
38
- if cls._client is not None:
39
- await cls._client.aclose()
40
- cls._client = None