jararaca 0.3.11a16__py3-none-any.whl → 0.4.0a5__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.
Files changed (88) hide show
  1. README.md +121 -0
  2. jararaca/__init__.py +184 -12
  3. jararaca/__main__.py +4 -0
  4. jararaca/broker_backend/__init__.py +4 -0
  5. jararaca/broker_backend/mapper.py +4 -0
  6. jararaca/broker_backend/redis_broker_backend.py +9 -3
  7. jararaca/cli.py +272 -47
  8. jararaca/common/__init__.py +3 -0
  9. jararaca/core/__init__.py +3 -0
  10. jararaca/core/providers.py +4 -0
  11. jararaca/core/uow.py +41 -7
  12. jararaca/di.py +4 -0
  13. jararaca/files/entity.py.mako +4 -0
  14. jararaca/lifecycle.py +6 -2
  15. jararaca/messagebus/__init__.py +4 -0
  16. jararaca/messagebus/bus_message_controller.py +4 -0
  17. jararaca/messagebus/consumers/__init__.py +3 -0
  18. jararaca/messagebus/decorators.py +33 -67
  19. jararaca/messagebus/implicit_headers.py +49 -0
  20. jararaca/messagebus/interceptors/__init__.py +3 -0
  21. jararaca/messagebus/interceptors/aiopika_publisher_interceptor.py +13 -4
  22. jararaca/messagebus/interceptors/publisher_interceptor.py +4 -0
  23. jararaca/messagebus/message.py +4 -0
  24. jararaca/messagebus/publisher.py +6 -0
  25. jararaca/messagebus/worker.py +850 -383
  26. jararaca/microservice.py +110 -1
  27. jararaca/observability/constants.py +7 -0
  28. jararaca/observability/decorators.py +170 -13
  29. jararaca/observability/fastapi_exception_handler.py +37 -0
  30. jararaca/observability/hooks.py +109 -0
  31. jararaca/observability/interceptor.py +4 -0
  32. jararaca/observability/providers/__init__.py +3 -0
  33. jararaca/observability/providers/otel.py +202 -11
  34. jararaca/persistence/base.py +38 -2
  35. jararaca/persistence/exports.py +4 -0
  36. jararaca/persistence/interceptors/__init__.py +3 -0
  37. jararaca/persistence/interceptors/aiosqa_interceptor.py +86 -73
  38. jararaca/persistence/interceptors/constants.py +5 -0
  39. jararaca/persistence/interceptors/decorators.py +50 -0
  40. jararaca/persistence/session.py +3 -0
  41. jararaca/persistence/sort_filter.py +4 -0
  42. jararaca/persistence/utilities.py +50 -20
  43. jararaca/presentation/__init__.py +3 -0
  44. jararaca/presentation/decorators.py +88 -86
  45. jararaca/presentation/exceptions.py +23 -0
  46. jararaca/presentation/hooks.py +4 -0
  47. jararaca/presentation/http_microservice.py +4 -0
  48. jararaca/presentation/server.py +97 -45
  49. jararaca/presentation/websocket/__init__.py +3 -0
  50. jararaca/presentation/websocket/base_types.py +4 -0
  51. jararaca/presentation/websocket/context.py +4 -0
  52. jararaca/presentation/websocket/decorators.py +8 -41
  53. jararaca/presentation/websocket/redis.py +280 -53
  54. jararaca/presentation/websocket/types.py +4 -0
  55. jararaca/presentation/websocket/websocket_interceptor.py +46 -19
  56. jararaca/reflect/__init__.py +3 -0
  57. jararaca/reflect/controller_inspect.py +16 -10
  58. jararaca/reflect/decorators.py +238 -0
  59. jararaca/reflect/metadata.py +34 -25
  60. jararaca/rpc/__init__.py +3 -0
  61. jararaca/rpc/http/__init__.py +101 -0
  62. jararaca/rpc/http/backends/__init__.py +14 -0
  63. jararaca/rpc/http/backends/httpx.py +43 -9
  64. jararaca/rpc/http/backends/otel.py +4 -0
  65. jararaca/rpc/http/decorators.py +378 -113
  66. jararaca/rpc/http/httpx.py +3 -0
  67. jararaca/scheduler/__init__.py +3 -0
  68. jararaca/scheduler/beat_worker.py +521 -105
  69. jararaca/scheduler/decorators.py +15 -22
  70. jararaca/scheduler/types.py +4 -0
  71. jararaca/tools/app_config/__init__.py +3 -0
  72. jararaca/tools/app_config/decorators.py +7 -19
  73. jararaca/tools/app_config/interceptor.py +6 -2
  74. jararaca/tools/typescript/__init__.py +3 -0
  75. jararaca/tools/typescript/decorators.py +120 -0
  76. jararaca/tools/typescript/interface_parser.py +1074 -173
  77. jararaca/utils/__init__.py +3 -0
  78. jararaca/utils/rabbitmq_utils.py +65 -39
  79. jararaca/utils/retry.py +10 -3
  80. jararaca-0.4.0a5.dist-info/LICENSE +674 -0
  81. jararaca-0.4.0a5.dist-info/LICENSES/GPL-3.0-or-later.txt +232 -0
  82. {jararaca-0.3.11a16.dist-info → jararaca-0.4.0a5.dist-info}/METADATA +11 -7
  83. jararaca-0.4.0a5.dist-info/RECORD +88 -0
  84. {jararaca-0.3.11a16.dist-info → jararaca-0.4.0a5.dist-info}/WHEEL +1 -1
  85. pyproject.toml +131 -0
  86. jararaca-0.3.11a16.dist-info/RECORD +0 -74
  87. /jararaca-0.3.11a16.dist-info/LICENSE → /LICENSE +0 -0
  88. {jararaca-0.3.11a16.dist-info → jararaca-0.4.0a5.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,3 @@
1
+ # SPDX-FileCopyrightText: 2025 Lucas S
2
+ #
3
+ # SPDX-License-Identifier: GPL-3.0-or-later
@@ -1,3 +1,7 @@
1
+ # SPDX-FileCopyrightText: 2025 Lucas S
2
+ #
3
+ # SPDX-License-Identifier: GPL-3.0-or-later
4
+
1
5
  import logging
2
6
 
3
7
  from aio_pika.abc import AbstractChannel, AbstractExchange, AbstractQueue
@@ -27,20 +31,24 @@ class RabbitmqUtils:
27
31
  )
28
32
  except ChannelNotFoundEntity as e:
29
33
  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}"
34
+ "Dead Letter Exchange '%s' does not exist. "
35
+ "Please use the declare command to create it first. Error: %s",
36
+ cls.DEAD_LETTER_EXCHANGE,
37
+ e,
32
38
  )
33
39
  raise
34
40
  except ChannelClosed as e:
35
41
  logger.error(
36
- f"Channel closed while getting Dead Letter Exchange '{cls.DEAD_LETTER_EXCHANGE}'. "
37
- f"Error: {e}"
42
+ "Channel closed while getting Dead Letter Exchange '%s'. " "Error: %s",
43
+ cls.DEAD_LETTER_EXCHANGE,
44
+ e,
38
45
  )
39
46
  raise
40
47
  except AMQPError as e:
41
48
  logger.error(
42
- f"AMQP error while getting Dead Letter Exchange '{cls.DEAD_LETTER_EXCHANGE}'. "
43
- f"Error: {e}"
49
+ "AMQP error while getting Dead Letter Exchange '%s'. " "Error: %s",
50
+ cls.DEAD_LETTER_EXCHANGE,
51
+ e,
44
52
  )
45
53
  raise
46
54
 
@@ -71,20 +79,24 @@ class RabbitmqUtils:
71
79
  )
72
80
  except ChannelNotFoundEntity as e:
73
81
  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}"
82
+ "Dead Letter Queue '%s' does not exist. "
83
+ "Please use the declare command to create it first. Error: %s",
84
+ cls.DEAD_LETTER_QUEUE,
85
+ e,
76
86
  )
77
87
  raise
78
88
  except ChannelClosed as e:
79
89
  logger.error(
80
- f"Channel closed while getting Dead Letter Queue '{cls.DEAD_LETTER_QUEUE}'. "
81
- f"Error: {e}"
90
+ "Channel closed while getting Dead Letter Queue '%s'. " "Error: %s",
91
+ cls.DEAD_LETTER_QUEUE,
92
+ e,
82
93
  )
83
94
  raise
84
95
  except AMQPError as e:
85
96
  logger.error(
86
- f"AMQP error while getting Dead Letter Queue '{cls.DEAD_LETTER_QUEUE}'. "
87
- f"Error: {e}"
97
+ "AMQP error while getting Dead Letter Queue '%s'. " "Error: %s",
98
+ cls.DEAD_LETTER_QUEUE,
99
+ e,
88
100
  )
89
101
  raise
90
102
 
@@ -120,19 +132,20 @@ class RabbitmqUtils:
120
132
  return dlx, dlq
121
133
  except ChannelNotFoundEntity as e:
122
134
  logger.error(
123
- f"Dead Letter infrastructure does not exist completely. "
124
- f"Please use the declare command to create it first. Error: {e}"
135
+ "Dead Letter infrastructure does not exist completely. "
136
+ "Please use the declare command to create it first. Error: %s",
137
+ e,
125
138
  )
126
139
  raise
127
140
  except ChannelClosed as e:
128
141
  logger.error(
129
- f"Channel closed while getting Dead Letter infrastructure. "
130
- f"Error: {e}"
142
+ "Channel closed while getting Dead Letter infrastructure. " "Error: %s",
143
+ e,
131
144
  )
132
145
  raise
133
146
  except AMQPError as e:
134
147
  logger.error(
135
- f"AMQP error while getting Dead Letter infrastructure. " f"Error: {e}"
148
+ "AMQP error while getting Dead Letter infrastructure. " "Error: %s", e
136
149
  )
137
150
  raise
138
151
 
@@ -161,19 +174,22 @@ class RabbitmqUtils:
161
174
  return await channel.get_exchange(exchange_name)
162
175
  except ChannelNotFoundEntity as e:
163
176
  logger.error(
164
- f"Exchange '{exchange_name}' does not exist. "
165
- f"Please use the declare command to create it first. Error: {e}"
177
+ "Exchange '%s' does not exist. "
178
+ "Please use the declare command to create it first. Error: %s",
179
+ exchange_name,
180
+ e,
166
181
  )
167
182
  raise
168
183
  except ChannelClosed as e:
169
184
  logger.error(
170
- f"Channel closed while getting exchange '{exchange_name}'. "
171
- f"Error: {e}"
185
+ "Channel closed while getting exchange '%s'. " "Error: %s",
186
+ exchange_name,
187
+ e,
172
188
  )
173
189
  raise
174
190
  except AMQPError as e:
175
191
  logger.error(
176
- f"AMQP error while getting exchange '{exchange_name}'. " f"Error: {e}"
192
+ "AMQP error while getting exchange '%s'. " "Error: %s", exchange_name, e
177
193
  )
178
194
  raise
179
195
 
@@ -206,18 +222,20 @@ class RabbitmqUtils:
206
222
  return await channel.get_queue(queue_name)
207
223
  except ChannelNotFoundEntity as e:
208
224
  logger.error(
209
- f"Queue '{queue_name}' does not exist. "
210
- f"Please use the declare command to create it first. Error: {e}"
225
+ "Queue '%s' does not exist. "
226
+ "Please use the declare command to create it first. Error: %s",
227
+ queue_name,
228
+ e,
211
229
  )
212
230
  raise
213
231
  except ChannelClosed as e:
214
232
  logger.error(
215
- f"Channel closed while getting queue '{queue_name}'. " f"Error: {e}"
233
+ "Channel closed while getting queue '%s'. " "Error: %s", queue_name, e
216
234
  )
217
235
  raise
218
236
  except AMQPError as e:
219
237
  logger.error(
220
- f"AMQP error while getting queue '{queue_name}'. " f"Error: {e}"
238
+ "AMQP error while getting queue '%s'. " "Error: %s", queue_name, e
221
239
  )
222
240
  raise
223
241
 
@@ -255,20 +273,24 @@ class RabbitmqUtils:
255
273
  return await channel.get_queue(queue_name)
256
274
  except ChannelNotFoundEntity as e:
257
275
  logger.error(
258
- f"Scheduler queue '{queue_name}' does not exist. "
259
- f"Please use the declare command to create it first. Error: {e}"
276
+ "Scheduler queue '%s' does not exist. "
277
+ "Please use the declare command to create it first. Error: %s",
278
+ queue_name,
279
+ e,
260
280
  )
261
281
  raise
262
282
  except ChannelClosed as e:
263
283
  logger.error(
264
- f"Channel closed while getting scheduler queue '{queue_name}'. "
265
- f"Error: {e}"
284
+ "Channel closed while getting scheduler queue '%s'. " "Error: %s",
285
+ queue_name,
286
+ e,
266
287
  )
267
288
  raise
268
289
  except AMQPError as e:
269
290
  logger.error(
270
- f"AMQP error while getting scheduler queue '{queue_name}'. "
271
- f"Error: {e}"
291
+ "AMQP error while getting scheduler queue '%s'. " "Error: %s",
292
+ queue_name,
293
+ e,
272
294
  )
273
295
  raise
274
296
 
@@ -310,15 +332,17 @@ class RabbitmqUtils:
310
332
  )
311
333
  except ChannelNotFoundEntity:
312
334
  # Exchange might not exist, which is fine
313
- logger.info(
314
- f"Exchange '{exchange_name}' does not exist, nothing to delete."
335
+ logger.debug(
336
+ "Exchange '%s' does not exist, nothing to delete.", exchange_name
315
337
  )
316
338
  except ChannelClosed as e:
317
339
  logger.warning(
318
- f"Channel closed while deleting exchange '{exchange_name}': {e}"
340
+ "Channel closed while deleting exchange '%s': %s", exchange_name, e
319
341
  )
320
342
  except AMQPError as e:
321
- logger.warning(f"AMQP error while deleting exchange '{exchange_name}': {e}")
343
+ logger.warning(
344
+ "AMQP error while deleting exchange '%s': %s", exchange_name, e
345
+ )
322
346
 
323
347
  @classmethod
324
348
  async def delete_queue(
@@ -339,8 +363,10 @@ class RabbitmqUtils:
339
363
  )
340
364
  except ChannelNotFoundEntity:
341
365
  # Queue might not exist, which is fine
342
- logger.info(f"Queue '{queue_name}' does not exist, nothing to delete.")
366
+ logger.debug("Queue '%s' does not exist, nothing to delete.", queue_name)
343
367
  except ChannelClosed as e:
344
- logger.warning(f"Channel closed while deleting queue '{queue_name}': {e}")
368
+ logger.warning(
369
+ "Channel closed while deleting queue '%s': %s", queue_name, e
370
+ )
345
371
  except AMQPError as e:
346
- logger.warning(f"AMQP error while deleting queue '{queue_name}': {e}")
372
+ logger.warning("AMQP error while deleting queue '%s': %s", queue_name, e)
jararaca/utils/retry.py CHANGED
@@ -1,3 +1,7 @@
1
+ # SPDX-FileCopyrightText: 2025 Lucas S
2
+ #
3
+ # SPDX-License-Identifier: GPL-3.0-or-later
4
+
1
5
  import asyncio
2
6
  import logging
3
7
  import random
@@ -80,7 +84,7 @@ async def retry_with_backoff(
80
84
 
81
85
  if retry_count >= retry_config.max_retries:
82
86
  logger.error(
83
- f"Max retries ({retry_config.max_retries}) exceeded: {str(e)}"
87
+ "Max retries (%s) exceeded: %s", retry_config.max_retries, e
84
88
  )
85
89
  raise
86
90
 
@@ -96,8 +100,11 @@ async def retry_with_backoff(
96
100
  delay = max(delay, 0.1)
97
101
 
98
102
  logger.warning(
99
- f"Retry {retry_count+1}/{retry_config.max_retries} after error: {str(e)}. "
100
- f"Retrying in {delay:.2f}s"
103
+ "Retry %s/%s after error: %s. Retrying in %.2fs",
104
+ retry_count + 1,
105
+ retry_config.max_retries,
106
+ e,
107
+ delay,
101
108
  )
102
109
 
103
110
  # Call the optional retry callback if provided