fdc-shared-kernel 0.0.24__tar.gz → 0.0.26__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.
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/PKG-INFO +2 -1
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/fdc_shared_kernel.egg-info/PKG-INFO +2 -1
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/fdc_shared_kernel.egg-info/SOURCES.txt +1 -0
- fdc_shared_kernel-0.0.24/requirements.txt → fdc_shared_kernel-0.0.26/fdc_shared_kernel.egg-info/requires.txt +2 -1
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/pyproject.toml +1 -1
- fdc_shared_kernel-0.0.24/fdc_shared_kernel.egg-info/requires.txt → fdc_shared_kernel-0.0.26/requirements.txt +1 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/http/__init__.py +1 -1
- fdc_shared_kernel-0.0.26/shared_kernel/interfaces/databus.py +112 -0
- fdc_shared_kernel-0.0.26/shared_kernel/messaging/__init__.py +14 -0
- fdc_shared_kernel-0.0.26/shared_kernel/messaging/http_databus.py +125 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/messaging/nats_databus.py +56 -41
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/security/key_vault/__init__.py +7 -6
- fdc_shared_kernel-0.0.24/shared_kernel/interfaces/databus.py +0 -99
- fdc_shared_kernel-0.0.24/shared_kernel/messaging/__init__.py +0 -1
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/README.md +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/README_pypi.md +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/fdc_shared_kernel.egg-info/dependency_links.txt +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/fdc_shared_kernel.egg-info/top_level.txt +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/setup.cfg +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/__init__.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/auth/__init__.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/auth/jwt_helper.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/auth/token_handler.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/config/__init__.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/database/__init__.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/exceptions/__init__.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/exceptions/configuration_exceptions.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/exceptions/custom_exceptions.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/exceptions/data_validation_exceptions.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/exceptions/http_exceptions.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/exceptions/infrastructure_exceptions.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/exceptions/operational_exceptions.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/exceptions/security_exceptions.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/http/httpx_http_client.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/http/request_http_client.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/interfaces/__init__.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/interfaces/http.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/interfaces/keyvault.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/logger/__init__.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/metrics/__init__.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/metrics/status_tracker.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/models/__init__.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/security/__init__.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/security/key_vault/aws_secret_manager.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/security/key_vault/azure_keyvault.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/__init__.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/config/__init__.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/config/test_config.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/logger/__init__.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/logger/test_logger.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/messaging/__init__.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/messaging/test_nats_interface.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/utils/__init__.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/utils/test_data_validators.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/utils/test_date_format_utils.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/utils/test_string_utils.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/utils/__init__.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/utils/data_validators_utils.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/utils/date_format_utils.py +0 -0
- {fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/utils/string_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: fdc_shared_kernel
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.26
|
|
4
4
|
Summary: Shared library for microservice
|
|
5
5
|
Author-email: Shikhil S <shikhil.s@dbizsolution.com>, Ahammed Akdham N <ahammedakdham.n@dbizsolution.com>
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -31,6 +31,7 @@ Requires-Dist: boto3==1.34.148
|
|
|
31
31
|
Requires-Dist: azure-keyvault-secrets==4.8.0
|
|
32
32
|
Requires-Dist: azure-identity==1.17.1
|
|
33
33
|
Requires-Dist: twine==5.1.1
|
|
34
|
+
Requires-Dist: httpx==0.27.0
|
|
34
35
|
|
|
35
36
|
# FDC Shared Kernel
|
|
36
37
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: fdc_shared_kernel
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.26
|
|
4
4
|
Summary: Shared library for microservice
|
|
5
5
|
Author-email: Shikhil S <shikhil.s@dbizsolution.com>, Ahammed Akdham N <ahammedakdham.n@dbizsolution.com>
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -31,6 +31,7 @@ Requires-Dist: boto3==1.34.148
|
|
|
31
31
|
Requires-Dist: azure-keyvault-secrets==4.8.0
|
|
32
32
|
Requires-Dist: azure-identity==1.17.1
|
|
33
33
|
Requires-Dist: twine==5.1.1
|
|
34
|
+
Requires-Dist: httpx==0.27.0
|
|
34
35
|
|
|
35
36
|
# FDC Shared Kernel
|
|
36
37
|
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/fdc_shared_kernel.egg-info/SOURCES.txt
RENAMED
|
@@ -30,6 +30,7 @@ shared_kernel/interfaces/http.py
|
|
|
30
30
|
shared_kernel/interfaces/keyvault.py
|
|
31
31
|
shared_kernel/logger/__init__.py
|
|
32
32
|
shared_kernel/messaging/__init__.py
|
|
33
|
+
shared_kernel/messaging/http_databus.py
|
|
33
34
|
shared_kernel/messaging/nats_databus.py
|
|
34
35
|
shared_kernel/metrics/__init__.py
|
|
35
36
|
shared_kernel/metrics/status_tracker.py
|
|
@@ -5,7 +5,7 @@ from shared_kernel.interfaces.http import HttpApiClient
|
|
|
5
5
|
|
|
6
6
|
class HttpClient:
|
|
7
7
|
@staticmethod
|
|
8
|
-
def
|
|
8
|
+
def create_client(client_type: str = "requests") -> HttpApiClient:
|
|
9
9
|
if client_type == 'requests':
|
|
10
10
|
return RequestsHttpClient()
|
|
11
11
|
elif client_type == 'httpx':
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Any, Callable
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DataBus(ABC):
|
|
6
|
+
"""
|
|
7
|
+
An abstract base class for a DataBus interface that handles both asynchronous and synchronous messaging.
|
|
8
|
+
|
|
9
|
+
Methods
|
|
10
|
+
-------
|
|
11
|
+
__init__() -> None:
|
|
12
|
+
Initializes the DataBus instance.
|
|
13
|
+
|
|
14
|
+
make_connection():
|
|
15
|
+
Connects to the DataBus server.
|
|
16
|
+
|
|
17
|
+
close_connection():
|
|
18
|
+
Closes the connection to the DataBus server.
|
|
19
|
+
|
|
20
|
+
publish_event(event_name: str, event_payload: dict):
|
|
21
|
+
Publishes an asynchronous message to a DataBus event_name.
|
|
22
|
+
|
|
23
|
+
request_event(event_name: str, event_payload: dict) -> Any:
|
|
24
|
+
Sends a synchronous request/message to a DataBus event_name and receives a response.
|
|
25
|
+
|
|
26
|
+
subscribe_sync_event(event_name: str, callback: Callable[[Any], None]):
|
|
27
|
+
Subscribes to a DataBus event_name and processes messages synchronously.
|
|
28
|
+
|
|
29
|
+
subscribe_async_event(event_name: str, callback: Callable[[Any], None]):
|
|
30
|
+
Subscribes to a DataBus event_name and processes messages asynchronously.
|
|
31
|
+
|
|
32
|
+
delete_message(message_id: str):
|
|
33
|
+
Deletes a message from the DataBus.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
@abstractmethod
|
|
37
|
+
def __init__(self) -> None:
|
|
38
|
+
"""
|
|
39
|
+
Initializes the DataBus instance.
|
|
40
|
+
"""
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
@abstractmethod
|
|
44
|
+
def make_connection(self):
|
|
45
|
+
"""
|
|
46
|
+
Connect to the DataBus server.
|
|
47
|
+
"""
|
|
48
|
+
pass
|
|
49
|
+
|
|
50
|
+
@abstractmethod
|
|
51
|
+
def close_connection(self):
|
|
52
|
+
"""
|
|
53
|
+
Close the connection to the DataBus server.
|
|
54
|
+
"""
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
@abstractmethod
|
|
58
|
+
def publish_event(self, event_name: str, event_payload: dict):
|
|
59
|
+
"""
|
|
60
|
+
Publish an asynchronous message to a DataBus event_name.
|
|
61
|
+
|
|
62
|
+
Parameters:
|
|
63
|
+
- event_name (str): The event name to publish the message to.
|
|
64
|
+
- event_payload (dict): The message to be published.
|
|
65
|
+
"""
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
@abstractmethod
|
|
69
|
+
def request_event(self, event_name: str, event_payload: dict) -> Any:
|
|
70
|
+
"""
|
|
71
|
+
Send a synchronous request/message to a DataBus event name and receive a response.
|
|
72
|
+
|
|
73
|
+
Parameters:
|
|
74
|
+
- event_name (str): The event name to send the message to.
|
|
75
|
+
- event_payload (dict): The message to be sent.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
- Any: The response received from the server.
|
|
79
|
+
"""
|
|
80
|
+
pass
|
|
81
|
+
|
|
82
|
+
@abstractmethod
|
|
83
|
+
def subscribe_sync_event(self, event_name: str, callback: Callable[[Any], None]):
|
|
84
|
+
"""
|
|
85
|
+
Subscribe to a DataBus event name and process messages synchronously.
|
|
86
|
+
|
|
87
|
+
Parameters:
|
|
88
|
+
- event_name (str): The event name to subscribe to.
|
|
89
|
+
- callback (Callable[[Any], None]): A callback function to handle received messages.
|
|
90
|
+
"""
|
|
91
|
+
pass
|
|
92
|
+
|
|
93
|
+
@abstractmethod
|
|
94
|
+
def subscribe_async_event(self, event_name: str, callback: Callable[[Any], None]):
|
|
95
|
+
"""
|
|
96
|
+
Subscribe to a DataBus event name and process messages asynchronously.
|
|
97
|
+
|
|
98
|
+
Parameters:
|
|
99
|
+
- event_name (str): The event name to subscribe to.
|
|
100
|
+
- callback (Callable[[Any], None]): A callback function to handle received messages.
|
|
101
|
+
"""
|
|
102
|
+
pass
|
|
103
|
+
|
|
104
|
+
@abstractmethod
|
|
105
|
+
def delete_message(self, message_id: str):
|
|
106
|
+
"""
|
|
107
|
+
Delete a message from the DataBus.
|
|
108
|
+
|
|
109
|
+
Parameters:
|
|
110
|
+
- message_id (str): The ID or receipt handle of the message to delete.
|
|
111
|
+
"""
|
|
112
|
+
pass
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from shared_kernel.messaging.nats_databus import NATSDataBus
|
|
2
|
+
from shared_kernel.messaging.http_databus import HTTPDataBus
|
|
3
|
+
from shared_kernel.interfaces import DataBus
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DataBus:
|
|
7
|
+
data_bus_classes = {"NATS": NATSDataBus, "HTTP": HTTPDataBus}
|
|
8
|
+
|
|
9
|
+
@staticmethod
|
|
10
|
+
def create_data_bus(bus_type: str, config: dict) -> DataBus:
|
|
11
|
+
data_bus_class = DataBus.data_bus_classes.get(bus_type)
|
|
12
|
+
if data_bus_class is None:
|
|
13
|
+
raise ValueError(f"Unknown data bus type: {bus_type}")
|
|
14
|
+
return data_bus_class(config)
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Callable, Any, Dict
|
|
4
|
+
from shared_kernel.interfaces import DataBus
|
|
5
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
6
|
+
from shared_kernel.http import HttpClient
|
|
7
|
+
|
|
8
|
+
logging.getLogger().setLevel(logging.INFO)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class HTTPDataBus(DataBus):
|
|
12
|
+
"""
|
|
13
|
+
A class to handle HTTP-based event operations, including EventBridge and SQS.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
_instance = None
|
|
17
|
+
|
|
18
|
+
def __new__(cls, *args, **kwargs):
|
|
19
|
+
if cls._instance is None:
|
|
20
|
+
cls._instance = super(HTTPDataBus, cls).__new__(cls)
|
|
21
|
+
return cls._instance
|
|
22
|
+
|
|
23
|
+
def __init__(self, config: Dict = None):
|
|
24
|
+
"""
|
|
25
|
+
Initialize the HTTPDataBus.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
config (Dict): A dictionary containing the HTTP client configuration.
|
|
29
|
+
"""
|
|
30
|
+
if not hasattr(self, "initialized"): # Prevent reinitialization
|
|
31
|
+
super().__init__()
|
|
32
|
+
self.http_client = HttpClient().create_client()
|
|
33
|
+
self.initialized = True
|
|
34
|
+
|
|
35
|
+
async def publish_event(self, event_name: str, event_payload: dict):
|
|
36
|
+
"""
|
|
37
|
+
Send an event payload to multiple HTTP endpoints and return the responses.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
event_name (str): The URLs to invoke the HTTP endpoints.
|
|
41
|
+
event_payload (dict): The payload containing all necessary information for the HTTP requests.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
None
|
|
45
|
+
"""
|
|
46
|
+
with ThreadPoolExecutor(max_workers=5) as executor:
|
|
47
|
+
futures = [executor.submit(self.http_client.post, url=url, json=event_payload) for url in event_name]
|
|
48
|
+
for future in futures:
|
|
49
|
+
future.result()
|
|
50
|
+
|
|
51
|
+
def subscribe_async_event(self, event_name: str, callback: Callable[[Any], None]):
|
|
52
|
+
"""
|
|
53
|
+
Subscribe to asynchronous events and invoke the provided callback upon receiving an event.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
event_name (str): The event name or URL to subscribe to.
|
|
57
|
+
callback (Callable[[Any], None]): The callback function to invoke with the event data.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
asyncio.Task: The task handling the asynchronous event subscription.
|
|
61
|
+
"""
|
|
62
|
+
return asyncio.create_task(callback(event_name))
|
|
63
|
+
|
|
64
|
+
def request_event(self, event_name: str, event_payload: dict) -> Any:
|
|
65
|
+
"""
|
|
66
|
+
Send an event payload to an HTTP endpoint and return the response.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
event_name (str): The URL to invoke the HTTP endpoint.
|
|
70
|
+
event_payload (dict): The payload containing all necessary information for the HTTP request.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Any: The response from the HTTP endpoint.
|
|
74
|
+
"""
|
|
75
|
+
response = self.http_client.post(url=event_name, json=event_payload)
|
|
76
|
+
return response
|
|
77
|
+
|
|
78
|
+
def subscribe_sync_event(self, event_name: str, callback: Callable[[Any], None]):
|
|
79
|
+
"""
|
|
80
|
+
Subscribe to synchronous events and invoke the provided callback upon receiving an event.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
event_name (str): The event name or URL to subscribe to.
|
|
84
|
+
callback (Callable[[Any], None]): The callback function to invoke with the event data.
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
Any: The result of the callback function.
|
|
88
|
+
"""
|
|
89
|
+
return callback(event_name)
|
|
90
|
+
|
|
91
|
+
def delete_message(self, receipt_handle: str):
|
|
92
|
+
"""
|
|
93
|
+
Placeholder method for deleting a message.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
receipt_handle (str): The receipt handle of the message to be deleted.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
None
|
|
100
|
+
"""
|
|
101
|
+
pass
|
|
102
|
+
|
|
103
|
+
def make_connection(self, receipt_handle: str):
|
|
104
|
+
"""
|
|
105
|
+
Placeholder method for establishing a connection.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
receipt_handle (str): The receipt handle related to the connection.
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
None
|
|
112
|
+
"""
|
|
113
|
+
pass
|
|
114
|
+
|
|
115
|
+
def close_connection(self, receipt_handle: str):
|
|
116
|
+
"""
|
|
117
|
+
Placeholder method for closing a connection.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
receipt_handle (str): The receipt handle related to the connection.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
None
|
|
124
|
+
"""
|
|
125
|
+
pass
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/messaging/nats_databus.py
RENAMED
|
@@ -2,16 +2,15 @@ import json
|
|
|
2
2
|
import logging
|
|
3
3
|
from nats.aio.client import Client as NATS
|
|
4
4
|
from nats.js.api import StreamConfig, ConsumerConfig, DeliverPolicy
|
|
5
|
-
from typing import Callable, Any, List, Union
|
|
5
|
+
from typing import Callable, Any, List, Union, Dict
|
|
6
6
|
from shared_kernel.interfaces import DataBus
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
logging.getLogger().setLevel(logging.INFO)
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
class NATSDataBus(DataBus):
|
|
13
12
|
"""
|
|
14
|
-
A NATS
|
|
13
|
+
A NATS interface class to handle both standard NATS and JetStream operations.
|
|
15
14
|
"""
|
|
16
15
|
|
|
17
16
|
_instance = None
|
|
@@ -21,31 +20,38 @@ class NATSDataBus(DataBus):
|
|
|
21
20
|
cls._instance = super(NATSDataBus, cls).__new__(cls)
|
|
22
21
|
return cls._instance
|
|
23
22
|
|
|
24
|
-
def __init__(self,
|
|
23
|
+
def __init__(self, config: Dict = None):
|
|
25
24
|
"""
|
|
26
|
-
Initialize the
|
|
25
|
+
Initialize the NATSDataBus.
|
|
27
26
|
|
|
28
27
|
Args:
|
|
29
|
-
|
|
28
|
+
config (Dict): A dictionary containing the NATS configuration.
|
|
30
29
|
"""
|
|
31
|
-
if not hasattr(self, "initialized"): #
|
|
30
|
+
if not hasattr(self, "initialized"): # Prevent reinitialization
|
|
32
31
|
super().__init__()
|
|
33
32
|
self.nc = NATS()
|
|
34
|
-
self.servers = servers
|
|
35
|
-
self.user = user
|
|
36
|
-
self.password = password
|
|
33
|
+
self.servers = config.get('servers')
|
|
34
|
+
self.user = config.get('user')
|
|
35
|
+
self.password = config.get('password')
|
|
37
36
|
self.connected = False
|
|
38
37
|
self.js = None # JetStream context
|
|
39
38
|
self.initialized = True
|
|
39
|
+
self.stream_name = config.get('stream_name', '')
|
|
40
|
+
self.event_names = config.get('event_names', [])
|
|
41
|
+
|
|
42
|
+
if self.stream_name and self.event_names:
|
|
43
|
+
self.create_stream(self.stream_name, self.event_names)
|
|
40
44
|
|
|
41
45
|
async def make_connection(self):
|
|
42
46
|
"""
|
|
43
47
|
Connect to the NATS server.
|
|
44
48
|
"""
|
|
45
49
|
if not self.connected:
|
|
46
|
-
await self.nc.connect(
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
await self.nc.connect(
|
|
51
|
+
servers=self.servers,
|
|
52
|
+
user=self.user,
|
|
53
|
+
password=self.password
|
|
54
|
+
)
|
|
49
55
|
self.js = self.nc.jetstream(timeout=10)
|
|
50
56
|
self.connected = True
|
|
51
57
|
|
|
@@ -53,19 +59,20 @@ class NATSDataBus(DataBus):
|
|
|
53
59
|
"""
|
|
54
60
|
Close the connection to the NATS server.
|
|
55
61
|
"""
|
|
56
|
-
|
|
57
|
-
|
|
62
|
+
if self.connected:
|
|
63
|
+
try:
|
|
58
64
|
await self.nc.close()
|
|
59
65
|
self.connected = False
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
except Exception as e:
|
|
67
|
+
raise e
|
|
62
68
|
|
|
63
|
-
async def create_stream(self, stream_name: str,
|
|
69
|
+
async def create_stream(self, stream_name: str, event_names: List[Any]):
|
|
64
70
|
"""
|
|
65
|
-
Create a stream for
|
|
71
|
+
Create a stream for event names to persist the messages.
|
|
66
72
|
|
|
67
73
|
Args:
|
|
68
|
-
|
|
74
|
+
stream_name (str): The name of the stream.
|
|
75
|
+
event_names (List[Any]): The subjects whose messages will be persisted.
|
|
69
76
|
"""
|
|
70
77
|
try:
|
|
71
78
|
self.stream_name = stream_name
|
|
@@ -76,40 +83,41 @@ class NATSDataBus(DataBus):
|
|
|
76
83
|
# Stream does not exist, so create it
|
|
77
84
|
stream_config = StreamConfig(
|
|
78
85
|
name=stream_name,
|
|
79
|
-
subjects=
|
|
80
|
-
max_age=600
|
|
86
|
+
subjects=event_names,
|
|
87
|
+
max_age=600 # Retain messages for 10 minutes
|
|
81
88
|
)
|
|
82
89
|
await self.js.add_stream(stream_config)
|
|
83
|
-
logging.info(f"Stream
|
|
90
|
+
logging.info(f"Stream '{stream_name}' created.")
|
|
84
91
|
|
|
85
92
|
async def publish_event(
|
|
86
|
-
|
|
93
|
+
self, event_name: str, event_payload: dict
|
|
87
94
|
) -> Union[bool, Exception]:
|
|
88
95
|
"""
|
|
89
96
|
Publish a message to a JetStream subject.
|
|
90
97
|
|
|
91
98
|
Args:
|
|
92
|
-
|
|
99
|
+
event_name (str): The subject to publish the message to.
|
|
93
100
|
event_payload (dict): The message to be published.
|
|
94
101
|
|
|
95
102
|
Returns:
|
|
96
103
|
bool: True if the event was published successfully.
|
|
97
104
|
"""
|
|
98
105
|
ack = await self.js.publish(
|
|
99
|
-
|
|
106
|
+
event_name, json.dumps(event_payload).encode("utf-8")
|
|
100
107
|
)
|
|
101
108
|
logging.info(
|
|
102
|
-
f"Published event '{event_payload.get('event_name')}' to
|
|
109
|
+
f"Published event '{event_payload.get('event_name')}' to subject '{event_name}', ack: {ack}"
|
|
103
110
|
)
|
|
111
|
+
return True
|
|
104
112
|
|
|
105
113
|
async def request_event(
|
|
106
|
-
|
|
114
|
+
self, event_name: str, event_payload: dict, timeout: float = 10.0
|
|
107
115
|
) -> Union[dict, Exception]:
|
|
108
116
|
"""
|
|
109
117
|
Send a request and wait for a response.
|
|
110
118
|
|
|
111
119
|
Args:
|
|
112
|
-
|
|
120
|
+
event_name (str): The subject to publish the message to.
|
|
113
121
|
event_payload (dict): The message to be published.
|
|
114
122
|
timeout (float): The timeout for the request.
|
|
115
123
|
|
|
@@ -117,19 +125,20 @@ class NATSDataBus(DataBus):
|
|
|
117
125
|
dict: The response message.
|
|
118
126
|
"""
|
|
119
127
|
response = await self.nc.request(
|
|
120
|
-
|
|
128
|
+
event_name, json.dumps(event_payload).encode("utf-8"), timeout=timeout
|
|
121
129
|
)
|
|
122
130
|
return json.loads(response.data.decode("utf-8"))
|
|
123
131
|
|
|
124
132
|
async def subscribe_async_event(
|
|
125
|
-
|
|
133
|
+
self, event_name: str, callback: Callable[[Any], None], durable_name: str
|
|
126
134
|
):
|
|
127
135
|
"""
|
|
128
136
|
Subscribe to a JetStream subject with a durable consumer and process messages asynchronously.
|
|
129
137
|
|
|
130
138
|
Args:
|
|
131
|
-
|
|
132
|
-
callback: A callback function to handle received messages.
|
|
139
|
+
event_name (str): The subject to subscribe to.
|
|
140
|
+
callback (Callable[[Any], None]): A callback function to handle received messages.
|
|
141
|
+
durable_name (str): The name of the durable consumer.
|
|
133
142
|
"""
|
|
134
143
|
try:
|
|
135
144
|
# Check if the consumer already exists
|
|
@@ -147,16 +156,22 @@ class NATSDataBus(DataBus):
|
|
|
147
156
|
await self.js.add_consumer(stream=self.stream_name, config=self.consumer_config)
|
|
148
157
|
logging.info(f"Consumer '{durable_name}' created.")
|
|
149
158
|
|
|
150
|
-
await self.js.subscribe_bind(
|
|
151
|
-
|
|
159
|
+
await self.js.subscribe_bind(
|
|
160
|
+
stream=self.stream_name, cb=callback, config=self.consumer_config,
|
|
161
|
+
consumer=durable_name
|
|
162
|
+
)
|
|
163
|
+
logging.info(f"Subscribed to async event on subject '{event_name}'")
|
|
152
164
|
|
|
153
|
-
async def subscribe_sync_event(self,
|
|
165
|
+
async def subscribe_sync_event(self, event_name: str, callback: Callable[[Any], None]):
|
|
154
166
|
"""
|
|
155
|
-
Subscribe to a NATS subject and
|
|
167
|
+
Subscribe to a NATS subject and process the message synchronously.
|
|
156
168
|
|
|
157
169
|
Args:
|
|
158
|
-
|
|
159
|
-
callback: A callback function to handle received messages.
|
|
170
|
+
event_name (str): The subject to subscribe to.
|
|
171
|
+
callback (Callable[[Any], None]): A callback function to handle received messages.
|
|
160
172
|
"""
|
|
161
|
-
await self.nc.subscribe(
|
|
162
|
-
logging.info(f"Subscribed to sync event on
|
|
173
|
+
await self.nc.subscribe(event_name, cb=callback)
|
|
174
|
+
logging.info(f"Subscribed to sync event on subject '{event_name}'")
|
|
175
|
+
|
|
176
|
+
def delete_message(self, receipt_handle: str):
|
|
177
|
+
pass
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/security/key_vault/__init__.py
RENAMED
|
@@ -4,11 +4,12 @@ from shared_kernel.security.key_vault.azure_keyvault import AzureKeyVault
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class KeyVaultManager:
|
|
7
|
+
|
|
8
|
+
keyvault_classes = {"AZURE": AzureKeyVault, "AWS": AWSSecretsManager}
|
|
9
|
+
|
|
7
10
|
@staticmethod
|
|
8
|
-
def
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
elif vault_type == 'AWS':
|
|
12
|
-
return AWSSecretsManager(config)
|
|
13
|
-
else:
|
|
11
|
+
def create_data_bus(vault_type: str, config: dict) -> KeyVaultInterface:
|
|
12
|
+
keyvault_class = KeyVaultManager.keyvault_classes.get(vault_type)
|
|
13
|
+
if keyvault_class is None:
|
|
14
14
|
raise ValueError(f"Unknown vault type: {vault_type}")
|
|
15
|
+
return keyvault_class(config)
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import Any, Callable
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class DataBus(ABC):
|
|
6
|
-
"""
|
|
7
|
-
An abstract base class for a DataBus interface that handles both asynchronous and synchronous messaging.
|
|
8
|
-
|
|
9
|
-
Methods
|
|
10
|
-
-------
|
|
11
|
-
__init__() -> None:
|
|
12
|
-
Initializes the DataBus instance.
|
|
13
|
-
|
|
14
|
-
make_connection():
|
|
15
|
-
Connects to the DataBus server.
|
|
16
|
-
|
|
17
|
-
close_connection():
|
|
18
|
-
Closes the connection to the DataBus server.
|
|
19
|
-
|
|
20
|
-
publish_event(topic: str, event_payload: dict):
|
|
21
|
-
Publishes an asynchronous message to a DataBus topic.
|
|
22
|
-
|
|
23
|
-
request_event(topic: str, event_payload: dict) -> Any:
|
|
24
|
-
Sends a synchronous request/message to a DataBus topic and receives a response.
|
|
25
|
-
|
|
26
|
-
subscribe_sync_event(topic: str, callback: Callable[[Any], None]):
|
|
27
|
-
Subscribes to a DataBus topic and processes messages synchronously.
|
|
28
|
-
|
|
29
|
-
subscribe_async_event(topic: str, callback: Callable[[Any], None]):
|
|
30
|
-
Subscribes to a DataBus topic and processes messages asynchronously.
|
|
31
|
-
"""
|
|
32
|
-
|
|
33
|
-
@abstractmethod
|
|
34
|
-
def __init__(self) -> None:
|
|
35
|
-
"""
|
|
36
|
-
Initializes the DataBus instance.
|
|
37
|
-
"""
|
|
38
|
-
pass
|
|
39
|
-
|
|
40
|
-
@abstractmethod
|
|
41
|
-
def make_connection(self):
|
|
42
|
-
"""
|
|
43
|
-
Connect to the DataBus server.
|
|
44
|
-
"""
|
|
45
|
-
pass
|
|
46
|
-
|
|
47
|
-
@abstractmethod
|
|
48
|
-
def close_connection(self):
|
|
49
|
-
"""
|
|
50
|
-
Close the connection to the DataBus server.
|
|
51
|
-
"""
|
|
52
|
-
pass
|
|
53
|
-
|
|
54
|
-
@abstractmethod
|
|
55
|
-
def publish_event(self, topic: str, event_payload: dict):
|
|
56
|
-
"""
|
|
57
|
-
Publish an asynchronous message to a DataBus topic.
|
|
58
|
-
|
|
59
|
-
Parameters:
|
|
60
|
-
- topic (str): The topic to publish the message to.
|
|
61
|
-
- event_payload (dict): The message to be published.
|
|
62
|
-
"""
|
|
63
|
-
pass
|
|
64
|
-
|
|
65
|
-
@abstractmethod
|
|
66
|
-
def request_event(self, topic: str, event_payload: dict) -> Any:
|
|
67
|
-
"""
|
|
68
|
-
Send a synchronous request/message to a DataBus topic and receive a response.
|
|
69
|
-
|
|
70
|
-
Parameters:
|
|
71
|
-
- topic (str): The topic to send the message to.
|
|
72
|
-
- event_payload (dict): The message to be sent.
|
|
73
|
-
|
|
74
|
-
Returns:
|
|
75
|
-
- Any: The response received from the server.
|
|
76
|
-
"""
|
|
77
|
-
pass
|
|
78
|
-
|
|
79
|
-
@abstractmethod
|
|
80
|
-
def subscribe_sync_event(self, topic: str, callback: Callable[[Any], None]):
|
|
81
|
-
"""
|
|
82
|
-
Subscribe to a DataBus topic and process messages synchronously.
|
|
83
|
-
|
|
84
|
-
Parameters:
|
|
85
|
-
- topic (str): The topic to subscribe to.
|
|
86
|
-
- callback (Callable[[Any], None]): A callback function to handle received messages.
|
|
87
|
-
"""
|
|
88
|
-
pass
|
|
89
|
-
|
|
90
|
-
@abstractmethod
|
|
91
|
-
def subscribe_async_event(self, topic: str, callback: Callable[[Any], None]):
|
|
92
|
-
"""
|
|
93
|
-
Subscribe to a DataBus topic and process messages asynchronously.
|
|
94
|
-
|
|
95
|
-
Parameters:
|
|
96
|
-
- topic (str): The topic to subscribe to.
|
|
97
|
-
- callback (Callable[[Any], None]): A callback function to handle received messages.
|
|
98
|
-
"""
|
|
99
|
-
pass
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from shared_kernel.messaging.nats_databus import * # noqa
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/fdc_shared_kernel.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/exceptions/custom_exceptions.py
RENAMED
|
File without changes
|
|
File without changes
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/exceptions/http_exceptions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/http/httpx_http_client.py
RENAMED
|
File without changes
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/http/request_http_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/metrics/status_tracker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/config/__init__.py
RENAMED
|
File without changes
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/config/test_config.py
RENAMED
|
File without changes
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/logger/__init__.py
RENAMED
|
File without changes
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/logger/test_logger.py
RENAMED
|
File without changes
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/messaging/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/tests/utils/test_string_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/utils/data_validators_utils.py
RENAMED
|
File without changes
|
{fdc_shared_kernel-0.0.24 → fdc_shared_kernel-0.0.26}/shared_kernel/utils/date_format_utils.py
RENAMED
|
File without changes
|
|
File without changes
|