fdc-shared-kernel 0.0.28__tar.gz → 0.0.30__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 (58) hide show
  1. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/PKG-INFO +1 -1
  2. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/fdc_shared_kernel.egg-info/PKG-INFO +1 -1
  3. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/pyproject.toml +1 -1
  4. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/http/httpx_http_client.py +21 -8
  5. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/http/request_http_client.py +25 -23
  6. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/interfaces/http.py +15 -14
  7. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/logger/__init__.py +31 -1
  8. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/messaging/http_databus.py +15 -1
  9. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/README.md +0 -0
  10. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/README_pypi.md +0 -0
  11. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/fdc_shared_kernel.egg-info/SOURCES.txt +0 -0
  12. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/fdc_shared_kernel.egg-info/dependency_links.txt +0 -0
  13. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/fdc_shared_kernel.egg-info/requires.txt +0 -0
  14. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/fdc_shared_kernel.egg-info/top_level.txt +0 -0
  15. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/requirements.txt +0 -0
  16. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/setup.cfg +0 -0
  17. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/__init__.py +0 -0
  18. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/auth/__init__.py +0 -0
  19. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/auth/jwt_helper.py +0 -0
  20. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/auth/token_handler.py +0 -0
  21. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/config/__init__.py +0 -0
  22. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/database/__init__.py +0 -0
  23. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/exceptions/__init__.py +0 -0
  24. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/exceptions/configuration_exceptions.py +0 -0
  25. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/exceptions/custom_exceptions.py +0 -0
  26. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/exceptions/data_validation_exceptions.py +0 -0
  27. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/exceptions/http_exceptions.py +0 -0
  28. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/exceptions/infrastructure_exceptions.py +0 -0
  29. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/exceptions/operational_exceptions.py +0 -0
  30. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/exceptions/security_exceptions.py +0 -0
  31. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/http/__init__.py +0 -0
  32. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/interfaces/__init__.py +0 -0
  33. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/interfaces/databus.py +0 -0
  34. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/interfaces/keyvault.py +0 -0
  35. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/messaging/__init__.py +0 -0
  36. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/messaging/nats_databus.py +0 -0
  37. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/metrics/__init__.py +0 -0
  38. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/metrics/status_tracker.py +0 -0
  39. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/models/__init__.py +0 -0
  40. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/security/__init__.py +0 -0
  41. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/security/key_vault/__init__.py +0 -0
  42. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/security/key_vault/aws_secret_manager.py +0 -0
  43. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/security/key_vault/azure_keyvault.py +0 -0
  44. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/tests/__init__.py +0 -0
  45. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/tests/config/__init__.py +0 -0
  46. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/tests/config/test_config.py +0 -0
  47. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/tests/logger/__init__.py +0 -0
  48. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/tests/logger/test_logger.py +0 -0
  49. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/tests/messaging/__init__.py +0 -0
  50. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/tests/messaging/test_nats_interface.py +0 -0
  51. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/tests/utils/__init__.py +0 -0
  52. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/tests/utils/test_data_validators.py +0 -0
  53. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/tests/utils/test_date_format_utils.py +0 -0
  54. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/tests/utils/test_string_utils.py +0 -0
  55. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/utils/__init__.py +0 -0
  56. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/utils/data_validators_utils.py +0 -0
  57. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/shared_kernel/utils/date_format_utils.py +0 -0
  58. {fdc_shared_kernel-0.0.28 → fdc_shared_kernel-0.0.30}/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.28
3
+ Version: 0.0.30
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fdc_shared_kernel
3
- Version: 0.0.28
3
+ Version: 0.0.30
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "fdc_shared_kernel"
7
- version = "0.0.28"
7
+ version = "0.0.30"
8
8
  requires-python = ">=3.7"
9
9
  readme = "README_pypi.md"
10
10
  description = "Shared library for microservice"
@@ -1,6 +1,7 @@
1
1
  import httpx
2
2
  from shared_kernel.interfaces import HttpApiClient
3
3
 
4
+
4
5
  class HttpxHttpClient(HttpApiClient):
5
6
  """
6
7
  An implementation of the HttpApiClient interface using httpx for asynchronous HTTP requests.
@@ -49,7 +50,9 @@ class HttpxHttpClient(HttpApiClient):
49
50
  response = await client.get(url, params=params, headers=headers)
50
51
  return response.json()
51
52
 
52
- async def post(self, url: str, data: dict = None, json: dict = None, headers: dict = None) -> dict:
53
+ async def post(
54
+ self, url: str, data: dict = None, json: dict = None, headers: dict = None
55
+ ) -> dict:
53
56
  """
54
57
  Sends an asynchronous POST request to the specified URL.
55
58
 
@@ -66,7 +69,9 @@ class HttpxHttpClient(HttpApiClient):
66
69
  response = await client.post(url, data=data, json=json, headers=headers)
67
70
  return response.json()
68
71
 
69
- async def put(self, url: str, data: dict = None, json: dict = None, headers: dict = None) -> dict:
72
+ async def put(
73
+ self, url: str, data: dict = None, json: dict = None, headers: dict = None
74
+ ) -> dict:
70
75
  """
71
76
  Sends an asynchronous PUT request to the specified URL.
72
77
 
@@ -98,7 +103,9 @@ class HttpxHttpClient(HttpApiClient):
98
103
  response = await client.delete(url, headers=headers)
99
104
  return response.json()
100
105
 
101
- async def patch(self, url: str, data: dict = None, json: dict = None, headers: dict = None) -> dict:
106
+ async def patch(
107
+ self, url: str, data: dict = None, json: dict = None, headers: dict = None
108
+ ) -> dict:
102
109
  """
103
110
  Sends an asynchronous PATCH request to the specified URL.
104
111
 
@@ -130,7 +137,9 @@ class HttpxHttpClient(HttpApiClient):
130
137
  response = await client.head(url, headers=headers)
131
138
  return response.json()
132
139
 
133
- async def upload_file(self, url: str, file_path: str, filename: str, headers: dict = None) -> dict:
140
+ async def upload_file(
141
+ self, url: str, file_path: str, filename: str, headers: dict = None
142
+ ) -> dict:
134
143
  """
135
144
  Uploads a file asynchronously to the specified URL.
136
145
 
@@ -144,11 +153,15 @@ class HttpxHttpClient(HttpApiClient):
144
153
  - dict: The response from the server as a JSON-decoded dictionary.
145
154
  """
146
155
  async with httpx.AsyncClient() as client:
147
- with open(file_path, 'rb') as file:
148
- response = await client.post(url, files={filename: file}, headers=headers)
156
+ with open(file_path, "rb") as file:
157
+ response = await client.post(
158
+ url, files={filename: file}, headers=headers
159
+ )
149
160
  return response.json()
150
161
 
151
- async def download_file(self, url: str, save_path: str, headers: dict = None) -> None:
162
+ async def download_file(
163
+ self, url: str, save_path: str, headers: dict = None
164
+ ) -> None:
152
165
  """
153
166
  Downloads a file asynchronously from the specified URL and saves it to the given path.
154
167
 
@@ -162,5 +175,5 @@ class HttpxHttpClient(HttpApiClient):
162
175
  """
163
176
  async with httpx.AsyncClient() as client:
164
177
  response = await client.get(url, headers=headers)
165
- with open(save_path, 'wb') as file:
178
+ with open(save_path, "wb") as file:
166
179
  file.write(await response.aread())
@@ -1,4 +1,6 @@
1
1
  import requests
2
+ from requests.exceptions import Timeout, RequestException
3
+ from requests import Response
2
4
 
3
5
  from shared_kernel.exceptions import InternalServerError
4
6
  from shared_kernel.interfaces.http import HttpApiClient
@@ -36,7 +38,7 @@ class RequestsHttpClient(HttpApiClient):
36
38
  Downloads a file synchronously from the specified URL and saves it to the given path.
37
39
  """
38
40
 
39
- def get(self, url: str, params: dict = None, headers: dict = None) -> dict:
41
+ def get(self, url: str, params: dict = None, headers: dict = None) -> Response:
40
42
  """
41
43
  Sends a synchronous GET request to the specified URL.
42
44
 
@@ -46,15 +48,15 @@ class RequestsHttpClient(HttpApiClient):
46
48
  - headers (dict, optional): HTTP headers to include in the request.
47
49
 
48
50
  Returns:
49
- - dict: The response from the server as a JSON-decoded dictionary.
51
+ - Response: Http response object
50
52
  """
51
53
  try:
52
54
  response = requests.get(url, params=params, headers=headers)
53
- return response.json()
54
- except requests.exceptions.RequestException as e:
55
+ return response
56
+ except (Timeout, RequestException) as e:
55
57
  raise InternalServerError(message=str(e))
56
58
 
57
- def post(self, url: str, data: dict = None, json: dict = None, headers: dict = None) -> dict:
59
+ def post(self, url: str, data: dict = None, json: dict = None, headers: dict = None) -> Response:
58
60
  """
59
61
  Sends a synchronous POST request to the specified URL.
60
62
 
@@ -65,15 +67,15 @@ class RequestsHttpClient(HttpApiClient):
65
67
  - headers (dict, optional): HTTP headers to include in the request.
66
68
 
67
69
  Returns:
68
- - dict: The response from the server as a JSON-decoded dictionary.
70
+ - Response: Http response object
69
71
  """
70
72
  try:
71
73
  response = requests.post(url, data=data, json=json, headers=headers)
72
- return response.json()
73
- except requests.exceptions.RequestException as e:
74
+ return response
75
+ except (Timeout, RequestException) as e:
74
76
  raise InternalServerError(message=str(e))
75
77
 
76
- def put(self, url: str, data: dict = None, json: dict = None, headers: dict = None) -> dict:
78
+ def put(self, url: str, data: dict = None, json: dict = None, headers: dict = None) -> Response:
77
79
  """
78
80
  Sends a synchronous PUT request to the specified URL.
79
81
 
@@ -84,12 +86,12 @@ class RequestsHttpClient(HttpApiClient):
84
86
  - headers (dict, optional): HTTP headers to include in the request.
85
87
 
86
88
  Returns:
87
- - dict: The response from the server as a JSON-decoded dictionary.
89
+ - Response: Http response object
88
90
  """
89
91
  response = requests.put(url, data=data, json=json, headers=headers)
90
- return response.json()
92
+ return response
91
93
 
92
- def delete(self, url: str, headers: dict = None) -> dict:
94
+ def delete(self, url: str, headers: dict = None) -> Response:
93
95
  """
94
96
  Sends a synchronous DELETE request to the specified URL.
95
97
 
@@ -98,15 +100,15 @@ class RequestsHttpClient(HttpApiClient):
98
100
  - headers (dict, optional): HTTP headers to include in the request.
99
101
 
100
102
  Returns:
101
- - dict: The response from the server as a JSON-decoded dictionary.
103
+ - Response: Http response object
102
104
  """
103
105
  try:
104
106
  response = requests.delete(url, headers=headers)
105
- return response.json()
107
+ return response
106
108
  except requests.exceptions.RequestException as e:
107
109
  raise InternalServerError(message=str(e))
108
110
 
109
- def patch(self, url: str, data: dict = None, json: dict = None, headers: dict = None) -> dict:
111
+ def patch(self, url: str, data: dict = None, json: dict = None, headers: dict = None) -> Response:
110
112
  """
111
113
  Sends a synchronous PATCH request to the specified URL.
112
114
 
@@ -117,15 +119,15 @@ class RequestsHttpClient(HttpApiClient):
117
119
  - headers (dict, optional): HTTP headers to include in the request.
118
120
 
119
121
  Returns:
120
- - dict: The response from the server as a JSON-decoded dictionary.
122
+ - Response: Http response object
121
123
  """
122
124
  try:
123
125
  response = requests.patch(url, data=data, json=json, headers=headers)
124
- return response.json()
126
+ return response
125
127
  except requests.exceptions.RequestException as e:
126
128
  raise InternalServerError(message=str(e))
127
129
 
128
- def head(self, url: str, headers: dict = None) -> dict:
130
+ def head(self, url: str, headers: dict = None) -> Response:
129
131
  """
130
132
  Sends a synchronous HEAD request to the specified URL.
131
133
 
@@ -134,15 +136,15 @@ class RequestsHttpClient(HttpApiClient):
134
136
  - headers (dict, optional): HTTP headers to include in the request.
135
137
 
136
138
  Returns:
137
- - dict: The response from the server as a JSON-decoded dictionary.
139
+ - Response: Http response object
138
140
  """
139
141
  try:
140
142
  response = requests.head(url, headers=headers)
141
- return response.json()
143
+ return response
142
144
  except requests.exceptions.RequestException as e:
143
145
  raise InternalServerError(message=str(e))
144
146
 
145
- def upload_file(self, url: str, file_path: str, filename: str, headers: dict = None) -> dict:
147
+ def upload_file(self, url: str, file_path: str, filename: str, headers: dict = None) -> Response:
146
148
  """
147
149
  Uploads a file synchronously to the specified URL.
148
150
 
@@ -153,12 +155,12 @@ class RequestsHttpClient(HttpApiClient):
153
155
  - headers (dict, optional): HTTP headers to include in the request.
154
156
 
155
157
  Returns:
156
- - dict: The response from the server as a JSON-decoded dictionary.
158
+ - Response: Http response object
157
159
  """
158
160
  try:
159
161
  with open(file_path, 'rb') as file:
160
162
  response = requests.post(url, files={filename: file}, headers=headers)
161
- return response.json()
163
+ return response
162
164
  except requests.exceptions.RequestException as e:
163
165
  raise InternalServerError(message=str(e))
164
166
 
@@ -1,4 +1,5 @@
1
1
  from abc import ABC, abstractmethod
2
+ from requests import Response
2
3
 
3
4
 
4
5
  class HttpApiClient(ABC):
@@ -34,7 +35,7 @@ class HttpApiClient(ABC):
34
35
  """
35
36
 
36
37
  @abstractmethod
37
- def get(self, url: str, params: dict = None, headers: dict = None) -> dict:
38
+ def get(self, url: str, params: dict = None, headers: dict = None) -> Response:
38
39
  """
39
40
  Sends a GET request to the specified URL.
40
41
 
@@ -44,12 +45,12 @@ class HttpApiClient(ABC):
44
45
  - headers (dict, optional): HTTP headers to include in the request.
45
46
 
46
47
  Returns:
47
- - dict: The response from the server as a dictionary.
48
+ - Response: Http response object
48
49
  """
49
50
  pass
50
51
 
51
52
  @abstractmethod
52
- def post(self, url: str, data: dict = None, json: dict = None, headers: dict = None) -> dict:
53
+ def post(self, url: str, data: dict = None, json: dict = None, headers: dict = None) -> Response:
53
54
  """
54
55
  Sends a POST request to the specified URL with optional data or JSON payload.
55
56
 
@@ -60,12 +61,12 @@ class HttpApiClient(ABC):
60
61
  - headers (dict, optional): HTTP headers to include in the request.
61
62
 
62
63
  Returns:
63
- - dict: The response from the server as a dictionary.
64
+ - Response: Http response object
64
65
  """
65
66
  pass
66
67
 
67
68
  @abstractmethod
68
- def put(self, url: str, data: dict = None, json: dict = None, headers: dict = None) -> dict:
69
+ def put(self, url: str, data: dict = None, json: dict = None, headers: dict = None) -> Response:
69
70
  """
70
71
  Sends a PUT request to the specified URL with optional data or JSON payload.
71
72
 
@@ -76,12 +77,12 @@ class HttpApiClient(ABC):
76
77
  - headers (dict, optional): HTTP headers to include in the request.
77
78
 
78
79
  Returns:
79
- - dict: The response from the server as a dictionary.
80
+ - Response: Http response object
80
81
  """
81
82
  pass
82
83
 
83
84
  @abstractmethod
84
- def delete(self, url: str, headers: dict = None) -> dict:
85
+ def delete(self, url: str, headers: dict = None) -> Response:
85
86
  """
86
87
  Sends a DELETE request to the specified URL.
87
88
 
@@ -90,12 +91,12 @@ class HttpApiClient(ABC):
90
91
  - headers (dict, optional): HTTP headers to include in the request.
91
92
 
92
93
  Returns:
93
- - dict: The response from the server as a dictionary.
94
+ - Response: Http response object
94
95
  """
95
96
  pass
96
97
 
97
98
  @abstractmethod
98
- def patch(self, url: str, data: dict = None, json: dict = None, headers: dict = None) -> dict:
99
+ def patch(self, url: str, data: dict = None, json: dict = None, headers: dict = None) -> Response:
99
100
  """
100
101
  Sends a PATCH request to the specified URL with optional data or JSON payload.
101
102
 
@@ -106,12 +107,12 @@ class HttpApiClient(ABC):
106
107
  - headers (dict, optional): HTTP headers to include in the request.
107
108
 
108
109
  Returns:
109
- - dict: The response from the server as a dictionary.
110
+ - Response: Http response object
110
111
  """
111
112
  pass
112
113
 
113
114
  @abstractmethod
114
- def head(self, url: str, headers: dict = None) -> dict:
115
+ def head(self, url: str, headers: dict = None) -> Response:
115
116
  """
116
117
  Sends a HEAD request to the specified URL.
117
118
 
@@ -120,12 +121,12 @@ class HttpApiClient(ABC):
120
121
  - headers (dict, optional): HTTP headers to include in the request.
121
122
 
122
123
  Returns:
123
- - dict: The response from the server as a dictionary.
124
+ - Response: Http response object
124
125
  """
125
126
  pass
126
127
 
127
128
  @abstractmethod
128
- def upload_file(self, url: str, file_path: str, filename: str, headers: dict = None) -> dict:
129
+ def upload_file(self, url: str, file_path: str, filename: str, headers: dict = None) -> Response:
129
130
  """
130
131
  Uploads a file to the specified URL.
131
132
 
@@ -136,7 +137,7 @@ class HttpApiClient(ABC):
136
137
  - headers (dict, optional): HTTP headers to include in the request.
137
138
 
138
139
  Returns:
139
- - dict: The response from the server as a dictionary.
140
+ - Response: Http response object
140
141
  """
141
142
  pass
142
143
 
@@ -1,7 +1,24 @@
1
1
  import logging
2
2
  import os
3
+ import json
3
4
 
5
+ class JSONFormatter(logging.Formatter):
6
+ """
7
+ Custom JSON formatter to structure log records as JSON.
8
+ """
4
9
 
10
+ def format(self, record):
11
+ log_record = {
12
+ "time": self.formatTime(record, self.datefmt),
13
+ "name": record.name,
14
+ "filename": record.filename,
15
+ "module": record.module,
16
+ "level": record.levelname,
17
+ "message": record.getMessage(),
18
+ }
19
+ if record.exc_info:
20
+ log_record["exception"] = self.formatException(record.exc_info)
21
+ return json.dumps(log_record)
5
22
  class Logger:
6
23
  """
7
24
  A singleton logger class that ensures only one logger instance is created.
@@ -22,7 +39,7 @@ class Logger:
22
39
  cls._instance._initialize(name=name)
23
40
  return cls._instance
24
41
 
25
- def _initialize(self, name=None, log_file: str = "fdc_app_logs.log"):
42
+ def _initialize(self, name=None, log_file: str = "fdc_app_logs.log", json_log_file: str = "fdc_app_logs.jsonl"):
26
43
 
27
44
  self.logger = logging.getLogger(name if name else __name__)
28
45
  self.logger.setLevel(logging.DEBUG)
@@ -30,6 +47,7 @@ class Logger:
30
47
  "%(asctime)s - %(name)s - %(filename)s - %(module)s - %(levelname)s - %(message)s"
31
48
  )
32
49
  self.log_file = log_file
50
+ self.json_log_file = json_log_file
33
51
 
34
52
  # ensure handlers are configured only once
35
53
  if not self.logger.handlers:
@@ -41,6 +59,7 @@ class Logger:
41
59
  """
42
60
  self.add_stream_handler()
43
61
  self.add_file_handler(log_file=self.log_file)
62
+ self.add_json_file_handler(log_file=self.json_log_file)
44
63
 
45
64
  def add_stream_handler(self):
46
65
  """
@@ -61,6 +80,17 @@ class Logger:
61
80
  file_handler.setLevel(self.logger.level)
62
81
  file_handler.setFormatter(self.formatter)
63
82
  self.logger.addHandler(file_handler)
83
+
84
+ def add_json_file_handler(self, log_file, log_directory="./logs"):
85
+ """
86
+ Adds a JSON file handler to the logger.
87
+ """
88
+ if not os.path.exists(log_directory):
89
+ os.makedirs(log_directory)
90
+ json_file_handler = logging.FileHandler(os.path.join(log_directory, log_file))
91
+ json_file_handler.setLevel(self.logger.level)
92
+ json_file_handler.setFormatter(JSONFormatter()) # Using the custom JSON formatter
93
+ self.logger.addHandler(json_file_handler)
64
94
 
65
95
  def info(self, message, *args, **kwargs):
66
96
  self.logger.info(message, *args, **kwargs)
@@ -1,6 +1,7 @@
1
1
  import asyncio
2
2
  import logging
3
3
  from typing import Callable, Any, Dict
4
+ from shared_kernel.exceptions.http_exceptions import BadRequest, InternalServerError
4
5
  from shared_kernel.interfaces import DataBus
5
6
  from concurrent.futures import ThreadPoolExecutor
6
7
  from shared_kernel.http import HttpClient
@@ -73,7 +74,20 @@ class HTTPDataBus(DataBus):
73
74
  Any: The response from the HTTP endpoint.
74
75
  """
75
76
  response = self.http_client.post(url=event_name, json=event_payload)
76
- return response
77
+
78
+ # handling success cases
79
+ if response.status_code in [200, 201, 204]:
80
+ return response.json()
81
+
82
+ # default error handling
83
+ response_data: Dict[str, Any] = response.json()
84
+ error_message: str = response_data.get('message', 'An error occurred')
85
+
86
+ # handling common HTTP errors
87
+ if response.status_code == 400:
88
+ raise BadRequest(error_message)
89
+ elif response.status_code == 500:
90
+ raise InternalServerError(error_message)
77
91
 
78
92
  def subscribe_sync_event(self, event_name: str, callback: Callable[[Any], None]):
79
93
  """