fdc-shared-kernel 0.0.72__tar.gz → 0.0.74__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 (79) hide show
  1. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/PKG-INFO +1 -1
  2. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/fdc_shared_kernel.egg-info/PKG-INFO +1 -1
  3. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/pyproject.toml +1 -1
  4. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/event_executor/event_executor.py +52 -5
  5. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/logger/__init__.py +2 -1
  6. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/messaging/aws_databus.py +2 -0
  7. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/messaging/utils/event_messages.py +3 -0
  8. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/registries/service_event_registry.py +2 -2
  9. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/status_tracker/status_tracker.py +13 -6
  10. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/README.md +0 -0
  11. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/README_pypi.md +0 -0
  12. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/fdc_shared_kernel.egg-info/SOURCES.txt +0 -0
  13. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/fdc_shared_kernel.egg-info/dependency_links.txt +0 -0
  14. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/fdc_shared_kernel.egg-info/requires.txt +0 -0
  15. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/fdc_shared_kernel.egg-info/top_level.txt +0 -0
  16. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/requirements.txt +0 -0
  17. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/setup.cfg +0 -0
  18. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/__init__.py +0 -0
  19. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/async_task_executor/__init__.py +0 -0
  20. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/async_task_executor/async_task_executor.py +0 -0
  21. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/auth/__init__.py +0 -0
  22. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/auth/jwt_helper.py +0 -0
  23. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/auth/token_handler.py +0 -0
  24. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/config/__init__.py +0 -0
  25. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/database/__init__.py +0 -0
  26. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/enums/__init__.py +0 -0
  27. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/enums/async_task_executor.py +0 -0
  28. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/enums/status_tracker.py +0 -0
  29. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/event_executor/__init__.py +0 -0
  30. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/event_executor/utils.py +0 -0
  31. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/exceptions/__init__.py +0 -0
  32. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/exceptions/configuration_exceptions.py +0 -0
  33. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/exceptions/custom_exceptions.py +0 -0
  34. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/exceptions/data_validation_exceptions.py +0 -0
  35. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/exceptions/http_exceptions.py +0 -0
  36. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/exceptions/infrastructure_exceptions.py +0 -0
  37. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/exceptions/operational_exceptions.py +0 -0
  38. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/exceptions/security_exceptions.py +0 -0
  39. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/http/__init__.py +0 -0
  40. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/http/httpx_http_client.py +0 -0
  41. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/http/request_http_client.py +0 -0
  42. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/interfaces/__init__.py +0 -0
  43. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/interfaces/databus.py +0 -0
  44. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/interfaces/http.py +0 -0
  45. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/interfaces/keyvault.py +0 -0
  46. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/messaging/__init__.py +0 -0
  47. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/messaging/http_databus.py +0 -0
  48. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/messaging/nats_databus.py +0 -0
  49. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/messaging/nats_publisher.py +0 -0
  50. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/messaging/nats_test.py +0 -0
  51. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/messaging/utils/aws_utility.py +0 -0
  52. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/metrics/__init__.py +0 -0
  53. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/metrics/status_tracker.py +0 -0
  54. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/models/__init__.py +0 -0
  55. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/registries/__init__.py +0 -0
  56. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/security/__init__.py +0 -0
  57. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/security/key_vault/__init__.py +0 -0
  58. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/security/key_vault/aws_secret_manager.py +0 -0
  59. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/security/key_vault/azure_keyvault.py +0 -0
  60. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/status_tracker/__init__.py +0 -0
  61. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/tests/__init__.py +0 -0
  62. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/tests/config/__init__.py +0 -0
  63. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/tests/config/test_config.py +0 -0
  64. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/tests/logger/__init__.py +0 -0
  65. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/tests/logger/test_logger.py +0 -0
  66. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/tests/messaging/__init__.py +0 -0
  67. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/tests/messaging/test_aws_databus.py +0 -0
  68. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/tests/messaging/test_event_executor.py +0 -0
  69. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/tests/messaging/test_nats_interface.py +0 -0
  70. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/tests/utils/__init__.py +0 -0
  71. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/tests/utils/test_data_validators.py +0 -0
  72. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/tests/utils/test_date_format_utils.py +0 -0
  73. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/tests/utils/test_string_utils.py +0 -0
  74. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/utils/__init__.py +0 -0
  75. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/utils/data_validators_utils.py +0 -0
  76. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/utils/date_format_utils.py +0 -0
  77. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/utils/string_utils.py +0 -0
  78. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/utils/template_renderer.py +0 -0
  79. {fdc_shared_kernel-0.0.72 → fdc_shared_kernel-0.0.74}/shared_kernel/utils/thread_local_util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fdc_shared_kernel
3
- Version: 0.0.72
3
+ Version: 0.0.74
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.72
3
+ Version: 0.0.74
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.72"
7
+ version = "0.0.74"
8
8
  requires-python = ">=3.7"
9
9
  readme = "README_pypi.md"
10
10
  description = "Shared library for microservice"
@@ -1,8 +1,10 @@
1
1
  import json
2
2
  import threading
3
- from concurrent.futures import ThreadPoolExecutor, Future
3
+ from concurrent.futures import Future
4
4
  from typing import Any, Callable, Dict, Optional
5
5
  from threading import Semaphore
6
+ import os
7
+ from typing import Tuple
6
8
 
7
9
  from shared_kernel.config import Config
8
10
  from shared_kernel.event_executor.utils import EventConcurrencyManager, EventStats
@@ -85,10 +87,14 @@ class EventExecutor:
85
87
  logger.info(
86
88
  f"Processing event {event_msg.event_name}. trace-id: {event_msg.event_meta.trace_id}. span-id: {event_msg.event_meta.trace_id}."
87
89
  )
88
- task: dict = self.status_tracker.get_task(
89
- task=event_msg.event_name, task_id=event_msg.event_meta.job_id
90
- )
91
90
 
91
+ task_details = self.status_tracker.get_task(task_details = event_msg)
92
+ if task_details is not None and task_details["is_duplicate"]:
93
+ logger.info(
94
+ f"Duplicate task {event_msg.event_name} is already in progress. trace-id: {event_msg.event_meta.trace_id}. span-id: {event_msg.event_meta.trace_id}."
95
+ )
96
+ return
97
+ task = task_details.get("task_details") if task_details is not None else None
92
98
  if task is None:
93
99
  logger.info(
94
100
  f"Creating new task for event {event_msg.event_name}. trace-id: {event_msg.event_meta.trace_id}. span-id: {event_msg.event_meta.trace_id}."
@@ -99,6 +105,8 @@ class EventExecutor:
99
105
  task=event_msg.event_name,
100
106
  status=TaskStatus.PROCESSING.value,
101
107
  task_id=event_msg.event_meta.job_id,
108
+ org_id=event_msg.event_meta.org_id,
109
+ entity_id=event_msg.event_meta.entity_id,
102
110
  )
103
111
 
104
112
  # setting tracking payload without the time taken and end time
@@ -302,6 +310,41 @@ class EventExecutor:
302
310
  logger.error(f"Error in event listener for {event_name}: {str(e)}")
303
311
  logger.info(f"Event listener for {event_name} has been stopped.")
304
312
 
313
+ # TODO: enable caching here
314
+ def _load_event_schema_and_description(self, event_name: str) -> Tuple[dict, str]:
315
+ """
316
+ Load event schema and description.
317
+
318
+ Args:
319
+ event_name: Name of the event
320
+
321
+ Returns:
322
+ A tuple containing:
323
+ - schema: Parsed JSON schema for the event.
324
+ - description: Text description for the event.
325
+ """
326
+ schema_path = os.path.join('src', 'infrastructure', 'event_details', f"{event_name.lower()}", 'schema.json')
327
+ description_path = os.path.join('src', 'infrastructure', 'event_details', f"{event_name.lower()}", 'description.txt')
328
+
329
+ if not os.path.exists(schema_path):
330
+ logger.error(f"Schema file missing for event {event_name}: {schema_path}")
331
+ raise Exception(f"Schema file missing for event {event_name}: {schema_path}")
332
+ if not os.path.exists(description_path):
333
+ logger.error(f"Description file missing for event {event_name}: {description_path}")
334
+ raise Exception(f"Description file missing for event {event_name}: {description_path}")
335
+
336
+ try:
337
+ with open(schema_path, 'r') as schema_file:
338
+ schema = json.load(schema_file)
339
+ with open(description_path, 'r') as description_file:
340
+ description = description_file.read().strip()
341
+
342
+ return schema, description
343
+
344
+ except json.JSONDecodeError:
345
+ logger.error(f"Invalid JSON schema for event {event_name}")
346
+ raise Exception(f"Invalid JSON schema for event {event_name}")
347
+
305
348
  def get_all_stats(self) -> dict:
306
349
  """
307
350
  Get comprehensive statistics for all registered events.
@@ -316,6 +359,8 @@ class EventExecutor:
316
359
 
317
360
  with self._stats_lock:
318
361
  event_stats = self._stats.get(event_name, EventStats())
362
+
363
+ event_schema, event_description = self._load_event_schema_and_description(event_name)
319
364
 
320
365
  all_stats[event_name] = {
321
366
  "workers": {
@@ -327,7 +372,9 @@ class EventExecutor:
327
372
  "successful": event_stats.successful_events,
328
373
  "failed": event_stats.failed_events,
329
374
  "total": event_stats.total_events
330
- }
375
+ },
376
+ "schema": event_schema,
377
+ "description": event_description,
331
378
  }
332
379
 
333
380
  return all_stats
@@ -33,7 +33,8 @@ class JSONFormatter(logging.Formatter):
33
33
  if hasattr(record, 'meta_data'):
34
34
  log_record.update(record.meta_data)
35
35
  if record.exc_info:
36
- log_record["exception"] = self.formatException(record.exc_info)
36
+ log_record["stack_trace"] = self.formatException(record.exc_info)
37
+ log_record["exception"] = str(record.exc_info[1])
37
38
  return json.dumps(log_record)
38
39
  class Logger:
39
40
  """
@@ -70,6 +70,8 @@ class AWSDataBus(DataBus):
70
70
  task=validated_event_dict["event_name"],
71
71
  status=TaskStatus.QUEUED.value,
72
72
  task_id=validated_event_dict["event_meta"]["job_id"],
73
+ org_id=validated_event_dict["event_meta"]["org_id"],
74
+ entity_id=validated_event_dict["event_meta"].get("entity_id", None),
73
75
  )
74
76
 
75
77
  self.status_tracker.set_event_meta_and_message_receipt_handle(
@@ -19,6 +19,9 @@ class EventMeta:
19
19
  self.trace_id: str = meta_data.get("trace_id")
20
20
  self.job_id: str = meta_data.get("job_id")
21
21
  self.trigger = meta_data.get("trigger")
22
+ self.org_id = meta_data.get("org_id")
23
+ # entity_id is an optional field as some events may not be associated with an entity
24
+ self.entity_id = meta_data.get("entity_id", None)
22
25
  # generate a new span_id for each event if not present already
23
26
  self.span_id: str = meta_data.get("span_id", str(uuid.uuid4()))
24
27
 
@@ -20,9 +20,9 @@ class ServiceEventRegistry:
20
20
  + "/event/subscribe-sync-event/MARK_TASK_AS_FAILURE/"
21
21
  )
22
22
 
23
- GET_TASK = (
23
+ PROCESS_TASK = (
24
24
  config.get("MASTER_SERVICE_BASE_ENDPOINT")
25
- + "/event/subscribe-sync-event/GET_TASK/"
25
+ + "/event/subscribe-sync-event/PROCESS_TASK/"
26
26
  )
27
27
 
28
28
  GET_IN_PROGRESS_TASK = (
@@ -1,6 +1,7 @@
1
1
  from shared_kernel.exceptions.custom_exceptions import StatusTrackerException
2
2
  from shared_kernel.interfaces.databus import DataBus
3
3
  from shared_kernel.messaging import DataBusFactory
4
+ from shared_kernel.messaging.utils.event_messages import EventMessage
4
5
  from shared_kernel.registries.service_event_registry import ServiceEventRegistry
5
6
 
6
7
  service_event_registry = ServiceEventRegistry()
@@ -32,7 +33,7 @@ class StatusTracker:
32
33
  )
33
34
 
34
35
 
35
- def create_task(self, span_id, trace_id, task, status, task_id):
36
+ def create_task(self, span_id, trace_id, task, status, task_id, org_id, entity_id=None):
36
37
  """Publishes a synchronous event to create a task"""
37
38
  try:
38
39
  payload = {
@@ -41,7 +42,10 @@ class StatusTracker:
41
42
  "task": task,
42
43
  "status": status,
43
44
  "task_id": task_id,
45
+ "org_id": org_id,
44
46
  }
47
+ if entity_id:
48
+ payload["entity_id"] = entity_id
45
49
  response = self.databus.request_event(
46
50
  getattr(service_event_registry, "CREATE_TASK"), payload
47
51
  )
@@ -89,15 +93,19 @@ class StatusTracker:
89
93
  raise StatusTrackerException(e)
90
94
 
91
95
 
92
- def get_task(self, task, task_id):
96
+ def get_task(self, task_details: EventMessage):
93
97
  """Publishes a synchronous event to retrieve a task"""
94
98
  try:
95
99
  payload = {
96
- "task": task,
97
- "task_id": task_id,
100
+ "task": task_details.event_name,
101
+ "task_id": task_details.event_meta.job_id,
102
+ "entity_id": task_details.event_meta.entity_id if task_details.event_meta.entity_id else None,
103
+ "trace_id": task_details.event_meta.trace_id,
104
+ "span_id": task_details.event_meta.span_id,
105
+ "org_id": task_details.event_meta.org_id,
98
106
  }
99
107
  response: dict = self.databus.request_event(
100
- getattr(service_event_registry, "GET_TASK"), payload
108
+ getattr(service_event_registry, "PROCESS_TASK"), payload
101
109
  )
102
110
  return response.get("data")
103
111
 
@@ -155,4 +163,3 @@ class StatusTracker:
155
163
 
156
164
  except Exception as e:
157
165
  raise StatusTrackerException(e)
158
-