jararaca 0.3.11a7__py3-none-any.whl → 0.3.11a9__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.

Potentially problematic release.


This version of jararaca might be problematic. Click here for more details.

@@ -1,4 +1,9 @@
1
+ import logging
2
+
1
3
  from aio_pika.abc import AbstractChannel, AbstractExchange, AbstractQueue
4
+ from aio_pika.exceptions import AMQPError, ChannelClosed, ChannelNotFoundEntity
5
+
6
+ logger = logging.getLogger(__name__)
2
7
 
3
8
 
4
9
  class RabbitmqUtils:
@@ -6,6 +11,39 @@ class RabbitmqUtils:
6
11
  DEAD_LETTER_EXCHANGE = "dlx"
7
12
  DEAD_LETTER_QUEUE = "dlq"
8
13
 
14
+ # Note: get_worker_v1_queue method is already defined above
15
+
16
+ DEAD_LETTER_EXCHANGE = "dlx"
17
+ DEAD_LETTER_QUEUE = "dlq"
18
+
19
+ @classmethod
20
+ async def get_dl_exchange(cls, channel: AbstractChannel) -> AbstractExchange:
21
+ """
22
+ Get the Dead Letter Exchange (DLX) for the given channel.
23
+ """
24
+ try:
25
+ return await channel.get_exchange(
26
+ cls.DEAD_LETTER_EXCHANGE,
27
+ )
28
+ except ChannelNotFoundEntity as e:
29
+ logger.error(
30
+ f"Dead Letter Exchange '{cls.DEAD_LETTER_EXCHANGE}' does not exist. "
31
+ f"Please use the declare command to create it first. Error: {e}"
32
+ )
33
+ raise
34
+ except ChannelClosed as e:
35
+ logger.error(
36
+ f"Channel closed while getting Dead Letter Exchange '{cls.DEAD_LETTER_EXCHANGE}'. "
37
+ f"Error: {e}"
38
+ )
39
+ raise
40
+ except AMQPError as e:
41
+ logger.error(
42
+ f"AMQP error while getting Dead Letter Exchange '{cls.DEAD_LETTER_EXCHANGE}'. "
43
+ f"Error: {e}"
44
+ )
45
+ raise
46
+
9
47
  @classmethod
10
48
  async def declare_dl_exchange(
11
49
  cls, channel: AbstractChannel, passive: bool
@@ -22,6 +60,34 @@ class RabbitmqUtils:
22
60
  auto_delete=False,
23
61
  )
24
62
 
63
+ @classmethod
64
+ async def get_dl_queue(cls, channel: AbstractChannel) -> AbstractQueue:
65
+ """
66
+ Get the Dead Letter Queue (DLQ) for the given channel.
67
+ """
68
+ try:
69
+ return await channel.get_queue(
70
+ cls.DEAD_LETTER_QUEUE,
71
+ )
72
+ except ChannelNotFoundEntity as e:
73
+ logger.error(
74
+ f"Dead Letter Queue '{cls.DEAD_LETTER_QUEUE}' does not exist. "
75
+ f"Please use the declare command to create it first. Error: {e}"
76
+ )
77
+ raise
78
+ except ChannelClosed as e:
79
+ logger.error(
80
+ f"Channel closed while getting Dead Letter Queue '{cls.DEAD_LETTER_QUEUE}'. "
81
+ f"Error: {e}"
82
+ )
83
+ raise
84
+ except AMQPError as e:
85
+ logger.error(
86
+ f"AMQP error while getting Dead Letter Queue '{cls.DEAD_LETTER_QUEUE}'. "
87
+ f"Error: {e}"
88
+ )
89
+ raise
90
+
25
91
  @classmethod
26
92
  async def declare_dl_queue(
27
93
  cls, channel: AbstractChannel, passive: bool
@@ -40,6 +106,36 @@ class RabbitmqUtils:
40
106
  },
41
107
  )
42
108
 
109
+ @classmethod
110
+ async def get_dl_kit(
111
+ cls,
112
+ channel: AbstractChannel,
113
+ ) -> tuple[AbstractExchange, AbstractQueue]:
114
+ """
115
+ Get the Dead Letter Exchange and Queue (DLX and DLQ) for the given channel.
116
+ """
117
+ try:
118
+ dlx = await cls.get_dl_exchange(channel)
119
+ dlq = await cls.get_dl_queue(channel)
120
+ return dlx, dlq
121
+ except ChannelNotFoundEntity as e:
122
+ logger.error(
123
+ f"Dead Letter infrastructure does not exist completely. "
124
+ f"Please use the declare command to create it first. Error: {e}"
125
+ )
126
+ raise
127
+ except ChannelClosed as e:
128
+ logger.error(
129
+ f"Channel closed while getting Dead Letter infrastructure. "
130
+ f"Error: {e}"
131
+ )
132
+ raise
133
+ except AMQPError as e:
134
+ logger.error(
135
+ f"AMQP error while getting Dead Letter infrastructure. " f"Error: {e}"
136
+ )
137
+ raise
138
+
43
139
  @classmethod
44
140
  async def declare_dl_kit(
45
141
  cls,
@@ -54,6 +150,33 @@ class RabbitmqUtils:
54
150
  await dlq.bind(dlx, routing_key=cls.DEAD_LETTER_EXCHANGE)
55
151
  return dlx, dlq
56
152
 
153
+ @classmethod
154
+ async def get_main_exchange(
155
+ cls, channel: AbstractChannel, exchange_name: str
156
+ ) -> AbstractExchange:
157
+ """
158
+ Get the main exchange for the given channel.
159
+ """
160
+ try:
161
+ return await channel.get_exchange(exchange_name)
162
+ except ChannelNotFoundEntity as e:
163
+ logger.error(
164
+ f"Exchange '{exchange_name}' does not exist. "
165
+ f"Please use the declare command to create it first. Error: {e}"
166
+ )
167
+ raise
168
+ except ChannelClosed as e:
169
+ logger.error(
170
+ f"Channel closed while getting exchange '{exchange_name}'. "
171
+ f"Error: {e}"
172
+ )
173
+ raise
174
+ except AMQPError as e:
175
+ logger.error(
176
+ f"AMQP error while getting exchange '{exchange_name}'. " f"Error: {e}"
177
+ )
178
+ raise
179
+
57
180
  @classmethod
58
181
  async def declare_main_exchange(
59
182
  cls, channel: AbstractChannel, exchange_name: str, passive: bool
@@ -70,6 +193,34 @@ class RabbitmqUtils:
70
193
  auto_delete=False,
71
194
  )
72
195
 
196
+ @classmethod
197
+ async def get_queue(
198
+ cls,
199
+ channel: AbstractChannel,
200
+ queue_name: str,
201
+ ) -> AbstractQueue:
202
+ """
203
+ Get a queue with the given name.
204
+ """
205
+ try:
206
+ return await channel.get_queue(queue_name)
207
+ except ChannelNotFoundEntity as e:
208
+ logger.error(
209
+ f"Queue '{queue_name}' does not exist. "
210
+ f"Please use the declare command to create it first. Error: {e}"
211
+ )
212
+ raise
213
+ except ChannelClosed as e:
214
+ logger.error(
215
+ f"Channel closed while getting queue '{queue_name}'. " f"Error: {e}"
216
+ )
217
+ raise
218
+ except AMQPError as e:
219
+ logger.error(
220
+ f"AMQP error while getting queue '{queue_name}'. " f"Error: {e}"
221
+ )
222
+ raise
223
+
73
224
  @classmethod
74
225
  async def declare_queue(
75
226
  cls,
@@ -90,3 +241,152 @@ class RabbitmqUtils:
90
241
  "x-dead-letter-routing-key": cls.DEAD_LETTER_EXCHANGE,
91
242
  },
92
243
  )
244
+
245
+ @classmethod
246
+ async def get_worker_v1_queue(
247
+ cls,
248
+ channel: AbstractChannel,
249
+ queue_name: str,
250
+ ) -> AbstractQueue:
251
+ """
252
+ Get a worker v1 queue.
253
+ """
254
+ try:
255
+ return await channel.get_queue(queue_name)
256
+ except ChannelNotFoundEntity as e:
257
+ logger.error(
258
+ f"Worker queue '{queue_name}' does not exist. "
259
+ f"Please use the declare command to create it first. Error: {e}"
260
+ )
261
+ raise
262
+ except ChannelClosed as e:
263
+ logger.error(
264
+ f"Channel closed while getting worker queue '{queue_name}'. "
265
+ f"Error: {e}"
266
+ )
267
+ raise
268
+ except AMQPError as e:
269
+ logger.error(
270
+ f"AMQP error while getting worker queue '{queue_name}'. " f"Error: {e}"
271
+ )
272
+ raise
273
+
274
+ @classmethod
275
+ async def declare_worker_v1_queue(
276
+ cls,
277
+ channel: AbstractChannel,
278
+ queue_name: str,
279
+ dlx_name: str,
280
+ dlq_name: str,
281
+ passive: bool = False,
282
+ ) -> AbstractQueue:
283
+ """
284
+ Declare a worker v1 queue with custom dead letter exchange and routing key.
285
+ """
286
+ return await channel.declare_queue(
287
+ passive=passive,
288
+ name=queue_name,
289
+ arguments={
290
+ "x-dead-letter-exchange": dlx_name,
291
+ "x-dead-letter-routing-key": dlq_name,
292
+ },
293
+ durable=True,
294
+ )
295
+
296
+ @classmethod
297
+ async def get_scheduler_queue(
298
+ cls,
299
+ channel: AbstractChannel,
300
+ queue_name: str,
301
+ ) -> AbstractQueue:
302
+ """
303
+ Get a scheduler queue.
304
+ """
305
+ try:
306
+ return await channel.get_queue(queue_name)
307
+ except ChannelNotFoundEntity as e:
308
+ logger.error(
309
+ f"Scheduler queue '{queue_name}' does not exist. "
310
+ f"Please use the declare command to create it first. Error: {e}"
311
+ )
312
+ raise
313
+ except ChannelClosed as e:
314
+ logger.error(
315
+ f"Channel closed while getting scheduler queue '{queue_name}'. "
316
+ f"Error: {e}"
317
+ )
318
+ raise
319
+ except AMQPError as e:
320
+ logger.error(
321
+ f"AMQP error while getting scheduler queue '{queue_name}'. "
322
+ f"Error: {e}"
323
+ )
324
+ raise
325
+
326
+ @classmethod
327
+ async def declare_scheduler_queue(
328
+ cls,
329
+ channel: AbstractChannel,
330
+ queue_name: str,
331
+ passive: bool = False,
332
+ ) -> AbstractQueue:
333
+ """
334
+ Declare a scheduler queue with simple durable configuration.
335
+ """
336
+ return await channel.declare_queue(
337
+ name=queue_name,
338
+ durable=True,
339
+ passive=passive,
340
+ )
341
+
342
+ @classmethod
343
+ async def delete_exchange(
344
+ cls,
345
+ channel: AbstractChannel,
346
+ exchange_name: str,
347
+ if_unused: bool = False,
348
+ ) -> None:
349
+ """
350
+ Delete an exchange.
351
+ """
352
+ try:
353
+ await channel.exchange_delete(
354
+ exchange_name=exchange_name,
355
+ if_unused=if_unused,
356
+ )
357
+ except ChannelNotFoundEntity:
358
+ # Exchange might not exist, which is fine
359
+ logger.info(
360
+ f"Exchange '{exchange_name}' does not exist, nothing to delete."
361
+ )
362
+ except ChannelClosed as e:
363
+ logger.warning(
364
+ f"Channel closed while deleting exchange '{exchange_name}': {e}"
365
+ )
366
+ except AMQPError as e:
367
+ logger.warning(f"AMQP error while deleting exchange '{exchange_name}': {e}")
368
+
369
+ @classmethod
370
+ async def delete_queue(
371
+ cls,
372
+ channel: AbstractChannel,
373
+ queue_name: str,
374
+ if_unused: bool = False,
375
+ if_empty: bool = False,
376
+ ) -> None:
377
+ """
378
+ Delete a queue.
379
+ """
380
+ try:
381
+ await channel.queue_delete(
382
+ queue_name=queue_name,
383
+ if_unused=if_unused,
384
+ if_empty=if_empty,
385
+ )
386
+ except ChannelNotFoundEntity:
387
+ # Queue might not exist, which is fine
388
+ logger.info(f"Queue '{queue_name}' does not exist, nothing to delete.")
389
+ except ChannelClosed as e:
390
+ logger.warning(f"Channel closed while deleting queue '{queue_name}': {e}")
391
+ except AMQPError as e:
392
+ logger.warning(f"AMQP error while deleting queue '{queue_name}': {e}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: jararaca
3
- Version: 0.3.11a7
3
+ Version: 0.3.11a9
4
4
  Summary: A simple and fast API framework for Python
5
5
  Author: Lucas S
6
6
  Author-email: me@luscasleo.dev
@@ -3,7 +3,7 @@ jararaca/__main__.py,sha256=-O3vsB5lHdqNFjUtoELDF81IYFtR-DSiiFMzRaiSsv4,67
3
3
  jararaca/broker_backend/__init__.py,sha256=GzEIuHR1xzgCJD4FE3harNjoaYzxHMHoEL0_clUaC-k,3528
4
4
  jararaca/broker_backend/mapper.py,sha256=vTsi7sWpNvlga1PWPFg0rCJ5joJ0cdzykkIc2Tuvenc,696
5
5
  jararaca/broker_backend/redis_broker_backend.py,sha256=a7DHchy3NAiD71Ix8SwmQOUnniu7uup-Woa4ON_4J7I,5786
6
- jararaca/cli.py,sha256=YdIot8zcnRoW5_Qm4rn0Ow1kfjlgPCJwndG63vDzpaA,24572
6
+ jararaca/cli.py,sha256=8B3WvRqZAGn2ErfgvldiumaeFHO74jU01GCF1VdnWr4,21950
7
7
  jararaca/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  jararaca/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  jararaca/core/providers.py,sha256=wktH84FK7c1s2wNq-fudf1uMfi3CQBR0neU2czJ_L0U,434
@@ -14,15 +14,15 @@ jararaca/lifecycle.py,sha256=qKlzLQQioS8QkxNJ_FC_5WbmT77cNbc_S7OcQeOoHkI,1895
14
14
  jararaca/messagebus/__init__.py,sha256=5jAqPqdcEMYBfQyfZDWPnplYdrfMyJLMcacf3qLyUhk,56
15
15
  jararaca/messagebus/bus_message_controller.py,sha256=Xd_qwnX5jUvgBTCarHR36fvtol9lPTsYp2IIGKyQQaE,1487
16
16
  jararaca/messagebus/consumers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- jararaca/messagebus/decorators.py,sha256=pNefkrfTFuhRQQzmfL7MSKcVa55b0TUHqEtKPunxoAA,5847
17
+ jararaca/messagebus/decorators.py,sha256=jkVkN-NNIefKjMGq0JcAjEprdoo04jZtHm7YMsja1to,5896
18
18
  jararaca/messagebus/interceptors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  jararaca/messagebus/interceptors/aiopika_publisher_interceptor.py,sha256=_DEHwIH9LYsA26Hu1mo9oHzLZuATgjilU9E3o-ecDjs,6520
20
20
  jararaca/messagebus/interceptors/publisher_interceptor.py,sha256=ojy1bRhqMgrkQljcGGS8cd8-8pUjL8ZHjIUkdmaAnNM,1325
21
21
  jararaca/messagebus/message.py,sha256=U6cyd2XknX8mtm0333slz5fanky2PFLWCmokAO56vvU,819
22
22
  jararaca/messagebus/publisher.py,sha256=JTkxdKbvxvDWT8nK8PVEyyX061vYYbKQMxRHXrZtcEY,2173
23
- jararaca/messagebus/worker.py,sha256=IMMI5NCVYnXmETFgFymkFJj-dGUHM0WQUZXNItfW5cY,14018
24
- jararaca/messagebus/worker_v2.py,sha256=M8bN_9L1mo_uzJDut90WgKv3okwrzfKg4jD6jUFcBvA,20904
25
- jararaca/microservice.py,sha256=jTGzkoJcco1nXwZZDeHRwEHAu_Hpr5gxA_d51P49C2c,7915
23
+ jararaca/messagebus/worker.py,sha256=Rc6-KG0Uxo89Q5JpOC-FMuGEwg9sIElUMVh2WLINGOc,14862
24
+ jararaca/messagebus/worker_v2.py,sha256=18oD-6Ip_rOa90p53EcEPlvkXho3SWrC40l4OVSIsE4,22356
25
+ jararaca/microservice.py,sha256=rRIimfeP2-wf289PKoUbk9wrSdA0ga_qWz5JNgQ5IE0,9667
26
26
  jararaca/observability/decorators.py,sha256=MOIr2PttPYYvRwEdfQZEwD5RxKHOTv8UEy9n1YQVoKw,2281
27
27
  jararaca/observability/interceptor.py,sha256=U4ZLM0f8j6Q7gMUKKnA85bnvD-Qa0ii79Qa_X8KsXAQ,1498
28
28
  jararaca/observability/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -58,18 +58,18 @@ jararaca/rpc/http/backends/otel.py,sha256=Uc6CjHSCZ5hvnK1fNFv3ota5xzUFnvIl1JOpG3
58
58
  jararaca/rpc/http/decorators.py,sha256=oUSzgMGI8w6SoKiz3GltDbd3BWAuyY60F23cdRRNeiw,11897
59
59
  jararaca/rpc/http/httpx.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
60
  jararaca/scheduler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
- jararaca/scheduler/decorators.py,sha256=ZvOMzQT1ypU7xRLuhu6YARek1YFQ69kje2NdGjlppY8,4325
62
- jararaca/scheduler/scheduler.py,sha256=PjX40P09tAeD77Z0f4U1XkW782aDk_1GlUXoLaEWXe8,5446
63
- jararaca/scheduler/scheduler_v2.py,sha256=x1snb4eaCmBqjAkAvAcqSNvgpQolXqf_zTfKRBK3bIM,11260
61
+ jararaca/scheduler/decorators.py,sha256=iyWFvPLCRh9c0YReQRemI2mLuaUv7r929So-xuKIWUs,4605
62
+ jararaca/scheduler/scheduler.py,sha256=1T7qKIOiU9WD2p0aJsiUW-MOArJZyUSMwpv_14ziTQM,6188
63
+ jararaca/scheduler/scheduler_v2.py,sha256=zrpbiYEzEn7dugbH-MhodOBVjPRzpJ9Z3iEPg8qZVB4,11839
64
64
  jararaca/scheduler/types.py,sha256=4HEQOmVIDp-BYLSzqmqSFIio1bd51WFmgFPIzPpVu04,135
65
65
  jararaca/tools/app_config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
66
  jararaca/tools/app_config/decorators.py,sha256=-ckkMZ1dswOmECdo1rFrZ15UAku--txaNXMp8fd1Ndk,941
67
67
  jararaca/tools/app_config/interceptor.py,sha256=HV8h4AxqUc_ACs5do4BSVlyxlRXzx7HqJtoVO9tfRnQ,2611
68
68
  jararaca/tools/typescript/interface_parser.py,sha256=35xbOrZDQDyTXdMrVZQ8nnFw79f28lJuLYNHAspIqi8,30492
69
69
  jararaca/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
- jararaca/utils/rabbitmq_utils.py,sha256=MFbXpScRxUyeZMfhB-o22PTFFF_SrU8Y09APaGYUtbo,2623
71
- jararaca-0.3.11a7.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
72
- jararaca-0.3.11a7.dist-info/METADATA,sha256=tNPHTsrnA-qsO31QGN1GzH5z8522sLFU2vlCrMDAe9o,4997
73
- jararaca-0.3.11a7.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
74
- jararaca-0.3.11a7.dist-info/entry_points.txt,sha256=WIh3aIvz8LwUJZIDfs4EeH3VoFyCGEk7cWJurW38q0I,45
75
- jararaca-0.3.11a7.dist-info/RECORD,,
70
+ jararaca/utils/rabbitmq_utils.py,sha256=8_HLPODHhXjiU6TqiXQtrf50EiN1IvAEUkbzrCSbjP8,12221
71
+ jararaca-0.3.11a9.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
72
+ jararaca-0.3.11a9.dist-info/METADATA,sha256=wr4fnnWJHt1xJnxQk57UjWtaV28FjNW8Xk2wYITk65s,4997
73
+ jararaca-0.3.11a9.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
74
+ jararaca-0.3.11a9.dist-info/entry_points.txt,sha256=WIh3aIvz8LwUJZIDfs4EeH3VoFyCGEk7cWJurW38q0I,45
75
+ jararaca-0.3.11a9.dist-info/RECORD,,