h-message-bus 0.0.39__tar.gz → 0.0.40__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 (82) hide show
  1. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/PKG-INFO +1 -1
  2. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/pyproject.toml +1 -1
  3. h_message_bus-0.0.40/src/h_message_bus/infrastructure/nats_client_repository.py +109 -0
  4. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus.egg-info/PKG-INFO +1 -1
  5. h_message_bus-0.0.39/src/h_message_bus/infrastructure/nats_client_repository.py +0 -93
  6. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/README.md +0 -0
  7. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/setup.cfg +0 -0
  8. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/__init__.py +0 -0
  9. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/__init__.py +0 -0
  10. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/adapters/__init__.py +0 -0
  11. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/adapters/nats_message_adapter.py +0 -0
  12. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/adapters/nats_publisher_adapter.py +0 -0
  13. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/adapters/nats_subscriber_adapter.py +0 -0
  14. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/application/__init__.py +0 -0
  15. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/application/message_processor.py +0 -0
  16. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/application/message_publisher.py +0 -0
  17. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/application/message_subcriber.py +0 -0
  18. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/__init__.py +0 -0
  19. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/event_messages/__init__.py +0 -0
  20. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/models/__init__.py +0 -0
  21. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/models/event_message_topic.py +0 -0
  22. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/models/hai_message.py +0 -0
  23. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/models/request_message_topic.py +0 -0
  24. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/models/twitter_message_metadata.py +0 -0
  25. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/models/twitter_user_metadata.py +0 -0
  26. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/models/vector_collection_metadata.py +0 -0
  27. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/models/vector_query_answer.py +0 -0
  28. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/__init__.py +0 -0
  29. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/graph_clear_request_message.py +0 -0
  30. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/graph_get_all_request_message.py +0 -0
  31. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/graph_get_all_result_response_message.py +0 -0
  32. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/graph_node_add_request_message.py +0 -0
  33. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/graph_node_added_response_message.py +0 -0
  34. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/graph_node_get_request_message.py +0 -0
  35. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/graph_node_get_result_response_message.py +0 -0
  36. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/graph_node_update_request_message.py +0 -0
  37. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/graph_node_update_response_message.py +0 -0
  38. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/graph_nodes_by_property_request_message.py +0 -0
  39. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/graph_nodes_by_property_response_message.py +0 -0
  40. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/graph_query_operation_request_message.py +0 -0
  41. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/graph_query_operation_response_message.py +0 -0
  42. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/graph_query_request_message.py +0 -0
  43. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/graph_relationship_added_request_message.py +0 -0
  44. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/init_knowledgebase_request.py +0 -0
  45. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/tg_message_request_message.py +0 -0
  46. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/tg_user_message_reply_request_message.py +0 -0
  47. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/tg_user_message_request_message.py +0 -0
  48. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_follow_user_request_message.py +0 -0
  49. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_follow_user_response_message.py +0 -0
  50. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_get_tweet_request_message.py +0 -0
  51. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_get_tweet_response_message.py +0 -0
  52. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_get_user_request_message.py +0 -0
  53. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_get_user_response_message.py +0 -0
  54. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_get_users_request_message.py +0 -0
  55. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_get_users_response_message.py +0 -0
  56. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_home_timeline_request_message.py +0 -0
  57. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_home_timeline_response_message.py +0 -0
  58. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_post_tweet_request_message.py +0 -0
  59. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_post_tweet_response_message.py +0 -0
  60. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_quote_retweet_request_message.py +0 -0
  61. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_quote_retweet_response_message.py +0 -0
  62. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_reply_request_message.py +0 -0
  63. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_reply_response_message.py +0 -0
  64. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_retweet_request_message.py +0 -0
  65. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_retweet_response_message.py +0 -0
  66. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_search_request_message.py +0 -0
  67. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_search_response_message.py +0 -0
  68. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_user_tweets_request_message.py +0 -0
  69. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/twitter_user_tweets_response_message.py +0 -0
  70. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/vector_query_collection_request_message.py +0 -0
  71. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/vector_query_collection_response_message.py +0 -0
  72. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/vector_read_metadata_request_message.py +0 -0
  73. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/vector_read_metadata_response_message.py +0 -0
  74. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/vector_save_request_message.py +0 -0
  75. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/web_get_docs_request_message.py +0 -0
  76. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/domain/request_messages/web_search_request_message.py +0 -0
  77. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/infrastructure/__init__.py +0 -0
  78. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus/infrastructure/nats_config.py +0 -0
  79. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus.egg-info/SOURCES.txt +0 -0
  80. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus.egg-info/dependency_links.txt +0 -0
  81. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus.egg-info/requires.txt +0 -0
  82. {h_message_bus-0.0.39 → h_message_bus-0.0.40}/src/h_message_bus.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: h_message_bus
3
- Version: 0.0.39
3
+ Version: 0.0.40
4
4
  Summary: Message bus integration for HAI
5
5
  Author-email: shoebill <shoebill.hai@gmail.com>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -4,7 +4,7 @@
4
4
 
5
5
  [project]
6
6
  name = "h_message_bus"
7
- version = "0.0.39"
7
+ version = "0.0.40"
8
8
  authors = [
9
9
  {name = "shoebill", email = "shoebill.hai@gmail.com"},
10
10
  ]
@@ -0,0 +1,109 @@
1
+ import logging
2
+ import asyncio
3
+ from typing import Optional, Callable, Any
4
+
5
+ import nats
6
+ from nats.aio.client import Client as NatsClient
7
+
8
+ from ..infrastructure.nats_config import NatsConfig
9
+
10
+ class NatsClientRepository:
11
+ """
12
+ Repository for managing connection and interaction with a NATS server.
13
+ """
14
+
15
+ def __init__(self, config: NatsConfig):
16
+ self.config = config
17
+ self.client: Optional[NatsClient] = None
18
+ self.subscriptions = []
19
+ self.logger = logging.getLogger(__name__)
20
+
21
+ async def connect(self) -> None:
22
+ """Connect to NATS server with event handlers and logging."""
23
+ if self.client and self.client.is_connected:
24
+ return
25
+
26
+ async def error_cb(e):
27
+ self.logger.error(f"NATS client error: {e}")
28
+
29
+ async def disconnect_cb():
30
+ self.logger.warning("NATS client disconnected.")
31
+
32
+ async def reconnect_cb():
33
+ self.logger.info("NATS client reconnected.")
34
+
35
+ async def closed_cb():
36
+ self.logger.warning("NATS client connection closed.")
37
+
38
+ self.logger.info(f"Connecting to NATS server at {self.config.server}")
39
+
40
+ self.client = await nats.connect(
41
+ servers=self.config.server,
42
+ max_reconnect_attempts=self.config.max_reconnect_attempts,
43
+ reconnect_time_wait=self.config.reconnect_time_wait,
44
+ connect_timeout=self.config.connection_timeout,
45
+ ping_interval=self.config.ping_interval,
46
+ max_outstanding_pings=self.config.max_outstanding_pings,
47
+ error_cb=error_cb,
48
+ disconnected_cb=disconnect_cb,
49
+ reconnected_cb=reconnect_cb,
50
+ closed_cb=closed_cb,
51
+ ) # type: ignore
52
+
53
+ async def _ensure_connected(self, retries: int = 5):
54
+ """Wait and retry until the client is connected."""
55
+ for attempt in range(retries):
56
+ if self.client and self.client.is_connected:
57
+ return
58
+ self.logger.info(f"Waiting for NATS connection (attempt {attempt+1})...")
59
+ await asyncio.sleep(2 ** attempt)
60
+ raise ConnectionError("Could not establish connection to NATS server.")
61
+
62
+ async def publish(self, subject: str, payload: bytes, retries: int = 3) -> None:
63
+ """Publish raw message to NATS with retries and backoff."""
64
+ for attempt in range(retries):
65
+ try:
66
+ await self._ensure_connected()
67
+ await self.client.publish(subject, payload)
68
+ return
69
+ except Exception as e:
70
+ self.logger.error(f"Failed to publish message (attempt {attempt+1}): {e}")
71
+ await asyncio.sleep(2 ** attempt)
72
+ self.logger.error("Giving up publishing after retries.")
73
+
74
+ async def subscribe(self, subject: str, callback: Callable) -> Any:
75
+ """Subscribe to a subject with a callback."""
76
+ await self._ensure_connected()
77
+ try:
78
+ subscription = await self.client.subscribe(subject, cb=callback)
79
+ self.subscriptions.append(subscription)
80
+ return subscription
81
+ except Exception as e:
82
+ self.logger.error(f"Failed to subscribe to {subject}: {e}")
83
+ return None
84
+
85
+ async def request(self, subject: str, payload: bytes, timeout: float = 2.0, retries: int = 3) -> Optional[bytes]:
86
+ """Send a request and get raw response with retries and backoff."""
87
+ for attempt in range(retries):
88
+ try:
89
+ await self._ensure_connected()
90
+ response = await self.client.request(subject, payload, timeout=timeout)
91
+ return response.data
92
+ except Exception as e:
93
+ self.logger.error(f"NATS request failed (attempt {attempt+1}): {e}")
94
+ await asyncio.sleep(2 ** attempt)
95
+ self.logger.error("Giving up request after retries.")
96
+ return None
97
+
98
+ async def close(self) -> None:
99
+ """Close all subscriptions and NATS connection."""
100
+ if self.client and self.client.is_connected:
101
+ try:
102
+ for sub in self.subscriptions:
103
+ await sub.unsubscribe()
104
+ await self.client.drain()
105
+ except Exception as e:
106
+ self.logger.error(f"Error during NATS cleanup: {e}")
107
+ finally:
108
+ self.client = None
109
+ self.subscriptions = []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: h_message_bus
3
- Version: 0.0.39
3
+ Version: 0.0.40
4
4
  Summary: Message bus integration for HAI
5
5
  Author-email: shoebill <shoebill.hai@gmail.com>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -1,93 +0,0 @@
1
- import logging
2
- from typing import Optional, Callable, Any
3
-
4
- import nats
5
- from nats.aio.client import Client as NatsClient
6
-
7
- from ..infrastructure.nats_config import NatsConfig
8
-
9
-
10
- class NatsClientRepository:
11
- """
12
- Repository for managing connection and interaction with a NATS server.
13
-
14
- This class provides methods to establish a connection with a NATS server,
15
- publish and subscribe to subjects, send requests and handle responses, and
16
- cleanly disconnect from the server. It abstracts the connection and ensures
17
- seamless communication with the NATS server.
18
-
19
- :ivar config: Configuration details for the NATS client, including server
20
- connection parameters, timeouts, and limits.
21
- :type config: NatsConfig
22
- :ivar client: Instance of the NATS client used for communication. Initialized
23
- as None and assigned upon connecting to a NATS server.
24
- :type client: Optional[NatsClient]
25
- :ivar subscriptions: List of active subscriptions for NATS subjects.
26
- :type subscriptions: list
27
- """
28
-
29
- def __init__(self, config: NatsConfig):
30
- self.config = config
31
- self.client: NatsClient | None = None
32
-
33
- self.subscriptions = []
34
- self.logger = logging.getLogger(__name__)
35
-
36
- async def connect(self) -> None:
37
- """Connect to NATS server."""
38
- if self.client and self.client.is_connected:
39
- return
40
- self.logger.info(f"Connecting to NATS server at {self.config.server}")
41
-
42
- self.client = await nats.connect(
43
- servers=self.config.server,
44
- max_reconnect_attempts=self.config.max_reconnect_attempts,
45
- reconnect_time_wait=self.config.reconnect_time_wait,
46
- connect_timeout=self.config.connection_timeout,
47
- ping_interval=self.config.ping_interval,
48
- max_outstanding_pings=self.config.max_outstanding_pings
49
- ) #ignore client type warning
50
-
51
- async def publish(self, subject: str, payload: bytes) -> None:
52
- """Publish raw message to NATS."""
53
- if not self.client or not self.client.is_connected:
54
- await self.connect()
55
-
56
- try:
57
- await self.client.publish(subject, payload)
58
- except Exception as e:
59
- print(f"Failed to publish message: {e}")
60
- return
61
-
62
- async def subscribe(self, subject: str, callback: Callable) -> Any:
63
- """Subscribe to a subject with a callback."""
64
- if not self.client or not self.client.is_connected:
65
- await self.connect()
66
-
67
- subscription = await self.client.subscribe(subject, cb=callback)
68
- self.subscriptions.append(subscription)
69
- return subscription
70
-
71
- async def request(self, subject: str, payload: bytes, timeout: float = 2.0) -> Optional[bytes]:
72
- """Send a request and get raw response."""
73
- if not self.client or not self.client.is_connected:
74
- await self.connect()
75
-
76
- try:
77
- response = await self.client.request(subject, payload, timeout=timeout)
78
- return response.data
79
- except Exception as e:
80
- print(f"NATS request failed: {e}")
81
- return None
82
-
83
- async def close(self) -> None:
84
- """Close all subscriptions and NATS connection."""
85
- if self.client and self.client.is_connected:
86
- # Unsubscribe from all subscriptions
87
- for sub in self.subscriptions:
88
- await sub.unsubscribe()
89
-
90
- # Drain and close connection
91
- await self.client.drain()
92
- self.client = None
93
- self.subscriptions = []
File without changes
File without changes