maleo-foundation 0.3.71__tar.gz → 0.3.72__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.
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/PKG-INFO +1 -1
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/client/manager.py +9 -3
- maleo_foundation-0.3.72/maleo_foundation/controller_types.py +25 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/client/base.py +37 -5
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/client/google/base.py +7 -3
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/client/google/secret.py +12 -3
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/client/google/storage.py +11 -2
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/client/google/subscription.py +40 -26
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/client/maleo.py +3 -5
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/credential.py +6 -2
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/service.py +25 -13
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/schemas/general.py +6 -6
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/configurations/client/maleo.py +1 -1
- maleo_foundation-0.3.72/maleo_foundation/models/transfers/general/configurations/pubsub/subscription.py +16 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/configurations/service.py +2 -1
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/operation.py +2 -2
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/settings.py +1 -1
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/exceptions/client.py +26 -1
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/exceptions/service.py +27 -2
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/logging.py +50 -21
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation.egg-info/PKG-INFO +1 -1
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation.egg-info/SOURCES.txt +2 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/pyproject.toml +1 -1
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/README.md +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/authentication.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/authorization.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/client/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/client/services/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/client/services/encryption/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/client/services/encryption/aes.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/client/services/encryption/rsa.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/client/services/hash/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/client/services/hash/bcrypt.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/client/services/hash/hmac.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/client/services/hash/sha256.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/client/services/key.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/client/services/signature.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/client/services/token.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/constants.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/enums.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/expanded_types/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/expanded_types/client.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/expanded_types/encryption/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/expanded_types/encryption/aes.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/expanded_types/encryption/rsa.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/expanded_types/general.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/expanded_types/hash.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/expanded_types/key.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/expanded_types/service.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/expanded_types/signature.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/expanded_types/token.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/extended_types.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/cache.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/client/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/client/google/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/client/google/parameter.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/configuration.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/db.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/middleware.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/middlewares/authentication.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/middlewares/base.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/middlewares/cors.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/responses.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/schemas/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/schemas/encryption.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/schemas/hash.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/schemas/key.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/schemas/parameter.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/schemas/result.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/schemas/signature.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/schemas/token.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/table.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/configurations/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/configurations/cache/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/configurations/cache/redis.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/configurations/client/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/configurations/database.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/configurations/middleware.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/configurations/pubsub/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/configurations/pubsub/publisher.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/credentials.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/data.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/database.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/key.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/request.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/signature.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/general/token.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/parameters/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/parameters/client.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/parameters/encryption/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/parameters/encryption/aes.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/parameters/encryption/rsa.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/parameters/general.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/parameters/hash/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/parameters/hash/bcrypt.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/parameters/hash/hmac.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/parameters/hash/sha256.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/parameters/key.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/parameters/service.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/parameters/signature.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/parameters/token.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/results/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/results/client/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/results/client/controllers/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/results/client/controllers/http.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/results/client/service.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/results/encryption/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/results/encryption/aes.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/results/encryption/rsa.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/results/hash.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/results/key.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/results/service/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/results/service/controllers/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/results/service/controllers/rest.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/results/service/general.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/results/signature.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/transfers/results/token.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/rest_controller_result.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/types.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/cache.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/client.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/controller.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/dependencies/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/dependencies/auth.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/dependencies/context.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/exceptions/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/exceptions/request.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/extractor.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/formatter/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/formatter/case.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/loaders/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/loaders/credential/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/loaders/credential/google.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/loaders/json.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/loaders/key/__init__.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/loaders/key/rsa.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/loaders/yaml.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/merger.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/query.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/repository.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/utils/searcher.py +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation.egg-info/dependency_links.txt +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation.egg-info/requires.txt +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation.egg-info/top_level.txt +0 -0
- {maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/setup.cfg +0 -0
@@ -1,6 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
|
+
from typing import Optional
|
3
|
+
from maleo_foundation.enums import BaseEnums
|
2
4
|
from maleo_foundation.managers.client.base import ClientManager
|
3
|
-
from maleo_foundation.types import BaseTypes
|
4
5
|
from maleo_foundation.utils.logging import SimpleConfig
|
5
6
|
from maleo_foundation.client.services.encryption import (
|
6
7
|
MaleoFoundationAESEncryptionClientService,
|
@@ -23,11 +24,16 @@ from maleo_foundation.client.services import (
|
|
23
24
|
|
24
25
|
class MaleoFoundationClientManager(ClientManager):
|
25
26
|
def __init__(
|
26
|
-
self,
|
27
|
+
self,
|
28
|
+
log_config: SimpleConfig,
|
29
|
+
service_environment: Optional[BaseEnums.EnvironmentType] = None,
|
30
|
+
service_key: Optional[BaseEnums.Service] = None,
|
27
31
|
) -> None:
|
28
32
|
key = "maleo-foundation"
|
29
33
|
name = "MaleoFoundation"
|
30
|
-
super().__init__(
|
34
|
+
super().__init__(
|
35
|
+
key, name, log_config, service_environment, service_key, service_environment
|
36
|
+
)
|
31
37
|
self._initialize_services()
|
32
38
|
self._logger.info("Client manager initialized successfully")
|
33
39
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
from google.cloud.pubsub_v1.subscriber.message import Message
|
2
|
+
from typing import Awaitable, Callable, Optional, Union
|
3
|
+
from maleo_foundation.models.transfers.results.service.controllers.rest import (
|
4
|
+
BaseServiceRESTControllerResults,
|
5
|
+
)
|
6
|
+
|
7
|
+
|
8
|
+
class ControllerTypes:
|
9
|
+
# * REST controller types
|
10
|
+
SyncRESTController = Callable[..., BaseServiceRESTControllerResults]
|
11
|
+
OptionalSyncRESTController = Optional[
|
12
|
+
Callable[..., BaseServiceRESTControllerResults]
|
13
|
+
]
|
14
|
+
AsyncRESTController = Callable[..., Awaitable[BaseServiceRESTControllerResults]]
|
15
|
+
OptionalAsyncRESTController = Optional[
|
16
|
+
Callable[..., Awaitable[BaseServiceRESTControllerResults]]
|
17
|
+
]
|
18
|
+
RESTController = Union[SyncRESTController, AsyncRESTController]
|
19
|
+
OptionalRESTController = Optional[RESTController]
|
20
|
+
|
21
|
+
# * Message controller types
|
22
|
+
SyncMessageController = Callable[[str, Message], bool]
|
23
|
+
AsyncMessageController = Callable[[str, Message], Awaitable[bool]]
|
24
|
+
MessageController = Union[SyncMessageController, AsyncMessageController]
|
25
|
+
OptionalMessageController = Optional[MessageController]
|
{maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/client/base.py
RENAMED
@@ -1,8 +1,9 @@
|
|
1
1
|
import httpx
|
2
|
+
import os
|
2
3
|
from contextlib import asynccontextmanager
|
3
4
|
from pydantic import BaseModel, ConfigDict, Field
|
4
|
-
from typing import AsyncGenerator, Generator
|
5
|
-
from maleo_foundation.
|
5
|
+
from typing import AsyncGenerator, Generator, Optional
|
6
|
+
from maleo_foundation.enums import BaseEnums
|
6
7
|
from maleo_foundation.utils.logging import ClientLogger, SimpleConfig
|
7
8
|
|
8
9
|
|
@@ -107,18 +108,43 @@ class ClientManager:
|
|
107
108
|
key: str,
|
108
109
|
name: str,
|
109
110
|
log_config: SimpleConfig,
|
110
|
-
|
111
|
+
service_environment: Optional[BaseEnums.EnvironmentType] = None,
|
112
|
+
service_key: Optional[BaseEnums.Service] = None,
|
113
|
+
environment: Optional[BaseEnums.EnvironmentType] = None,
|
111
114
|
) -> None:
|
112
115
|
self._key = key
|
113
116
|
self._name = name
|
114
117
|
self._log_config = log_config
|
115
|
-
|
118
|
+
|
119
|
+
# Ensure environment exists
|
120
|
+
actual_service_environment = service_environment or os.getenv("ENVIRONMENT")
|
121
|
+
if actual_service_environment is None:
|
122
|
+
raise ValueError(
|
123
|
+
"ENVIRONMENT environment variable must be set if 'service_environment' is set to None"
|
124
|
+
)
|
125
|
+
else:
|
126
|
+
self._service_environment = BaseEnums.EnvironmentType(
|
127
|
+
actual_service_environment
|
128
|
+
)
|
129
|
+
|
130
|
+
# Ensure service_key exists
|
131
|
+
actual_service_key = service_key or os.getenv("SERVICE_KEY")
|
132
|
+
if actual_service_key is None:
|
133
|
+
raise ValueError(
|
134
|
+
"SERVICE_KEY environment variable must be set if 'service_key' is set to None"
|
135
|
+
)
|
136
|
+
else:
|
137
|
+
self._service_key = BaseEnums.Service(actual_service_key)
|
138
|
+
|
139
|
+
self._environment = environment
|
140
|
+
|
116
141
|
self._initialize_logger()
|
117
|
-
self._logger.info("Initializing client manager")
|
142
|
+
self._logger.info(f"Initializing {self._name} client manager")
|
118
143
|
|
119
144
|
def _initialize_logger(self) -> None:
|
120
145
|
self._logger = ClientLogger(
|
121
146
|
client_key=self._key,
|
147
|
+
environment=self._service_environment,
|
122
148
|
service_key=self._service_key,
|
123
149
|
**self._log_config.model_dump(),
|
124
150
|
)
|
@@ -131,6 +157,12 @@ class ClientManager:
|
|
131
157
|
def name(self) -> str:
|
132
158
|
return self._name
|
133
159
|
|
160
|
+
@property
|
161
|
+
def environment(self) -> BaseEnums.EnvironmentType:
|
162
|
+
if self._environment is None:
|
163
|
+
raise ValueError("Environment has not been initialized.")
|
164
|
+
return self._environment
|
165
|
+
|
134
166
|
@property
|
135
167
|
def logger(self) -> ClientLogger:
|
136
168
|
return self._logger
|
{maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/client/google/base.py
RENAMED
@@ -1,7 +1,7 @@
|
|
1
1
|
from google.oauth2.service_account import Credentials
|
2
2
|
from pathlib import Path
|
3
3
|
from typing import Optional, Union
|
4
|
-
from maleo_foundation.
|
4
|
+
from maleo_foundation.enums import BaseEnums
|
5
5
|
from maleo_foundation.managers.client.base import ClientManager
|
6
6
|
from maleo_foundation.utils.loaders.credential.google import GoogleCredentialsLoader
|
7
7
|
from maleo_foundation.utils.logging import SimpleConfig
|
@@ -13,11 +13,15 @@ class GoogleClientManager(ClientManager):
|
|
13
13
|
key: str,
|
14
14
|
name: str,
|
15
15
|
log_config: SimpleConfig,
|
16
|
-
|
16
|
+
service_environment: Optional[BaseEnums.EnvironmentType] = None,
|
17
|
+
service_key: Optional[BaseEnums.Service] = None,
|
18
|
+
environment: Optional[BaseEnums.EnvironmentType] = None,
|
17
19
|
credentials: Optional[Credentials] = None,
|
18
20
|
credentials_path: Optional[Union[Path, str]] = None,
|
19
21
|
) -> None:
|
20
|
-
super().__init__(
|
22
|
+
super().__init__(
|
23
|
+
key, name, log_config, service_environment, service_key, environment
|
24
|
+
)
|
21
25
|
if (credentials is not None and credentials_path is not None) or (
|
22
26
|
credentials is None and credentials_path is None
|
23
27
|
):
|
@@ -4,7 +4,7 @@ from google.cloud import secretmanager
|
|
4
4
|
from google.oauth2.service_account import Credentials
|
5
5
|
from pathlib import Path
|
6
6
|
from typing import Optional, Union
|
7
|
-
from maleo_foundation.
|
7
|
+
from maleo_foundation.enums import BaseEnums
|
8
8
|
from maleo_foundation.utils.logging import SimpleConfig
|
9
9
|
from .base import GoogleClientManager
|
10
10
|
|
@@ -13,14 +13,23 @@ class GoogleSecretManager(GoogleClientManager):
|
|
13
13
|
def __init__(
|
14
14
|
self,
|
15
15
|
log_config: SimpleConfig,
|
16
|
-
|
16
|
+
service_environment: Optional[BaseEnums.EnvironmentType] = None,
|
17
|
+
service_key: Optional[BaseEnums.Service] = None,
|
18
|
+
environment: Optional[BaseEnums.EnvironmentType] = None,
|
17
19
|
credentials: Optional[Credentials] = None,
|
18
20
|
credentials_path: Optional[Union[Path, str]] = None,
|
19
21
|
) -> None:
|
20
22
|
key = "google-secret-manager"
|
21
23
|
name = "GoogleSecretManager"
|
22
24
|
super().__init__(
|
23
|
-
key,
|
25
|
+
key,
|
26
|
+
name,
|
27
|
+
log_config,
|
28
|
+
service_environment,
|
29
|
+
service_key,
|
30
|
+
environment,
|
31
|
+
credentials,
|
32
|
+
credentials_path,
|
24
33
|
)
|
25
34
|
self._client = secretmanager.SecretManagerServiceClient(
|
26
35
|
credentials=self._credentials
|
@@ -15,7 +15,9 @@ class GoogleCloudStorage(GoogleClientManager):
|
|
15
15
|
def __init__(
|
16
16
|
self,
|
17
17
|
log_config: SimpleConfig,
|
18
|
-
|
18
|
+
service_environment: Optional[BaseEnums.EnvironmentType] = None,
|
19
|
+
service_key: Optional[BaseEnums.Service] = None,
|
20
|
+
environment: Optional[BaseEnums.EnvironmentType] = None,
|
19
21
|
credentials: Optional[Credentials] = None,
|
20
22
|
credentials_path: Optional[Union[Path, str]] = None,
|
21
23
|
bucket_name: BaseTypes.OptionalString = None,
|
@@ -24,7 +26,14 @@ class GoogleCloudStorage(GoogleClientManager):
|
|
24
26
|
key = "google-cloud-storage"
|
25
27
|
name = "GoogleCloudStorage"
|
26
28
|
super().__init__(
|
27
|
-
key,
|
29
|
+
key,
|
30
|
+
name,
|
31
|
+
log_config,
|
32
|
+
service_environment,
|
33
|
+
service_key,
|
34
|
+
environment,
|
35
|
+
credentials,
|
36
|
+
credentials_path,
|
28
37
|
)
|
29
38
|
self._client = Client(credentials=self._credentials)
|
30
39
|
self._bucket_name = bucket_name or os.getenv("GCS_BUCKET_NAME")
|
@@ -5,36 +5,37 @@ from google.cloud.pubsub_v1.subscriber.futures import StreamingPullFuture
|
|
5
5
|
from google.cloud.pubsub_v1.subscriber.message import Message
|
6
6
|
from google.oauth2.service_account import Credentials
|
7
7
|
from pathlib import Path
|
8
|
-
from
|
9
|
-
from
|
8
|
+
from typing import Dict, List, Optional, Union, cast
|
9
|
+
from maleo_foundation.controller_types import ControllerTypes
|
10
|
+
from maleo_foundation.enums import BaseEnums
|
10
11
|
from maleo_foundation.managers.client.google.base import GoogleClientManager
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
Controller = Union[SyncController, AsyncController]
|
15
|
-
OptionalController = Optional[Controller]
|
16
|
-
|
17
|
-
|
18
|
-
class SubscriptionConfigurations(BaseModel):
|
19
|
-
subscription_name: str
|
20
|
-
max_messages: int = 10
|
21
|
-
ack_deadline: int = 10
|
22
|
-
controller: OptionalController = None
|
12
|
+
from maleo_foundation.models.transfers.general.configurations.pubsub.subscription import (
|
13
|
+
ExtendedSubscriptionConfigurations,
|
14
|
+
)
|
23
15
|
|
24
16
|
|
25
17
|
class SubscriptionManager(GoogleClientManager):
|
26
18
|
def __init__(
|
27
19
|
self,
|
28
|
-
subscriptions: List[
|
20
|
+
subscriptions: List[ExtendedSubscriptionConfigurations],
|
29
21
|
log_config,
|
30
|
-
|
22
|
+
service_environment: Optional[BaseEnums.EnvironmentType] = None,
|
23
|
+
service_key: Optional[BaseEnums.Service] = None,
|
24
|
+
environment: Optional[BaseEnums.EnvironmentType] = None,
|
31
25
|
credentials: Optional[Credentials] = None,
|
32
26
|
credentials_path: Optional[Union[Path, str]] = None,
|
33
27
|
):
|
34
28
|
key = "google-subscription-manager"
|
35
29
|
name = "GoogleSubscriptionManager"
|
36
30
|
super().__init__(
|
37
|
-
key,
|
31
|
+
key,
|
32
|
+
name,
|
33
|
+
log_config,
|
34
|
+
service_environment,
|
35
|
+
service_key,
|
36
|
+
environment,
|
37
|
+
credentials,
|
38
|
+
credentials_path,
|
38
39
|
)
|
39
40
|
self.subscriber = pubsub_v1.SubscriberClient(credentials=self._credentials)
|
40
41
|
self.subscriptions = subscriptions
|
@@ -42,19 +43,28 @@ class SubscriptionManager(GoogleClientManager):
|
|
42
43
|
self.loop: Optional[asyncio.AbstractEventLoop] = None
|
43
44
|
|
44
45
|
async def _handle_async_controller(
|
45
|
-
self,
|
46
|
+
self,
|
47
|
+
controller: ControllerTypes.AsyncMessageController,
|
48
|
+
subscription_name: str,
|
49
|
+
message: Message,
|
46
50
|
) -> None:
|
47
51
|
success = await controller(subscription_name, message)
|
48
52
|
message.ack() if success else message.nack()
|
49
53
|
|
50
54
|
def _handle_sync_controller(
|
51
|
-
self,
|
55
|
+
self,
|
56
|
+
controller: ControllerTypes.SyncMessageController,
|
57
|
+
subscription_name: str,
|
58
|
+
message: Message,
|
52
59
|
) -> None:
|
53
60
|
success = controller(subscription_name, message)
|
54
61
|
message.ack() if success else message.nack()
|
55
62
|
|
56
63
|
def _message_callback(
|
57
|
-
self,
|
64
|
+
self,
|
65
|
+
controller: ControllerTypes.OptionalMessageController,
|
66
|
+
subscription_name: str,
|
67
|
+
message: Message,
|
58
68
|
):
|
59
69
|
# If controller is not given, conduct default message processing
|
60
70
|
if controller is None:
|
@@ -68,13 +78,17 @@ class SubscriptionManager(GoogleClientManager):
|
|
68
78
|
raise RuntimeError("Event loop not set in SubscriptionManager")
|
69
79
|
asyncio.run_coroutine_threadsafe(
|
70
80
|
self._handle_async_controller(
|
71
|
-
cast(
|
81
|
+
cast(ControllerTypes.AsyncMessageController, controller),
|
82
|
+
subscription_name,
|
83
|
+
message,
|
72
84
|
),
|
73
85
|
self.loop,
|
74
86
|
)
|
75
87
|
else:
|
76
88
|
self._handle_sync_controller(
|
77
|
-
cast(
|
89
|
+
cast(ControllerTypes.SyncMessageController, controller),
|
90
|
+
subscription_name,
|
91
|
+
message,
|
78
92
|
)
|
79
93
|
|
80
94
|
def _default_message_processing(
|
@@ -94,18 +108,18 @@ class SubscriptionManager(GoogleClientManager):
|
|
94
108
|
message.nack()
|
95
109
|
|
96
110
|
async def _start_subscription_listener(
|
97
|
-
self, config:
|
111
|
+
self, config: ExtendedSubscriptionConfigurations
|
98
112
|
) -> None:
|
99
113
|
if self.credentials.project_id is None:
|
100
114
|
raise ValueError("Project ID must be set in credentials")
|
101
115
|
subscription_path = self.subscriber.subscription_path(
|
102
|
-
self.credentials.project_id, config.
|
116
|
+
self.credentials.project_id, config.id
|
103
117
|
)
|
104
118
|
flow_control = pubsub_v1.types.FlowControl(max_messages=config.max_messages)
|
105
119
|
future = self.subscriber.subscribe(
|
106
120
|
subscription_path,
|
107
121
|
callback=lambda message: self._message_callback(
|
108
|
-
config.controller, config.
|
122
|
+
config.controller, config.id, message
|
109
123
|
),
|
110
124
|
flow_control=flow_control,
|
111
125
|
await_callbacks_on_shutdown=True,
|
@@ -117,7 +131,7 @@ class SubscriptionManager(GoogleClientManager):
|
|
117
131
|
if not isinstance(e, asyncio.CancelledError):
|
118
132
|
self._logger.error(
|
119
133
|
"Listener error for subscription '%s': %s",
|
120
|
-
config.
|
134
|
+
config.id,
|
121
135
|
e,
|
122
136
|
exc_info=True,
|
123
137
|
)
|
{maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/managers/client/maleo.py
RENAMED
@@ -74,7 +74,9 @@ class MaleoClientManager(ClientManager):
|
|
74
74
|
key,
|
75
75
|
name,
|
76
76
|
service_manager.log_config,
|
77
|
-
service_manager.
|
77
|
+
service_manager.settings.ENVIRONMENT,
|
78
|
+
service_manager.settings.SERVICE_KEY,
|
79
|
+
environment,
|
78
80
|
)
|
79
81
|
self._environment = environment
|
80
82
|
|
@@ -82,10 +84,6 @@ class MaleoClientManager(ClientManager):
|
|
82
84
|
def service_manager(self) -> ServiceManager:
|
83
85
|
return self._service_manager
|
84
86
|
|
85
|
-
@property
|
86
|
-
def environment(self) -> BaseEnums.EnvironmentType:
|
87
|
-
return self._environment
|
88
|
-
|
89
87
|
def _initialize_controllers(self) -> None:
|
90
88
|
# * Initialize managers
|
91
89
|
http_controller_manager = ClientHTTPControllerManager(url=self._url)
|
@@ -9,9 +9,13 @@ from maleo_foundation.utils.logging import SimpleConfig
|
|
9
9
|
|
10
10
|
|
11
11
|
class CredentialManager:
|
12
|
-
def __init__(
|
13
|
-
self
|
12
|
+
def __init__(
|
13
|
+
self,
|
14
|
+
log_config: SimpleConfig,
|
15
|
+
settings: Settings,
|
16
|
+
):
|
14
17
|
self.log_config = log_config
|
18
|
+
self.settings = settings
|
15
19
|
self._initialize()
|
16
20
|
|
17
21
|
def _load_google_credentials(self) -> None:
|
@@ -51,16 +51,14 @@ class ServiceManager:
|
|
51
51
|
self,
|
52
52
|
db_metadata: MetaData,
|
53
53
|
log_config: SimpleConfig,
|
54
|
-
settings:
|
54
|
+
settings: Settings,
|
55
55
|
additional_topics_configurations: Optional[
|
56
56
|
AdditionalTopicsConfigurations
|
57
57
|
] = None,
|
58
58
|
):
|
59
59
|
self._db_metadata = db_metadata # * Declare DB Metadata
|
60
60
|
self._log_config = log_config # * Declare log config
|
61
|
-
self._settings =
|
62
|
-
settings if settings is not None else Settings() # type: ignore
|
63
|
-
) # * Initialize settings
|
61
|
+
self._settings = settings # * Initialize settings
|
64
62
|
|
65
63
|
# * Disable google cloud logging if environment is local
|
66
64
|
if self._settings.ENVIRONMENT == "local":
|
@@ -134,22 +132,34 @@ class ServiceManager:
|
|
134
132
|
|
135
133
|
def _initialize_loggers(self) -> None:
|
136
134
|
application = ApplicationLogger(
|
137
|
-
|
135
|
+
environment=self.settings.ENVIRONMENT,
|
136
|
+
service_key=self.settings.SERVICE_KEY,
|
137
|
+
**self._log_config.model_dump(),
|
138
138
|
)
|
139
139
|
cache = CacheLogger(
|
140
|
-
|
140
|
+
environment=self.settings.ENVIRONMENT,
|
141
|
+
service_key=self.settings.SERVICE_KEY,
|
142
|
+
**self._log_config.model_dump(),
|
141
143
|
)
|
142
144
|
database = DatabaseLogger(
|
143
|
-
|
145
|
+
environment=self.settings.ENVIRONMENT,
|
146
|
+
service_key=self.settings.SERVICE_KEY,
|
147
|
+
**self._log_config.model_dump(),
|
144
148
|
)
|
145
149
|
middleware = MiddlewareLogger(
|
146
|
-
|
150
|
+
environment=self.settings.ENVIRONMENT,
|
151
|
+
service_key=self.settings.SERVICE_KEY,
|
152
|
+
**self._log_config.model_dump(),
|
147
153
|
)
|
148
154
|
repository = RepositoryLogger(
|
149
|
-
|
155
|
+
environment=self.settings.ENVIRONMENT,
|
156
|
+
service_key=self.settings.SERVICE_KEY,
|
157
|
+
**self._log_config.model_dump(),
|
150
158
|
)
|
151
159
|
service = ServiceLogger(
|
152
|
-
|
160
|
+
environment=self.settings.ENVIRONMENT,
|
161
|
+
service_key=self.settings.SERVICE_KEY,
|
162
|
+
**self._log_config.model_dump(),
|
153
163
|
)
|
154
164
|
self._loggers = Loggers(
|
155
165
|
application=application,
|
@@ -166,8 +176,8 @@ class ServiceManager:
|
|
166
176
|
|
167
177
|
async def _clear_cache(self) -> None:
|
168
178
|
prefixes = [
|
169
|
-
self.
|
170
|
-
f"google-cloud-storage:{self.
|
179
|
+
self.settings.SERVICE_KEY,
|
180
|
+
f"google-cloud-storage:{self.settings.SERVICE_KEY}",
|
171
181
|
]
|
172
182
|
for prefix in prefixes:
|
173
183
|
async for key in self._redis.scan_iter(f"{prefix}*"):
|
@@ -243,7 +253,9 @@ class ServiceManager:
|
|
243
253
|
|
244
254
|
def _initialize_foundation(self) -> None:
|
245
255
|
self._foundation = MaleoFoundationClientManager(
|
246
|
-
log_config=self._log_config,
|
256
|
+
log_config=self._log_config,
|
257
|
+
service_environment=self._settings.ENVIRONMENT,
|
258
|
+
service_key=self._settings.SERVICE_KEY,
|
247
259
|
)
|
248
260
|
|
249
261
|
@property
|
{maleo_foundation-0.3.71 → maleo_foundation-0.3.72}/maleo_foundation/models/schemas/general.py
RENAMED
@@ -8,6 +8,12 @@ from maleo_foundation.types import BaseTypes
|
|
8
8
|
|
9
9
|
|
10
10
|
class BaseGeneralSchemas:
|
11
|
+
class ServiceContext(BaseModel):
|
12
|
+
key: BaseEnums.Service = Field(..., description="Service's key")
|
13
|
+
environment: BaseEnums.EnvironmentType = Field(
|
14
|
+
..., description="Service's environment"
|
15
|
+
)
|
16
|
+
|
11
17
|
class DateFilter(BaseModel):
|
12
18
|
name: str = Field(..., description="Column name.")
|
13
19
|
from_date: BaseTypes.OptionalDatetime = Field(None, description="From date.")
|
@@ -95,12 +101,6 @@ class BaseGeneralSchemas:
|
|
95
101
|
|
96
102
|
return self
|
97
103
|
|
98
|
-
class OperationServiceContext(BaseModel):
|
99
|
-
key: BaseEnums.Service = Field(..., description="Service's key")
|
100
|
-
environment: BaseEnums.EnvironmentType = Field(
|
101
|
-
..., description="Service's environment"
|
102
|
-
)
|
103
|
-
|
104
104
|
class OperationTimestamps(BaseModel):
|
105
105
|
started_at: BaseTypes.OptionalDatetime = Field(
|
106
106
|
None, description="Started at timestamp (Optional)"
|
@@ -7,7 +7,7 @@ class MaleoClientConfigurations(BaseModel):
|
|
7
7
|
environment: BaseEnums.EnvironmentType = Field(
|
8
8
|
..., description="Client's environment"
|
9
9
|
)
|
10
|
-
key:
|
10
|
+
key: BaseEnums.Service = Field(..., description="Client's key")
|
11
11
|
name: str = Field(..., description="Client's name")
|
12
12
|
url: str = Field(..., description="Client's URL")
|
13
13
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
from pydantic import BaseModel, ConfigDict, Field
|
2
|
+
from maleo_foundation.controller_types import ControllerTypes
|
3
|
+
|
4
|
+
|
5
|
+
class SubscriptionConfigurations(BaseModel):
|
6
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
7
|
+
|
8
|
+
id: str = Field(..., description="Subscription's ID")
|
9
|
+
max_messages: int = Field(10, description="Subscription's Max messages")
|
10
|
+
ack_deadline: int = Field(10, description="Subscription's ACK deadline")
|
11
|
+
|
12
|
+
|
13
|
+
class ExtendedSubscriptionConfigurations(SubscriptionConfigurations):
|
14
|
+
controller: ControllerTypes.OptionalMessageController = Field(
|
15
|
+
None, description="Optional message controller"
|
16
|
+
)
|
@@ -1,8 +1,9 @@
|
|
1
1
|
from pydantic import BaseModel, Field
|
2
|
+
from maleo_foundation.enums import BaseEnums
|
2
3
|
|
3
4
|
|
4
5
|
class ServiceConfigurations(BaseModel):
|
5
|
-
key:
|
6
|
+
key: BaseEnums.Service = Field(..., description="Service's key")
|
6
7
|
name: str = Field(..., description="Service's name")
|
7
8
|
host: str = Field(..., description="Service's host")
|
8
9
|
port: int = Field(..., description="Service's port")
|
@@ -10,7 +10,7 @@ class Operation(BaseModel):
|
|
10
10
|
request_context: RequestContext = Field(..., description="Request context")
|
11
11
|
authentication: Authentication = Field(..., description="Authentication")
|
12
12
|
authorization: Optional[Authorization] = Field(None, description="Authorization")
|
13
|
-
service: BaseGeneralSchemas.
|
13
|
+
service: BaseGeneralSchemas.ServiceContext = Field(
|
14
14
|
..., description="Service's context"
|
15
15
|
)
|
16
16
|
timestamps: BaseGeneralSchemas.OperationTimestamps = Field(
|
@@ -34,7 +34,7 @@ class DatabaseOperation(BaseModel):
|
|
34
34
|
request_context: RequestContext = Field(..., description="Request context")
|
35
35
|
authentication: Authentication = Field(..., description="Authentication")
|
36
36
|
authorization: Optional[Authorization] = Field(None, description="Authorization")
|
37
|
-
service: BaseGeneralSchemas.
|
37
|
+
service: BaseGeneralSchemas.ServiceContext = Field(
|
38
38
|
..., description="Service's context"
|
39
39
|
)
|
40
40
|
timestamps: BaseGeneralSchemas.OperationTimestamps = Field(
|
@@ -7,7 +7,7 @@ from maleo_foundation.types import BaseTypes
|
|
7
7
|
|
8
8
|
class Settings(BaseSettings):
|
9
9
|
ENVIRONMENT: BaseEnums.EnvironmentType = Field(..., description="Environment")
|
10
|
-
SERVICE_KEY:
|
10
|
+
SERVICE_KEY: BaseEnums.Service = Field(..., description="Service's key")
|
11
11
|
ROOT_PATH: str = Field("", description="Application's root path")
|
12
12
|
GOOGLE_CREDENTIALS_PATH: str = Field(
|
13
13
|
"/credentials/maleo-google-service-account.json",
|