aury-boot 0.0.22__py3-none-any.whl → 0.0.24__py3-none-any.whl

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.
aury/boot/_version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.0.22'
32
- __version_tuple__ = version_tuple = (0, 0, 22)
31
+ __version__ = version = '0.0.24'
32
+ __version_tuple__ = version_tuple = (0, 0, 24)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -20,10 +20,7 @@ notification_channel = ChannelManager.get_instance("notification")
20
20
  await sse_channel.initialize(backend="memory")
21
21
 
22
22
  # Redis 后端(多进程/分布式)
23
- from aury.boot.infrastructure.clients.redis import RedisClient
24
- redis_client = RedisClient.get_instance()
25
- await redis_client.initialize(url="redis://localhost:6379/0")
26
- await notification_channel.initialize(backend="redis", redis_client=redis_client)
23
+ await notification_channel.initialize(backend="redis", url="redis://localhost:6379/0")
27
24
  ```
28
25
 
29
26
  ## 13.2 发布和订阅(Topic 管理)
@@ -71,12 +68,51 @@ async def sse_stream(user_id: str):
71
68
 
72
69
  @router.post("/notify/{{user_id}}")
73
70
  async def send_notification(user_id: str, message: str):
74
- \"\"\"\u53d1\u9001\u901a\u77e5\u3002\"\"\"
71
+ \"\"\"发送通知。\"\"\"
75
72
  await sse_channel.publish(f"user:{{user_id}}", {{"message": message}})
76
73
  return {{"status": "sent"}}
77
74
  ```
78
75
 
79
- ## 13.4 应用场景示例
76
+ ## 13.4 模式订阅(psubscribe)
77
+
78
+ 使用通配符订阅多个通道,适合一个 SSE 连接接收多种事件的场景。
79
+
80
+ ```python
81
+ @router.get("/spaces/{{space_id}}/events")
82
+ async def space_events(space_id: str):
83
+ \"\"\"订阅空间下所有事件。\"\"\"
84
+ async def event_generator():
85
+ # 使用 psubscribe 订阅 space:{id}:* 下所有事件
86
+ async for msg in sse_channel.psubscribe(f"space:{{space_id}}:*"):
87
+ yield msg.to_sse() # 自动转换为 SSE 格式
88
+
89
+ return StreamingResponse(
90
+ event_generator(),
91
+ media_type="text/event-stream"
92
+ )
93
+
94
+
95
+ # 后端发布不同类型的事件
96
+ await sse_channel.publish(f"space:{{space_id}}:file_analyzed", {{
97
+ "file_id": "abc",
98
+ "status": "done"
99
+ }}, event="file_analyzed")
100
+
101
+ await sse_channel.publish(f"space:{{space_id}}:comment_added", {{
102
+ "comment_id": "xyz",
103
+ "content": "..."
104
+ }}, event="comment_added")
105
+ ```
106
+
107
+ **通配符说明**:
108
+ - `*` 匹配任意字符
109
+ - `?` 匹配单个字符
110
+ - `[seq]` 匹配 seq 中的任意字符
111
+ - 示例:`space:123:*` 匹配 `space:123:file_analyzed`、`space:123:comment_added` 等
112
+
113
+ Redis 后端使用 Redis 原生 `PSUBSCRIBE`,内存后端使用 `fnmatch` 实现。
114
+
115
+ ## 13.5 应用场景示例
80
116
 
81
117
  ```python
82
118
  # 不同业务场景使用不同的命名实例
@@ -86,11 +122,11 @@ notify_channel = ChannelManager.get_instance("notify") # 系统通知
86
122
 
87
123
  # 分别初始化(可使用不同后端)
88
124
  await sse_channel.initialize(backend="memory") # 单进程即可
89
- await chat_channel.initialize(backend="redis", redis_client=redis_client) # 需要跨进程
90
- await notify_channel.initialize(backend="redis", redis_client=redis_client)
125
+ await chat_channel.initialize(backend="redis", url="redis://localhost:6379/3") # 需要跨进程
126
+ await notify_channel.initialize(backend="redis", url="redis://localhost:6379/4")
91
127
  ```
92
128
 
93
- ## 13.5 环境变量
129
+ ## 13.6 环境变量
94
130
 
95
131
  ```bash
96
132
  # 默认实例
@@ -8,6 +8,7 @@ from __future__ import annotations
8
8
  import asyncio
9
9
  from collections.abc import AsyncIterator
10
10
  import contextlib
11
+ import fnmatch
11
12
 
12
13
  from aury.boot.common.logging import logger
13
14
 
@@ -31,12 +32,15 @@ class MemoryChannel(IChannel):
31
32
  self._max_subscribers = max_subscribers
32
33
  # channel -> list of queues
33
34
  self._subscribers: dict[str, list[asyncio.Queue[ChannelMessage]]] = {}
35
+ # pattern -> list of queues (用于 psubscribe)
36
+ self._pattern_subscribers: dict[str, list[asyncio.Queue[ChannelMessage]]] = {}
34
37
  self._lock = asyncio.Lock()
35
38
 
36
39
  async def publish(self, channel: str, message: ChannelMessage) -> None:
37
40
  """发布消息到通道。"""
38
41
  message.channel = channel
39
42
  async with self._lock:
43
+ # 精确匹配订阅者
40
44
  subscribers = self._subscribers.get(channel, [])
41
45
  for queue in subscribers:
42
46
  try:
@@ -44,6 +48,15 @@ class MemoryChannel(IChannel):
44
48
  except asyncio.QueueFull:
45
49
  logger.warning(f"通道 [{channel}] 订阅者队列已满,消息被丢弃")
46
50
 
51
+ # 模式匹配订阅者
52
+ for pattern, queues in self._pattern_subscribers.items():
53
+ if fnmatch.fnmatch(channel, pattern):
54
+ for queue in queues:
55
+ try:
56
+ queue.put_nowait(message)
57
+ except asyncio.QueueFull:
58
+ logger.warning(f"模式 [{pattern}] 订阅者队列已满,消息被丢弃")
59
+
47
60
  async def subscribe(self, channel: str) -> AsyncIterator[ChannelMessage]:
48
61
  """订阅通道。"""
49
62
  queue: asyncio.Queue[ChannelMessage] = asyncio.Queue(maxsize=100)
@@ -67,6 +80,35 @@ class MemoryChannel(IChannel):
67
80
  if not self._subscribers[channel]:
68
81
  del self._subscribers[channel]
69
82
 
83
+ async def psubscribe(self, pattern: str) -> AsyncIterator[ChannelMessage]:
84
+ """模式订阅通道。
85
+
86
+ 使用 fnmatch 风格的通配符:
87
+ - `*` 匹配任意字符
88
+ - `?` 匹配单个字符
89
+ - `[seq]` 匹配 seq 中的任意字符
90
+ """
91
+ queue: asyncio.Queue[ChannelMessage] = asyncio.Queue(maxsize=100)
92
+
93
+ async with self._lock:
94
+ if pattern not in self._pattern_subscribers:
95
+ self._pattern_subscribers[pattern] = []
96
+ if len(self._pattern_subscribers[pattern]) >= self._max_subscribers:
97
+ raise RuntimeError(f"模式 [{pattern}] 订阅者数量已达上限")
98
+ self._pattern_subscribers[pattern].append(queue)
99
+
100
+ try:
101
+ while True:
102
+ message = await queue.get()
103
+ yield message
104
+ finally:
105
+ async with self._lock:
106
+ if pattern in self._pattern_subscribers:
107
+ with contextlib.suppress(ValueError):
108
+ self._pattern_subscribers[pattern].remove(queue)
109
+ if not self._pattern_subscribers[pattern]:
110
+ del self._pattern_subscribers[pattern]
111
+
70
112
  async def unsubscribe(self, channel: str) -> None:
71
113
  """取消订阅通道(清除所有订阅者)。"""
72
114
  async with self._lock:
@@ -77,6 +119,7 @@ class MemoryChannel(IChannel):
77
119
  """关闭通道,清理所有订阅。"""
78
120
  async with self._lock:
79
121
  self._subscribers.clear()
122
+ self._pattern_subscribers.clear()
80
123
  logger.debug("内存通道已关闭")
81
124
 
82
125
 
@@ -72,6 +72,48 @@ class RedisChannel(IChannel):
72
72
  await pubsub.unsubscribe(channel)
73
73
  await pubsub.close()
74
74
 
75
+ async def psubscribe(self, pattern: str) -> AsyncIterator[ChannelMessage]:
76
+ """模式订阅(通配符)。
77
+
78
+ Args:
79
+ pattern: 通道模式,支持 * 和 ? 通配符
80
+ - * 匹配任意字符
81
+ - ? 匹配单个字符
82
+ - 示例: "space:123:*" 订阅 space:123 下所有事件
83
+
84
+ Yields:
85
+ ChannelMessage: 接收到的消息
86
+ """
87
+ pubsub = self._client.connection.pubsub()
88
+ await pubsub.psubscribe(pattern)
89
+
90
+ try:
91
+ async for raw_message in pubsub.listen():
92
+ # psubscribe 的消息类型是 "pmessage"
93
+ if raw_message["type"] == "pmessage":
94
+ try:
95
+ data = json.loads(raw_message["data"])
96
+ # pmessage 包含实际匹配的通道名
97
+ actual_channel = raw_message.get("channel")
98
+ if isinstance(actual_channel, bytes):
99
+ actual_channel = actual_channel.decode("utf-8")
100
+
101
+ message = ChannelMessage(
102
+ data=data.get("data"),
103
+ event=data.get("event"),
104
+ id=data.get("id"),
105
+ channel=actual_channel or data.get("channel"),
106
+ timestamp=datetime.fromisoformat(data["timestamp"])
107
+ if data.get("timestamp")
108
+ else datetime.now(),
109
+ )
110
+ yield message
111
+ except (json.JSONDecodeError, KeyError) as e:
112
+ logger.warning(f"解析通道消息失败: {e}")
113
+ finally:
114
+ await pubsub.punsubscribe(pattern)
115
+ await pubsub.close()
116
+
75
117
  async def unsubscribe(self, channel: str) -> None:
76
118
  """取消订阅通道。"""
77
119
  if self._pubsub:
@@ -70,6 +70,21 @@ class IChannel(ABC):
70
70
  """
71
71
  ...
72
72
 
73
+ async def psubscribe(self, pattern: str) -> AsyncIterator[ChannelMessage]:
74
+ """模式订阅(通配符)。
75
+
76
+ Args:
77
+ pattern: 通道模式,如 "space:123:*" 订阅 space:123 下所有事件
78
+
79
+ Yields:
80
+ ChannelMessage: 接收到的消息
81
+
82
+ 注意:内存后端默认回退到普通 subscribe,Redis 后端支持真正的模式匹配。
83
+ """
84
+ # 默认实现:回退到普通订阅(子类可覆盖)
85
+ async for msg in self.subscribe(pattern):
86
+ yield msg
87
+
73
88
  @abstractmethod
74
89
  async def unsubscribe(self, channel: str) -> None:
75
90
  """取消订阅通道。
@@ -6,7 +6,6 @@
6
6
  from __future__ import annotations
7
7
 
8
8
  from collections.abc import AsyncIterator
9
- from typing import TYPE_CHECKING
10
9
 
11
10
  from aury.boot.common.logging import logger
12
11
 
@@ -14,9 +13,6 @@ from .backends.memory import MemoryChannel
14
13
  from .backends.redis import RedisChannel
15
14
  from .base import ChannelBackend, ChannelMessage, IChannel
16
15
 
17
- if TYPE_CHECKING:
18
- from aury.boot.infrastructure.clients.redis import RedisClient
19
-
20
16
 
21
17
  class ChannelManager:
22
18
  """通道管理器(命名多实例)。
@@ -55,6 +51,8 @@ class ChannelManager:
55
51
  self._backend: IChannel | None = None
56
52
  self._backend_type: ChannelBackend | None = None
57
53
  self._initialized: bool = False
54
+ self._redis_client = None
55
+ self._url: str | None = None
58
56
 
59
57
  @classmethod
60
58
  def get_instance(cls, name: str = "default") -> ChannelManager:
@@ -88,14 +86,14 @@ class ChannelManager:
88
86
  self,
89
87
  backend: ChannelBackend | str = ChannelBackend.MEMORY,
90
88
  *,
91
- redis_client: RedisClient | None = None,
89
+ url: str | None = None,
92
90
  max_subscribers: int = 1000,
93
91
  ) -> ChannelManager:
94
92
  """初始化通道(链式调用)。
95
93
 
96
94
  Args:
97
95
  backend: 后端类型
98
- redis_client: Redis 客户端(当 backend=redis 时需要)
96
+ url: Redis 连接 URL(当 backend=redis 时需要)
99
97
  max_subscribers: 内存后端的最大订阅者数量
100
98
 
101
99
  Returns:
@@ -110,13 +108,19 @@ class ChannelManager:
110
108
  backend = ChannelBackend(backend.lower())
111
109
 
112
110
  self._backend_type = backend
111
+ self._url = url
113
112
 
114
113
  if backend == ChannelBackend.MEMORY:
115
114
  self._backend = MemoryChannel(max_subscribers=max_subscribers)
116
115
  elif backend == ChannelBackend.REDIS:
117
- if redis_client is None:
118
- raise ValueError("Redis 通道需要提供 redis_client 参数")
119
- self._backend = RedisChannel(redis_client)
116
+ if url is None:
117
+ raise ValueError("Redis 通道需要提供 url 参数")
118
+ # 内部创建 RedisClient
119
+ from aury.boot.infrastructure.clients.redis import RedisClient
120
+
121
+ self._redis_client = RedisClient()
122
+ await self._redis_client.configure(url=url).initialize()
123
+ self._backend = RedisChannel(self._redis_client)
120
124
  else:
121
125
  raise ValueError(f"不支持的通道后端: {backend}")
122
126
 
@@ -178,6 +182,29 @@ class ChannelManager:
178
182
  async for message in self.backend.subscribe(channel):
179
183
  yield message
180
184
 
185
+ async def psubscribe(self, pattern: str) -> AsyncIterator[ChannelMessage]:
186
+ """模式订阅(通配符)。
187
+
188
+ Args:
189
+ pattern: 通道模式,支持 * 和 ? 通配符
190
+ - "space:123:*" 订阅 space:123 下所有事件
191
+ - "user:*:notification" 订阅所有用户的通知
192
+
193
+ Yields:
194
+ ChannelMessage: 接收到的消息
195
+
196
+ 示例:
197
+ # SSE 路由中订阅某个空间的所有事件
198
+ async for msg in channel.psubscribe(f"space:{{space_id}}:*"):
199
+ yield msg.to_sse()
200
+
201
+ # 发布不同类型的事件
202
+ await channel.publish(f"space:{{space_id}}:file_analyzed", {{...}})
203
+ await channel.publish(f"space:{{space_id}}:comment_added", {{...}})
204
+ """
205
+ async for message in self.backend.psubscribe(pattern):
206
+ yield message
207
+
181
208
  async def unsubscribe(self, channel: str) -> None:
182
209
  """取消订阅通道。
183
210
 
@@ -191,8 +218,11 @@ class ChannelManager:
191
218
  if self._backend:
192
219
  await self._backend.close()
193
220
  self._backend = None
194
- self._initialized = False
195
- logger.info(f"通道管理器 [{self.name}] 已关闭")
221
+ if self._redis_client:
222
+ await self._redis_client.cleanup()
223
+ self._redis_client = None
224
+ self._initialized = False
225
+ logger.info(f"通道管理器 [{self.name}] 已关闭")
196
226
 
197
227
  def __repr__(self) -> str:
198
228
  """字符串表示。"""
@@ -17,10 +17,17 @@ if TYPE_CHECKING:
17
17
  from aury.boot.infrastructure.clients.redis import RedisClient
18
18
 
19
19
 
20
+ # 框架默认前缀
21
+ DEFAULT_CHANNEL_PREFIX = "aury:event:"
22
+
23
+
20
24
  class RedisEventBus(IEventBus):
21
25
  """Redis 事件总线实现。
22
26
 
23
27
  使用 Redis Pub/Sub 实现跨进程的事件发布/订阅。
28
+
29
+ 频道命名格式:{channel_prefix}{event_name}
30
+ 默认:aury:event:user.created
24
31
  """
25
32
 
26
33
  def __init__(
@@ -28,14 +35,14 @@ class RedisEventBus(IEventBus):
28
35
  url: str | None = None,
29
36
  *,
30
37
  redis_client: RedisClient | None = None,
31
- channel_prefix: str = "events:",
38
+ channel_prefix: str = DEFAULT_CHANNEL_PREFIX,
32
39
  ) -> None:
33
40
  """初始化 Redis 事件总线。
34
41
 
35
42
  Args:
36
43
  url: Redis 连接 URL(当 redis_client 为 None 时必须提供)
37
44
  redis_client: RedisClient 实例(可选,优先使用)
38
- channel_prefix: 频道名称前缀
45
+ channel_prefix: 频道名称前缀,默认 "aury:event:"
39
46
 
40
47
  Raises:
41
48
  ValueError: 当 url 和 redis_client 都为 None 时
@@ -97,8 +97,8 @@ class EventBusManager:
97
97
  config: EventInstanceConfig | None = None,
98
98
  redis_client: RedisClient | None = None,
99
99
  url: str | None = None,
100
- channel_prefix: str = "events:",
101
- exchange_name: str = "events",
100
+ channel_prefix: str | None = None,
101
+ exchange_name: str = "aury.events",
102
102
  ) -> EventBusManager:
103
103
  """初始化事件总线(链式调用)。
104
104
 
@@ -107,8 +107,8 @@ class EventBusManager:
107
107
  config: Event 实例配置(推荐,自动根据 backend 初始化)
108
108
  redis_client: Redis 客户端(当 backend=redis 且 config=None 时需要)
109
109
  url: 连接 URL(当 config=None 时需要)
110
- channel_prefix: Redis 频道前缀
111
- exchange_name: RabbitMQ 交换机名称
110
+ channel_prefix: Redis 频道前缀,默认 "aury:event:"
111
+ exchange_name: RabbitMQ 交换机名称,默认 "aury.events"
112
112
 
113
113
  Returns:
114
114
  self: 支持链式调用
@@ -136,7 +136,11 @@ class EventBusManager:
136
136
  if backend == EventBackend.MEMORY:
137
137
  self._backend = MemoryEventBus()
138
138
  elif backend == EventBackend.REDIS:
139
- self._backend = RedisEventBus(url=url, redis_client=redis_client, channel_prefix=channel_prefix)
139
+ # channel_prefix 为 None 时使用 RedisEventBus 的默认值
140
+ kwargs = {"url": url, "redis_client": redis_client}
141
+ if channel_prefix is not None:
142
+ kwargs["channel_prefix"] = channel_prefix
143
+ self._backend = RedisEventBus(**kwargs)
140
144
  elif backend == EventBackend.RABBITMQ:
141
145
  self._backend = RabbitMQEventBus(url=url, exchange_name=exchange_name)
142
146
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aury-boot
3
- Version: 0.0.22
3
+ Version: 0.0.24
4
4
  Summary: Aury Boot - 基于 FastAPI 生态的企业级 API 开发框架
5
5
  Requires-Python: >=3.13
6
6
  Requires-Dist: alembic>=1.17.2
@@ -1,5 +1,5 @@
1
1
  aury/boot/__init__.py,sha256=pCno-EInnpIBa1OtxNYF-JWf9j95Cd2h6vmu0xqa_-4,1791
2
- aury/boot/_version.py,sha256=ppqXAvMQkDCf5uPK5J4O6hozIheDimMJFhFAaY9euV0,706
2
+ aury/boot/_version.py,sha256=XrY1zhka91SvYFuoqczo63946VCS-B_2e6wTaL8sPYQ,706
3
3
  aury/boot/application/__init__.py,sha256=0o_XmiwFCeAu06VHggS8I1e7_nSMoRq0Hcm0fYfCywU,3071
4
4
  aury/boot/application/adapter/__init__.py,sha256=e1bcSb1bxUMfofTwiCuHBZJk5-STkMCWPF2EJXHQ7UU,3976
5
5
  aury/boot/application/adapter/base.py,sha256=Ar_66fiHPDEmV-1DKnqXKwc53p3pozG31bgTJTEUriY,15763
@@ -81,7 +81,7 @@ aury/boot/commands/templates/project/aury_docs/09-tasks.md.tpl,sha256=swHOQ_pWPt
81
81
  aury/boot/commands/templates/project/aury_docs/10-storage.md.tpl,sha256=mhe0j0S51ndPJLjaQ6yD8OPYBEO02NHumJVbBvz2qkw,4320
82
82
  aury/boot/commands/templates/project/aury_docs/11-logging.md.tpl,sha256=bwxFCGQsO9cTEbwqJF1xcjsZKP82HRWhIMRUS0c9_ZI,2435
83
83
  aury/boot/commands/templates/project/aury_docs/12-admin.md.tpl,sha256=6z3mN54qP2jtpTFOJBLVexvEv0ZHXYKjncvpZG4yOdw,1883
84
- aury/boot/commands/templates/project/aury_docs/13-channel.md.tpl,sha256=rdtlog3ajcSsT0fq9a_US3MPcZhTvDo72eT6hetg4aI,3376
84
+ aury/boot/commands/templates/project/aury_docs/13-channel.md.tpl,sha256=jz10V8v-ygVweio7Ri6A2pPGOZzKZOoWMOyYW7QH77w,4426
85
85
  aury/boot/commands/templates/project/aury_docs/14-mq.md.tpl,sha256=4bxLQBbCi0Fue0VQWOPt6acZ5P00BoLkCoLPQe_8k4U,2396
86
86
  aury/boot/commands/templates/project/aury_docs/15-events.md.tpl,sha256=a4wQRgVPuYUGTGmw_lX1HJH_yFTbD30mBz7Arc4zgfs,3361
87
87
  aury/boot/commands/templates/project/aury_docs/16-adapter.md.tpl,sha256=pkmJkZw2Ca6_uYk2jZvAb8DozjBa2tWq_t3gtq1lFSk,11456
@@ -139,11 +139,11 @@ aury/boot/infrastructure/cache/exceptions.py,sha256=KZsFIHXW3_kOh_KB93EVZJKbiDvD
139
139
  aury/boot/infrastructure/cache/factory.py,sha256=aF74JoiiSKFgctqqh2Z8OtGRS2Am_ou-I40GyygLzC0,2489
140
140
  aury/boot/infrastructure/cache/manager.py,sha256=GGoOgYyIdWKMmhej5cRvEfpNeMN1GaSaU9hc0dy8_sA,12106
141
141
  aury/boot/infrastructure/channel/__init__.py,sha256=Ztcfn1-TomgV91qhePpFK-3_nKgBt862yEFYUzIwPlo,566
142
- aury/boot/infrastructure/channel/base.py,sha256=lBpP6vQB2AReoE7pJorkj9mAylXgC31B9Iwhyy2XKlk,2087
143
- aury/boot/infrastructure/channel/manager.py,sha256=aZ-5lVn2lVRnq_tyCcEgBjZngrt_B6tuoWxlDOf3ykw,6260
142
+ aury/boot/infrastructure/channel/base.py,sha256=kRjvoOQ0X5ilUAdz03BNBfbZJgdqcsjUviK4_dJatBs,2642
143
+ aury/boot/infrastructure/channel/manager.py,sha256=wOkO018Ch2694z9vOGgojaGOdCXHi0zrekkfLezn8bo,7444
144
144
  aury/boot/infrastructure/channel/backends/__init__.py,sha256=zrOhrzkhEIgsO7Armhgda1ruJQ6a9ZK7GPZuzvEiuN8,151
145
- aury/boot/infrastructure/channel/backends/memory.py,sha256=bQuuCU1fHRYdzLRsGwtqObI6U6VYlfyfT_gEwsZcujQ,2808
146
- aury/boot/infrastructure/channel/backends/redis.py,sha256=lJEPyUxKazjcNa-RU5GyIT2BzyOPLAw3KBTijHslrEo,2810
145
+ aury/boot/infrastructure/channel/backends/memory.py,sha256=QQyZxIdYtA_pWqdKgUIMkvnbBwvv45-vX-qostDHyfg,4699
146
+ aury/boot/infrastructure/channel/backends/redis.py,sha256=_UL7wE-bO147CPXKDjJgYGjj09Lg9x9U2PLYa37q5yQ,4666
147
147
  aury/boot/infrastructure/clients/__init__.py,sha256=1ANMejb3RrBgaR-jq-dsxJ0kQDRHz5jV-QvdUNcf_ok,435
148
148
  aury/boot/infrastructure/clients/rabbitmq/__init__.py,sha256=cnU-W7jOcAgp_FvsY9EipNCeJzeA9gHLRuZ0yQZE2DI,200
149
149
  aury/boot/infrastructure/clients/rabbitmq/config.py,sha256=YmvNiISpqNt-LE2CrpzmxCgaEgYna7IbOfUSnA0B4T0,1239
@@ -161,12 +161,12 @@ aury/boot/infrastructure/di/__init__.py,sha256=qFYlk265d6_rS8OiX37_wOc7mBFw8hk3y
161
161
  aury/boot/infrastructure/di/container.py,sha256=14FVbafGXea-JEAYeOEBxB6zAwndLCZJvprKiD_1IOQ,12524
162
162
  aury/boot/infrastructure/events/__init__.py,sha256=D5JNFkGHCH79nYbqUil0Z8eW2p6Gx8P0vBbNnHqnTgM,698
163
163
  aury/boot/infrastructure/events/base.py,sha256=oS6aNUWRvpXlbh7L3_4vzlwUumYmg44HKS1S4m_zOFo,3019
164
- aury/boot/infrastructure/events/manager.py,sha256=HIHcTMs9lz9pFIcR7S1F2iKBUKGeLaD_4P5rlLjp1vw,7334
164
+ aury/boot/infrastructure/events/manager.py,sha256=Hnua9x_Ppmo99JUEmjuZcKIPv2IEZQ3Du9ziPg-C8Fo,7570
165
165
  aury/boot/infrastructure/events/middleware.py,sha256=Ck3qNMTtLuFFKsJuEUeOMG9nu3qK1N_aqt6wH5JoAtw,1336
166
166
  aury/boot/infrastructure/events/backends/__init__.py,sha256=V_hPtdjVUkYU4Uf8hTPVBUcnNYG9OfkjRPDnjp_5_zA,224
167
167
  aury/boot/infrastructure/events/backends/memory.py,sha256=Up7vAxdJvIqkcqpnKNCu81ec6iCfNIhcQ-jKM3M2hZc,2623
168
168
  aury/boot/infrastructure/events/backends/rabbitmq.py,sha256=XCuI9mc3GR-t0zht4yZ3e2nnyFl8UuTDir_0nsDbfxM,6495
169
- aury/boot/infrastructure/events/backends/redis.py,sha256=ZCcA6ZvJFvRuwW9IbBfEUy9yp1IKiIrhJ6eDnp2ikKs,5596
169
+ aury/boot/infrastructure/events/backends/redis.py,sha256=i8jPCtR7ITPVTl9DVFDbNbjypnWoeSpar6z4lJJlOD8,5790
170
170
  aury/boot/infrastructure/monitoring/__init__.py,sha256=VgElCdCVcgERTIn3oRoSNslR82W9gRX5vgJcYDeloak,16149
171
171
  aury/boot/infrastructure/mq/__init__.py,sha256=Q7kBk_GeQnxnqkyp29Bh1yFH3Q8xxxjs8oDYLeDj8C0,498
172
172
  aury/boot/infrastructure/mq/base.py,sha256=kHrWUysWflMj3qyOnioLZ90it8d9Alq1Wb4PYhpBW4k,3396
@@ -192,7 +192,7 @@ aury/boot/testing/client.py,sha256=KOg1EemuIVsBG68G5y0DjSxZGcIQVdWQ4ASaHE3o1R0,4
192
192
  aury/boot/testing/factory.py,sha256=8GvwX9qIDu0L65gzJMlrWB0xbmJ-7zPHuwk3eECULcg,5185
193
193
  aury/boot/toolkit/__init__.py,sha256=AcyVb9fDf3CaEmJPNkWC4iGv32qCPyk4BuFKSuNiJRQ,334
194
194
  aury/boot/toolkit/http/__init__.py,sha256=zIPmpIZ9Qbqe25VmEr7jixoY2fkRbLm7NkCB9vKpg6I,11039
195
- aury_boot-0.0.22.dist-info/METADATA,sha256=ni5jJsNSu861N3iwbJndJrniPtKLU3U7kEa1CVNDNwA,7695
196
- aury_boot-0.0.22.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
197
- aury_boot-0.0.22.dist-info/entry_points.txt,sha256=f9KXEkDIGc0BGkgBvsNx_HMz9VhDjNxu26q00jUpDwQ,49
198
- aury_boot-0.0.22.dist-info/RECORD,,
195
+ aury_boot-0.0.24.dist-info/METADATA,sha256=BeSds7eWMGtPxD_RNx0CXwIz_FdwWXxr6QRqR1nitzI,7695
196
+ aury_boot-0.0.24.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
197
+ aury_boot-0.0.24.dist-info/entry_points.txt,sha256=f9KXEkDIGc0BGkgBvsNx_HMz9VhDjNxu26q00jUpDwQ,49
198
+ aury_boot-0.0.24.dist-info/RECORD,,