buz 2.25.0__tar.gz → 2.26.1__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 (277) hide show
  1. {buz-2.25.0 → buz-2.26.1}/PKG-INFO +1 -1
  2. {buz-2.25.0 → buz-2.26.1}/pyproject.toml +1 -1
  3. buz-2.26.1/src/buz/event/async_event_bus_with_publish_result.py +35 -0
  4. {buz-2.25.0 → buz-2.26.1}/src/buz/event/event.py +3 -1
  5. buz-2.26.1/src/buz/event/event_bus_publish_result.py +10 -0
  6. buz-2.26.1/src/buz/event/infrastructure/buz_kafka/async_buz_kafka_event_bus.py +48 -0
  7. buz-2.26.1/src/buz/event/infrastructure/buz_kafka/async_buz_kafka_event_bus_with_publish_result.py +80 -0
  8. buz-2.26.1/src/buz/event/infrastructure/buz_kafka/base_async_buz_kafka_event_bus.py +118 -0
  9. {buz-2.25.0 → buz-2.26.1}/src/buz/event/middleware/__init__.py +5 -0
  10. buz-2.26.1/src/buz/event/middleware/base_async_publish_middleware.py +27 -0
  11. {buz-2.25.0 → buz-2.26.1}/src/buz/event/strategies/retry/max_retries_consume_retrier.py +5 -3
  12. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/__init__.py +1 -2
  13. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/aiokafka/aiokafka_producer.py +1 -5
  14. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/kafka_python/kafka_python_admin_test_client.py +1 -2
  15. {buz-2.25.0 → buz-2.26.1}/src/buz/message.py +4 -1
  16. buz-2.25.0/src/buz/event/infrastructure/buz_kafka/async_buz_kafka_event_bus.py +0 -108
  17. {buz-2.25.0 → buz-2.26.1}/LICENSE +0 -0
  18. {buz-2.25.0 → buz-2.26.1}/README.md +0 -0
  19. {buz-2.25.0 → buz-2.26.1}/src/buz/__init__.py +0 -0
  20. {buz-2.25.0 → buz-2.26.1}/src/buz/command/__init__.py +0 -0
  21. {buz-2.25.0 → buz-2.26.1}/src/buz/command/asynchronous/__init__.py +0 -0
  22. {buz-2.25.0 → buz-2.26.1}/src/buz/command/asynchronous/base_command_handler.py +0 -0
  23. {buz-2.25.0 → buz-2.26.1}/src/buz/command/asynchronous/command_bus.py +0 -0
  24. {buz-2.25.0 → buz-2.26.1}/src/buz/command/asynchronous/command_handler.py +0 -0
  25. {buz-2.25.0 → buz-2.26.1}/src/buz/command/asynchronous/middleware/__init__.py +0 -0
  26. {buz-2.25.0 → buz-2.26.1}/src/buz/command/asynchronous/middleware/base_handle_middleware.py +0 -0
  27. {buz-2.25.0 → buz-2.26.1}/src/buz/command/asynchronous/middleware/handle_middleware.py +0 -0
  28. {buz-2.25.0 → buz-2.26.1}/src/buz/command/asynchronous/middleware/handle_middleware_chain_resolver.py +0 -0
  29. {buz-2.25.0 → buz-2.26.1}/src/buz/command/asynchronous/self_process/__init__.py +0 -0
  30. {buz-2.25.0 → buz-2.26.1}/src/buz/command/asynchronous/self_process/self_process_command_bus.py +0 -0
  31. {buz-2.25.0 → buz-2.26.1}/src/buz/command/command.py +0 -0
  32. {buz-2.25.0 → buz-2.26.1}/src/buz/command/more_than_one_command_handler_related_exception.py +0 -0
  33. {buz-2.25.0 → buz-2.26.1}/src/buz/command/synchronous/__init__.py +0 -0
  34. {buz-2.25.0 → buz-2.26.1}/src/buz/command/synchronous/base_command_handler.py +0 -0
  35. {buz-2.25.0 → buz-2.26.1}/src/buz/command/synchronous/command_bus.py +0 -0
  36. {buz-2.25.0 → buz-2.26.1}/src/buz/command/synchronous/command_handler.py +0 -0
  37. {buz-2.25.0 → buz-2.26.1}/src/buz/command/synchronous/middleware/__init__.py +0 -0
  38. {buz-2.25.0 → buz-2.26.1}/src/buz/command/synchronous/middleware/base_handle_middleware.py +0 -0
  39. {buz-2.25.0 → buz-2.26.1}/src/buz/command/synchronous/middleware/handle_middleware.py +0 -0
  40. {buz-2.25.0 → buz-2.26.1}/src/buz/command/synchronous/middleware/handle_middleware_chain_resolver.py +0 -0
  41. {buz-2.25.0 → buz-2.26.1}/src/buz/command/synchronous/self_process/__init__.py +0 -0
  42. {buz-2.25.0 → buz-2.26.1}/src/buz/command/synchronous/self_process/self_process_command_bus.py +0 -0
  43. {buz-2.25.0 → buz-2.26.1}/src/buz/command/synchronous/synced_async/__init__.py +0 -0
  44. {buz-2.25.0 → buz-2.26.1}/src/buz/command/synchronous/synced_async/synced_async_command_bus.py +0 -0
  45. {buz-2.25.0 → buz-2.26.1}/src/buz/event/__init__.py +0 -0
  46. {buz-2.25.0 → buz-2.26.1}/src/buz/event/async_consumer.py +0 -0
  47. {buz-2.25.0 → buz-2.26.1}/src/buz/event/async_event_bus.py +0 -0
  48. {buz-2.25.0 → buz-2.26.1}/src/buz/event/async_subscriber.py +0 -0
  49. {buz-2.25.0 → buz-2.26.1}/src/buz/event/async_worker.py +0 -0
  50. {buz-2.25.0 → buz-2.26.1}/src/buz/event/base_async_subscriber.py +0 -0
  51. {buz-2.25.0 → buz-2.26.1}/src/buz/event/base_subscriber.py +0 -0
  52. {buz-2.25.0 → buz-2.26.1}/src/buz/event/consumer.py +0 -0
  53. {buz-2.25.0 → buz-2.26.1}/src/buz/event/dead_letter_queue/__init__.py +0 -0
  54. {buz-2.25.0 → buz-2.26.1}/src/buz/event/dead_letter_queue/dlq_criteria.py +0 -0
  55. {buz-2.25.0 → buz-2.26.1}/src/buz/event/dead_letter_queue/dlq_record.py +0 -0
  56. {buz-2.25.0 → buz-2.26.1}/src/buz/event/dead_letter_queue/dlq_repository.py +0 -0
  57. {buz-2.25.0 → buz-2.26.1}/src/buz/event/event_bus.py +0 -0
  58. {buz-2.25.0 → buz-2.26.1}/src/buz/event/exceptions/__init__.py +0 -0
  59. {buz-2.25.0 → buz-2.26.1}/src/buz/event/exceptions/event_not_published_exception.py +0 -0
  60. {buz-2.25.0 → buz-2.26.1}/src/buz/event/exceptions/event_restore_exception.py +0 -0
  61. {buz-2.25.0 → buz-2.26.1}/src/buz/event/exceptions/subscribers_not_found_exception.py +0 -0
  62. {buz-2.25.0 → buz-2.26.1}/src/buz/event/exceptions/term_signal_interruption_exception.py +0 -0
  63. {buz-2.25.0 → buz-2.26.1}/src/buz/event/exceptions/worker_execution_exception.py +0 -0
  64. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/__init__.py +0 -0
  65. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/__init__.py +0 -0
  66. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/base_buz_aiokafka_async_consumer.py +0 -0
  67. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/buz_aiokafka_async_consumer.py +0 -0
  68. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/buz_aiokafka_multi_threaded_consumer.py +0 -0
  69. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/buz_kafka_event_bus.py +0 -0
  70. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/consume_strategy/__init__.py +0 -0
  71. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/consume_strategy/consume_strategy.py +0 -0
  72. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/consume_strategy/kafka_on_fail_strategy.py +0 -0
  73. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/consume_strategy/topic_and_subscription_group_per_subscriber_kafka_consumer_strategy.py +0 -0
  74. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/exceptions/__init__.py +0 -0
  75. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/exceptions/kafka_event_bus_config_not_valid_exception.py +0 -0
  76. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/exceptions/max_consumer_retry_exception.py +0 -0
  77. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/exceptions/retry_exception.py +0 -0
  78. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/kafka_event_async_subscriber_executor.py +0 -0
  79. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/kafka_event_subscriber_executor.py +0 -0
  80. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/kafka_event_sync_subscriber_executor.py +0 -0
  81. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/models/cdc_process_context.py +0 -0
  82. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/models/kafka_delivery_context.py +0 -0
  83. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/publish_strategy/__init__.py +0 -0
  84. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/publish_strategy/publish_strategy.py +0 -0
  85. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/buz_kafka/publish_strategy/topic_per_event_kafka_publish_strategy.py +0 -0
  86. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/kombu/__init__.py +0 -0
  87. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/kombu/allowed_kombu_serializer.py +0 -0
  88. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/kombu/consume_strategy/__init__.py +0 -0
  89. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/kombu/consume_strategy/consume_strategy.py +0 -0
  90. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/kombu/consume_strategy/queue_per_subscriber_consume_strategy.py +0 -0
  91. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/kombu/kombu_consumer.py +0 -0
  92. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/kombu/kombu_event_bus.py +0 -0
  93. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/kombu/models/kombu_delivery_context.py +0 -0
  94. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/kombu/publish_strategy/__init__.py +0 -0
  95. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/kombu/publish_strategy/fanout_exchange_per_event_publish_strategy.py +0 -0
  96. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/kombu/publish_strategy/publish_strategy.py +0 -0
  97. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/kombu/retry_strategy/__init__.py +0 -0
  98. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/kombu/retry_strategy/publish_retry_policy.py +0 -0
  99. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/kombu/retry_strategy/simple_publish_retry_policy.py +0 -0
  100. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/models/__init__.py +0 -0
  101. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/models/consuming_task.py +0 -0
  102. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/models/delivery_context.py +0 -0
  103. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/models/execution_context.py +0 -0
  104. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/models/process_context.py +0 -0
  105. {buz-2.25.0 → buz-2.26.1}/src/buz/event/infrastructure/queue/__init__.py +0 -0
  106. {buz-2.25.0 → buz-2.26.1}/src/buz/event/meta_base_subscriber.py +0 -0
  107. {buz-2.25.0 → buz-2.26.1}/src/buz/event/meta_subscriber.py +0 -0
  108. {buz-2.25.0 → buz-2.26.1}/src/buz/event/middleware/async_consume_middleware.py +0 -0
  109. {buz-2.25.0 → buz-2.26.1}/src/buz/event/middleware/async_consume_middleware_chain_resolver.py +0 -0
  110. {buz-2.25.0 → buz-2.26.1}/src/buz/event/middleware/async_publish_middleware.py +0 -0
  111. {buz-2.25.0 → buz-2.26.1}/src/buz/event/middleware/async_publish_middleware_chain_resolver.py +0 -0
  112. {buz-2.25.0 → buz-2.26.1}/src/buz/event/middleware/base_async_consume_middleware.py +0 -0
  113. {buz-2.25.0 → buz-2.26.1}/src/buz/event/middleware/base_consume_middleware.py +0 -0
  114. {buz-2.25.0 → buz-2.26.1}/src/buz/event/middleware/base_publish_middleware.py +0 -0
  115. {buz-2.25.0 → buz-2.26.1}/src/buz/event/middleware/consume_middleware.py +0 -0
  116. {buz-2.25.0 → buz-2.26.1}/src/buz/event/middleware/consume_middleware_chain_resolver.py +0 -0
  117. {buz-2.25.0 → buz-2.26.1}/src/buz/event/middleware/exceptions/__init__.py +0 -0
  118. {buz-2.25.0 → buz-2.26.1}/src/buz/event/middleware/exceptions/event_already_in_progress_exception.py +0 -0
  119. {buz-2.25.0 → buz-2.26.1}/src/buz/event/middleware/publish_middleware.py +0 -0
  120. {buz-2.25.0 → buz-2.26.1}/src/buz/event/middleware/publish_middleware_chain_resolver.py +0 -0
  121. {buz-2.25.0 → buz-2.26.1}/src/buz/event/strategies/__init__.py +0 -0
  122. {buz-2.25.0 → buz-2.26.1}/src/buz/event/strategies/execution_strategy/__init__.py +0 -0
  123. {buz-2.25.0 → buz-2.26.1}/src/buz/event/strategies/execution_strategy/async_execution_strategy.py +0 -0
  124. {buz-2.25.0 → buz-2.26.1}/src/buz/event/strategies/execution_strategy/async_self_process_execution_strategy.py +0 -0
  125. {buz-2.25.0 → buz-2.26.1}/src/buz/event/strategies/execution_strategy/cyclic_iterator_execution_strategy.py +0 -0
  126. {buz-2.25.0 → buz-2.26.1}/src/buz/event/strategies/execution_strategy/execution_strategy.py +0 -0
  127. {buz-2.25.0 → buz-2.26.1}/src/buz/event/strategies/execution_strategy/self_process_execution_strategy.py +0 -0
  128. {buz-2.25.0 → buz-2.26.1}/src/buz/event/strategies/retry/__init__.py +0 -0
  129. {buz-2.25.0 → buz-2.26.1}/src/buz/event/strategies/retry/consume_retrier.py +0 -0
  130. {buz-2.25.0 → buz-2.26.1}/src/buz/event/strategies/retry/consumed_event_retry.py +0 -0
  131. {buz-2.25.0 → buz-2.26.1}/src/buz/event/strategies/retry/consumed_event_retry_repository.py +0 -0
  132. {buz-2.25.0 → buz-2.26.1}/src/buz/event/strategies/retry/max_retries_negative_exception.py +0 -0
  133. {buz-2.25.0 → buz-2.26.1}/src/buz/event/strategies/retry/reject_callback.py +0 -0
  134. {buz-2.25.0 → buz-2.26.1}/src/buz/event/subscriber.py +0 -0
  135. {buz-2.25.0 → buz-2.26.1}/src/buz/event/sync/__init__.py +0 -0
  136. {buz-2.25.0 → buz-2.26.1}/src/buz/event/sync/models/__init__.py +0 -0
  137. {buz-2.25.0 → buz-2.26.1}/src/buz/event/sync/models/sync_delivery_context.py +0 -0
  138. {buz-2.25.0 → buz-2.26.1}/src/buz/event/sync/sync_event_bus.py +0 -0
  139. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/__init__.py +0 -0
  140. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/event_to_outbox_record_translator.py +0 -0
  141. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/fqn_to_event_mapper.py +0 -0
  142. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_criteria/__init__.py +0 -0
  143. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_criteria/deliverable_records_outbox_criteria_factory.py +0 -0
  144. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_criteria/outbox_criteria.py +0 -0
  145. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_criteria/outbox_criteria_factory.py +0 -0
  146. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_criteria/outbox_sorting_criteria.py +0 -0
  147. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_record.py +0 -0
  148. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_record_finder/__init__.py +0 -0
  149. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_record_finder/outbox_record_stream_finder.py +0 -0
  150. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_record_finder/polling_outbox_record_stream_finder.py +0 -0
  151. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_record_to_event_translator.py +0 -0
  152. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_record_validation/__init__.py +0 -0
  153. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_record_validation/abstract_outbox_record_validator.py +0 -0
  154. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_record_validation/outbox_record_size_not_allowed_exception.py +0 -0
  155. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_record_validation/outbox_record_validation_exception.py +0 -0
  156. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_record_validation/outbox_record_validator.py +0 -0
  157. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_record_validation/size_outbox_record_validator.py +0 -0
  158. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/outbox_repository.py +0 -0
  159. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/transactional_outbox_event_bus.py +0 -0
  160. {buz-2.25.0 → buz-2.26.1}/src/buz/event/transactional_outbox/transactional_outbox_worker.py +0 -0
  161. {buz-2.25.0 → buz-2.26.1}/src/buz/event/worker.py +0 -0
  162. {buz-2.25.0 → buz-2.26.1}/src/buz/handler.py +0 -0
  163. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/exceptions/__init__.py +0 -0
  164. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/exceptions/consumer_group_not_found_exception.py +0 -0
  165. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/exceptions/not_all_partition_assigned_exception.py +0 -0
  166. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/exceptions/not_valid_kafka_message_exception.py +0 -0
  167. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/exceptions/not_valid_partition_number_exception.py +0 -0
  168. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/exceptions/topic_already_created_exception.py +0 -0
  169. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/exceptions/topic_not_found_exception.py +0 -0
  170. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/models/__init__.py +0 -0
  171. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/models/auto_create_topic_configuration.py +0 -0
  172. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/models/consumer_initial_offset_position.py +0 -0
  173. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/models/create_kafka_topic.py +0 -0
  174. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/models/kafka_connection_config.py +0 -0
  175. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/models/kafka_connection_credentials.py +0 -0
  176. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/models/kafka_connection_plain_text_credentials.py +0 -0
  177. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/models/kafka_connection_sasl_credentials.py +0 -0
  178. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/models/kafka_consumer_record.py +0 -0
  179. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/models/kafka_poll_record.py +0 -0
  180. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/models/kafka_supported_compression_type.py +0 -0
  181. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/models/kafka_supported_sasl_mechanisms.py +0 -0
  182. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/models/kafka_supported_security_protocols.py +0 -0
  183. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/services/__init__.py +0 -0
  184. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/services/async_kafka_producer.py +0 -0
  185. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/services/kafka_admin_client.py +0 -0
  186. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/services/kafka_admin_test_client.py +0 -0
  187. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/domain/services/kafka_producer.py +0 -0
  188. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/__init__.py +0 -0
  189. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/aiokafka/__init__.py +0 -0
  190. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/aiokafka/aiokafka_consumer.py +0 -0
  191. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/aiokafka/rebalance/__init__.py +0 -0
  192. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/aiokafka/rebalance/kafka_callback_rebalancer.py +0 -0
  193. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/aiokafka/translators/__init__.py +0 -0
  194. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/aiokafka/translators/consumer_initial_offset_position_translator.py +0 -0
  195. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/cdc/__init__.py +0 -0
  196. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/cdc/cdc_message.py +0 -0
  197. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/cdc/cdc_payload.py +0 -0
  198. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/cdc/cdc_schema.py +0 -0
  199. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/deserializers/__init__.py +0 -0
  200. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/deserializers/byte_deserializer.py +0 -0
  201. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/deserializers/bytes_to_message_deserializer.py +0 -0
  202. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/deserializers/implementations/__init__.py +0 -0
  203. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/deserializers/implementations/cdc/cannot_decode_cdc_message_exception.py +0 -0
  204. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/deserializers/implementations/cdc/cannot_restore_event_from_cdc_payload_exception.py +0 -0
  205. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/deserializers/implementations/cdc/cdc_record_bytes_to_cdc_payload_deserializer.py +0 -0
  206. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/deserializers/implementations/cdc/cdc_record_bytes_to_event_deserializer.py +0 -0
  207. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/deserializers/implementations/json_byte_deserializer.py +0 -0
  208. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/deserializers/implementations/json_bytes_to_message_deserializer.py +0 -0
  209. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/interfaces/__init__.py +0 -0
  210. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/interfaces/async_connection_manager.py +0 -0
  211. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/interfaces/connection_manager.py +0 -0
  212. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/kafka_python/__init__.py +0 -0
  213. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/kafka_python/exception/consumer_interrupted_exception.py +0 -0
  214. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/kafka_python/kafka_python_admin_client.py +0 -0
  215. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/kafka_python/kafka_python_producer.py +0 -0
  216. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/kafka_python/translators/__init__.py +0 -0
  217. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/kafka_python/translators/consumer_initial_offset_position_translator.py +0 -0
  218. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/serializers/byte_serializer.py +0 -0
  219. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/serializers/implementations/cdc_partition_key_serializer.py +0 -0
  220. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/serializers/implementations/cdc_record_bytes_to_event_serializer.py +0 -0
  221. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/serializers/implementations/json_byte_serializer.py +0 -0
  222. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/serializers/kafka_header_serializer.py +0 -0
  223. {buz-2.25.0 → buz-2.26.1}/src/buz/kafka/infrastructure/serializers/partitiion_key_generator.py +0 -0
  224. {buz-2.25.0 → buz-2.26.1}/src/buz/locator/__init__.py +0 -0
  225. {buz-2.25.0 → buz-2.26.1}/src/buz/locator/handler_fqn_not_found_exception.py +0 -0
  226. {buz-2.25.0 → buz-2.26.1}/src/buz/locator/locator.py +0 -0
  227. {buz-2.25.0 → buz-2.26.1}/src/buz/locator/message_fqn_not_found_exception.py +0 -0
  228. {buz-2.25.0 → buz-2.26.1}/src/buz/locator/pypendency/__init__.py +0 -0
  229. {buz-2.25.0 → buz-2.26.1}/src/buz/locator/pypendency/container_locator.py +0 -0
  230. {buz-2.25.0 → buz-2.26.1}/src/buz/locator/pypendency/container_locator_resolution_configuration.py +0 -0
  231. {buz-2.25.0 → buz-2.26.1}/src/buz/locator/pypendency/handler_not_found_exception.py +0 -0
  232. {buz-2.25.0 → buz-2.26.1}/src/buz/locator/pypendency/handler_not_registered_exception.py +0 -0
  233. {buz-2.25.0 → buz-2.26.1}/src/buz/locator/sync/__init__.py +0 -0
  234. {buz-2.25.0 → buz-2.26.1}/src/buz/locator/sync/handler_already_registered_exception.py +0 -0
  235. {buz-2.25.0 → buz-2.26.1}/src/buz/locator/sync/handler_not_registered_exception.py +0 -0
  236. {buz-2.25.0 → buz-2.26.1}/src/buz/locator/sync/instance_locator.py +0 -0
  237. {buz-2.25.0 → buz-2.26.1}/src/buz/metadata.py +0 -0
  238. {buz-2.25.0 → buz-2.26.1}/src/buz/middleware/__init__.py +0 -0
  239. {buz-2.25.0 → buz-2.26.1}/src/buz/middleware/middleware.py +0 -0
  240. {buz-2.25.0 → buz-2.26.1}/src/buz/middleware/middleware_chain_builder.py +0 -0
  241. {buz-2.25.0 → buz-2.26.1}/src/buz/py.typed +0 -0
  242. {buz-2.25.0 → buz-2.26.1}/src/buz/query/__init__.py +0 -0
  243. {buz-2.25.0 → buz-2.26.1}/src/buz/query/asynchronous/__init__.py +0 -0
  244. {buz-2.25.0 → buz-2.26.1}/src/buz/query/asynchronous/base_query_handler.py +0 -0
  245. {buz-2.25.0 → buz-2.26.1}/src/buz/query/asynchronous/middleware/__init__.py +0 -0
  246. {buz-2.25.0 → buz-2.26.1}/src/buz/query/asynchronous/middleware/base_handle_middleware.py +0 -0
  247. {buz-2.25.0 → buz-2.26.1}/src/buz/query/asynchronous/middleware/handle_middleware.py +0 -0
  248. {buz-2.25.0 → buz-2.26.1}/src/buz/query/asynchronous/middleware/handle_middleware_chain_resolver.py +0 -0
  249. {buz-2.25.0 → buz-2.26.1}/src/buz/query/asynchronous/query_bus.py +0 -0
  250. {buz-2.25.0 → buz-2.26.1}/src/buz/query/asynchronous/query_handler.py +0 -0
  251. {buz-2.25.0 → buz-2.26.1}/src/buz/query/asynchronous/self_process/__init__.py +0 -0
  252. {buz-2.25.0 → buz-2.26.1}/src/buz/query/asynchronous/self_process/self_process_query_bus.py +0 -0
  253. {buz-2.25.0 → buz-2.26.1}/src/buz/query/more_than_one_query_handler_related_exception.py +0 -0
  254. {buz-2.25.0 → buz-2.26.1}/src/buz/query/query.py +0 -0
  255. {buz-2.25.0 → buz-2.26.1}/src/buz/query/query_response.py +0 -0
  256. {buz-2.25.0 → buz-2.26.1}/src/buz/query/synchronous/__init__.py +0 -0
  257. {buz-2.25.0 → buz-2.26.1}/src/buz/query/synchronous/base_query_handler.py +0 -0
  258. {buz-2.25.0 → buz-2.26.1}/src/buz/query/synchronous/middleware/__init__.py +0 -0
  259. {buz-2.25.0 → buz-2.26.1}/src/buz/query/synchronous/middleware/base_handle_middleware.py +0 -0
  260. {buz-2.25.0 → buz-2.26.1}/src/buz/query/synchronous/middleware/handle_middleware.py +0 -0
  261. {buz-2.25.0 → buz-2.26.1}/src/buz/query/synchronous/middleware/handle_middleware_chain_resolver.py +0 -0
  262. {buz-2.25.0 → buz-2.26.1}/src/buz/query/synchronous/query_bus.py +0 -0
  263. {buz-2.25.0 → buz-2.26.1}/src/buz/query/synchronous/query_handler.py +0 -0
  264. {buz-2.25.0 → buz-2.26.1}/src/buz/query/synchronous/self_process/__init__.py +0 -0
  265. {buz-2.25.0 → buz-2.26.1}/src/buz/query/synchronous/self_process/self_process_query_bus.py +0 -0
  266. {buz-2.25.0 → buz-2.26.1}/src/buz/query/synchronous/synced_async/__init__.py +0 -0
  267. {buz-2.25.0 → buz-2.26.1}/src/buz/query/synchronous/synced_async/synced_async_query_bus.py +0 -0
  268. {buz-2.25.0 → buz-2.26.1}/src/buz/queue/__init__.py +0 -0
  269. {buz-2.25.0 → buz-2.26.1}/src/buz/queue/in_memory/in_memory_multiqueue_repository.py +0 -0
  270. {buz-2.25.0 → buz-2.26.1}/src/buz/queue/in_memory/in_memory_queue_repository.py +0 -0
  271. {buz-2.25.0 → buz-2.26.1}/src/buz/queue/multiqueue_repository.py +0 -0
  272. {buz-2.25.0 → buz-2.26.1}/src/buz/queue/queue_repository.py +0 -0
  273. {buz-2.25.0 → buz-2.26.1}/src/buz/serializer/message_to_bytes_serializer.py +0 -0
  274. {buz-2.25.0 → buz-2.26.1}/src/buz/serializer/message_to_json_bytes_serializer.py +0 -0
  275. {buz-2.25.0 → buz-2.26.1}/src/buz/wrapper/__init__.py +0 -0
  276. {buz-2.25.0 → buz-2.26.1}/src/buz/wrapper/async_to_sync.py +0 -0
  277. {buz-2.25.0 → buz-2.26.1}/src/buz/wrapper/event_loop.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: buz
3
- Version: 2.25.0
3
+ Version: 2.26.1
4
4
  Summary: Buz is a set of light, simple and extensible implementations of event, command and query buses.
5
5
  License: MIT
6
6
  Author: Luis Pintado Lozano
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "buz"
3
- version = "2.25.0"
3
+ version = "2.26.1"
4
4
  description = "Buz is a set of light, simple and extensible implementations of event, command and query buses."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -0,0 +1,35 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Collection
3
+
4
+ from buz.event import Event
5
+ from buz.event.event_bus_publish_result import EventBusPublishResult
6
+ from buz.kafka.infrastructure.interfaces.async_connection_manager import AsyncConnectionManager
7
+
8
+
9
+ class AsyncEventBusWithPublishResult(AsyncConnectionManager, ABC):
10
+ """
11
+ Event bus with publish result tracking capabilities.
12
+
13
+ Unlike AsyncEventBus which returns None, this event bus returns
14
+ EventBusPublishResult to report which events succeeded and which failed.
15
+
16
+ This enables:
17
+ - Partial success tracking
18
+ - Fail-fast behavior with precise tracking
19
+ - Application-level retry control
20
+ - Better observability
21
+ """
22
+
23
+ @abstractmethod
24
+ async def publish(self, event: Event) -> None:
25
+ pass
26
+
27
+ @abstractmethod
28
+ async def bulk_publish(self, events: Collection[Event]) -> EventBusPublishResult:
29
+ """
30
+ Publish multiple events and return detailed results.
31
+
32
+ Returns:
33
+ EventBusPublishResult containing published_events and failed_events
34
+ """
35
+ pass
@@ -1,6 +1,8 @@
1
1
  from dataclasses import dataclass
2
2
 
3
- from buz import Message
3
+ from buz.message import Message, MessageId
4
+
5
+ EventId = MessageId
4
6
 
5
7
 
6
8
  @dataclass(frozen=True)
@@ -0,0 +1,10 @@
1
+ from dataclasses import dataclass
2
+ from typing import Collection
3
+
4
+ from buz.event import Event
5
+
6
+
7
+ @dataclass
8
+ class EventBusPublishResult:
9
+ published_events: Collection[Event]
10
+ failed_events: Collection[Event]
@@ -0,0 +1,48 @@
1
+ from logging import Logger
2
+ from typing import Collection, Optional
3
+
4
+ from buz.event import Event
5
+ from buz.event.async_event_bus import AsyncEventBus
6
+ from buz.event.infrastructure.buz_kafka.base_async_buz_kafka_event_bus import BaseAsyncBuzKafkaEventBus
7
+ from buz.event.infrastructure.buz_kafka.publish_strategy.publish_strategy import KafkaPublishStrategy
8
+ from buz.event.middleware.async_publish_middleware import AsyncPublishMiddleware
9
+ from buz.kafka.domain.models.auto_create_topic_configuration import AutoCreateTopicConfiguration
10
+ from buz.kafka.domain.services.async_kafka_producer import AsyncKafkaProducer
11
+ from buz.kafka.domain.services.kafka_admin_client import KafkaAdminClient
12
+ from buz.kafka.infrastructure.serializers.partitiion_key_generator import PartitionKeySerializer
13
+
14
+
15
+ class AsyncBuzKafkaEventBus(BaseAsyncBuzKafkaEventBus, AsyncEventBus):
16
+ """
17
+ Async Kafka event bus with simple behavior (consistent with sync version).
18
+
19
+ - Returns None from bulk_publish
20
+ - Raises exception on failure
21
+ - No retry logic
22
+ """
23
+
24
+ def __init__(
25
+ self,
26
+ *,
27
+ publish_strategy: KafkaPublishStrategy,
28
+ producer: AsyncKafkaProducer,
29
+ logger: Logger,
30
+ kafka_admin_client: Optional[KafkaAdminClient] = None,
31
+ publish_middlewares: Optional[list[AsyncPublishMiddleware]] = None,
32
+ auto_create_topic_configuration: Optional[AutoCreateTopicConfiguration] = None,
33
+ partition_key_generator: Optional[PartitionKeySerializer] = None,
34
+ ):
35
+ super().__init__(
36
+ publish_strategy=publish_strategy,
37
+ producer=producer,
38
+ logger=logger,
39
+ kafka_admin_client=kafka_admin_client,
40
+ publish_middlewares=publish_middlewares,
41
+ auto_create_topic_configuration=auto_create_topic_configuration,
42
+ partition_key_generator=partition_key_generator,
43
+ )
44
+
45
+ async def bulk_publish(self, events: Collection[Event]) -> None:
46
+ """Publish all events sequentially. Raises exception on first failure."""
47
+ for event in events:
48
+ await self.publish(event)
@@ -0,0 +1,80 @@
1
+ from logging import Logger
2
+ from typing import Collection, Optional
3
+
4
+ from buz.event import Event
5
+ from buz.event.async_event_bus_with_publish_result import AsyncEventBusWithPublishResult
6
+ from buz.event.event_bus_publish_result import EventBusPublishResult
7
+ from buz.event.infrastructure.buz_kafka.base_async_buz_kafka_event_bus import BaseAsyncBuzKafkaEventBus
8
+ from buz.event.infrastructure.buz_kafka.publish_strategy.publish_strategy import KafkaPublishStrategy
9
+ from buz.event.middleware.async_publish_middleware import AsyncPublishMiddleware
10
+ from buz.kafka.domain.models.auto_create_topic_configuration import AutoCreateTopicConfiguration
11
+ from buz.kafka.domain.services.async_kafka_producer import AsyncKafkaProducer
12
+ from buz.kafka.domain.services.kafka_admin_client import KafkaAdminClient
13
+ from buz.kafka.infrastructure.serializers.partitiion_key_generator import PartitionKeySerializer
14
+
15
+
16
+ class AsyncBuzKafkaEventBusWithPublishResult(BaseAsyncBuzKafkaEventBus, AsyncEventBusWithPublishResult):
17
+ """
18
+ Kafka event bus with publish result tracking and fail-fast behavior.
19
+
20
+ Features:
21
+ - Returns EventBusPublishResult with published/failed events
22
+ - Fail-fast behavior (stops on first failure)
23
+ - Partial success tracking for external state management
24
+ """
25
+
26
+ def __init__(
27
+ self,
28
+ *,
29
+ publish_strategy: KafkaPublishStrategy,
30
+ producer: AsyncKafkaProducer,
31
+ logger: Logger,
32
+ kafka_admin_client: Optional[KafkaAdminClient] = None,
33
+ publish_middlewares: Optional[list[AsyncPublishMiddleware]] = None,
34
+ auto_create_topic_configuration: Optional[AutoCreateTopicConfiguration] = None,
35
+ partition_key_generator: Optional[PartitionKeySerializer] = None,
36
+ ):
37
+ super().__init__(
38
+ publish_strategy=publish_strategy,
39
+ producer=producer,
40
+ logger=logger,
41
+ kafka_admin_client=kafka_admin_client,
42
+ publish_middlewares=publish_middlewares,
43
+ auto_create_topic_configuration=auto_create_topic_configuration,
44
+ partition_key_generator=partition_key_generator,
45
+ )
46
+
47
+ async def bulk_publish(self, events: Collection[Event]) -> EventBusPublishResult:
48
+ """
49
+ Publish events one by one with fail-fast behavior.
50
+
51
+ Publishes events sequentially. If any event fails, stops immediately and returns the result with:
52
+ - published_events: All events successfully published before the failure
53
+ - failed_events: The first event that failed (only one event)
54
+
55
+ This allows the caller to track which events were sent and which were not,
56
+ enabling proper state management in external systems.
57
+
58
+ Note: Kafka automatically handles partition assignment based on partition_key.
59
+ Events with the same partition_key will go to the same partition and maintain order.
60
+
61
+ Returns:
62
+ EventBusPublishResult with published_events and failed_events
63
+ """
64
+ published_events: list[Event] = []
65
+ failed_events: list[Event] = []
66
+
67
+ # FAIL-FAST: Stop on first failure
68
+ for event in events:
69
+ try:
70
+ await self.publish(event)
71
+ published_events.append(event)
72
+ except Exception as exc:
73
+ self._logger.error(f"Failed to publish event {event.id}. Error: {exc}")
74
+ failed_events.append(event)
75
+ break
76
+
77
+ return EventBusPublishResult(
78
+ published_events=published_events,
79
+ failed_events=failed_events,
80
+ )
@@ -0,0 +1,118 @@
1
+ from logging import Logger
2
+ from typing import Optional
3
+
4
+ from buz.event import Event
5
+ from buz.event.exceptions.event_not_published_exception import EventNotPublishedException
6
+ from buz.event.infrastructure.buz_kafka.exceptions.kafka_event_bus_config_not_valid_exception import (
7
+ KafkaEventBusConfigNotValidException,
8
+ )
9
+ from buz.event.infrastructure.buz_kafka.publish_strategy.publish_strategy import KafkaPublishStrategy
10
+ from buz.event.middleware.async_publish_middleware import AsyncPublishMiddleware
11
+ from buz.event.middleware.async_publish_middleware_chain_resolver import AsyncPublishMiddlewareChainResolver
12
+ from buz.kafka.domain.exceptions.topic_already_created_exception import KafkaTopicsAlreadyCreatedException
13
+ from buz.kafka.domain.models.auto_create_topic_configuration import AutoCreateTopicConfiguration
14
+ from buz.kafka.domain.models.create_kafka_topic import CreateKafkaTopic
15
+ from buz.kafka.domain.services.async_kafka_producer import AsyncKafkaProducer
16
+ from buz.kafka.domain.services.kafka_admin_client import KafkaAdminClient
17
+ from buz.kafka.infrastructure.serializers.implementations.cdc_partition_key_serializer import CDCPartitionKeySerializer
18
+ from buz.kafka.infrastructure.serializers.partitiion_key_generator import PartitionKeySerializer
19
+
20
+
21
+ class BaseAsyncBuzKafkaEventBus:
22
+ """
23
+ Base class for async Kafka event buses with common functionality.
24
+
25
+ Provides:
26
+ - Event publishing with middleware support
27
+ - Topic auto-creation
28
+ - Partition key generation
29
+ - Connection management
30
+ """
31
+
32
+ def __init__(
33
+ self,
34
+ *,
35
+ publish_strategy: KafkaPublishStrategy,
36
+ producer: AsyncKafkaProducer,
37
+ logger: Logger,
38
+ kafka_admin_client: Optional[KafkaAdminClient] = None,
39
+ publish_middlewares: Optional[list[AsyncPublishMiddleware]] = None,
40
+ auto_create_topic_configuration: Optional[AutoCreateTopicConfiguration] = None,
41
+ partition_key_generator: Optional[PartitionKeySerializer] = None,
42
+ ):
43
+ self._publish_middleware_chain_resolver = AsyncPublishMiddlewareChainResolver(publish_middlewares or [])
44
+ self._publish_strategy = publish_strategy
45
+ self._producer = producer
46
+ self._topics_checked: dict[str, bool] = {}
47
+ self._kafka_admin_client = kafka_admin_client
48
+ self._auto_create_topic_configuration = auto_create_topic_configuration
49
+ self._logger = logger
50
+ self._partition_key_generator: PartitionKeySerializer = partition_key_generator or CDCPartitionKeySerializer()
51
+ self._check_kafka_admin_client_is_needed()
52
+
53
+ def _check_kafka_admin_client_is_needed(self) -> None:
54
+ if self._kafka_admin_client is None and self._auto_create_topic_configuration is not None:
55
+ raise KafkaEventBusConfigNotValidException(
56
+ "A KafkaAdminClient is needed to create topics when 'auto_create_topic_configuration' is set."
57
+ )
58
+
59
+ async def publish(self, event: Event) -> None:
60
+ """Publish a single event through the middleware chain."""
61
+ await self._publish_middleware_chain_resolver.resolve(event, self._perform_publish)
62
+
63
+ async def _perform_publish(self, event: Event) -> None:
64
+ try:
65
+ topic = self._publish_strategy.get_topic(event)
66
+
67
+ if self._auto_create_topic_configuration is not None and self._is_topic_created(topic) is False:
68
+ try:
69
+ self._logger.info(f"Creating missing topic: {topic}..")
70
+ self._get_kafka_admin_client().create_topics(
71
+ topics=[
72
+ CreateKafkaTopic(
73
+ name=topic,
74
+ partitions=self._auto_create_topic_configuration.partitions,
75
+ replication_factor=self._auto_create_topic_configuration.replication_factor,
76
+ configs=self._auto_create_topic_configuration.configs,
77
+ )
78
+ ]
79
+ )
80
+ self._logger.info(f"Created missing topic: {topic}")
81
+ self._topics_checked[topic] = True
82
+ except KafkaTopicsAlreadyCreatedException:
83
+ pass
84
+
85
+ headers = self._get_event_headers(event)
86
+ await self._producer.produce(
87
+ message=event,
88
+ headers=headers,
89
+ topic=topic,
90
+ partition_key=self._partition_key_generator.generate_key(event),
91
+ )
92
+ except Exception as exc:
93
+ raise EventNotPublishedException(event) from exc
94
+
95
+ def _get_kafka_admin_client(self) -> KafkaAdminClient:
96
+ if self._kafka_admin_client is None:
97
+ raise KafkaEventBusConfigNotValidException("KafkaAdminClient is not set.")
98
+ return self._kafka_admin_client
99
+
100
+ def _is_topic_created(self, topic: str) -> bool:
101
+ is_topic_created = self._topics_checked.get(topic, None)
102
+
103
+ if is_topic_created is not None:
104
+ return is_topic_created
105
+
106
+ is_topic_created = self._get_kafka_admin_client().is_topic_created(topic)
107
+ self._topics_checked[topic] = is_topic_created
108
+
109
+ return is_topic_created
110
+
111
+ def _get_event_headers(self, event: Event) -> dict:
112
+ return {"id": event.id}
113
+
114
+ async def connect(self) -> None:
115
+ await self._producer.connect()
116
+
117
+ async def disconnect(self) -> None:
118
+ await self._producer.disconnect()
@@ -1,10 +1,12 @@
1
1
  from buz.event.middleware.base_async_consume_middleware import BaseAsyncConsumeMiddleware
2
+ from buz.event.middleware.base_async_publish_middleware import BaseAsyncPublishMiddleware
2
3
  from buz.event.middleware.publish_middleware import PublishMiddleware, PublishCallable
3
4
  from buz.event.middleware.base_publish_middleware import BasePublishMiddleware
4
5
  from buz.event.middleware.publish_middleware_chain_resolver import PublishMiddlewareChainResolver
5
6
  from buz.event.middleware.consume_middleware import ConsumeMiddleware, ConsumeCallable
6
7
  from buz.event.middleware.base_consume_middleware import BaseConsumeMiddleware
7
8
  from buz.event.middleware.consume_middleware_chain_resolver import ConsumeMiddlewareChainResolver
9
+ from buz.event.middleware.async_publish_middleware import AsyncPublishMiddleware, AsyncPublishCallable
8
10
 
9
11
  __all__ = [
10
12
  "PublishMiddleware",
@@ -16,4 +18,7 @@ __all__ = [
16
18
  "BaseConsumeMiddleware",
17
19
  "ConsumeMiddlewareChainResolver",
18
20
  "BaseAsyncConsumeMiddleware",
21
+ "BaseAsyncPublishMiddleware",
22
+ "AsyncPublishMiddleware",
23
+ "AsyncPublishCallable",
19
24
  ]
@@ -0,0 +1,27 @@
1
+ from abc import abstractmethod
2
+
3
+ from buz.event import Event
4
+ from buz.event.middleware.async_publish_middleware import AsyncPublishCallable, AsyncPublishMiddleware
5
+
6
+
7
+ class BaseAsyncPublishMiddleware(AsyncPublishMiddleware):
8
+ """
9
+ Base class for async publish middlewares with before/after hooks.
10
+ Provides a template pattern for middleware that need to execute logic
11
+ before and after event publishing.
12
+ """
13
+
14
+ async def on_publish(self, event: Event, publish: AsyncPublishCallable) -> None:
15
+ await self._before_on_publish(event)
16
+ await publish(event)
17
+ await self._after_on_publish(event)
18
+
19
+ @abstractmethod
20
+ async def _before_on_publish(self, event: Event) -> None:
21
+ """Hook executed before publishing the event."""
22
+ pass
23
+
24
+ @abstractmethod
25
+ async def _after_on_publish(self, event: Event) -> None:
26
+ """Hook executed after publishing the event."""
27
+ pass
@@ -15,9 +15,9 @@ class MaxRetriesConsumeRetrier(ConsumeRetrier):
15
15
  ):
16
16
  self.__consumed_event_retry_repository = consumed_event_retry_repository
17
17
  self.__max_retries = max_retries
18
- self.__check_max_retries_positive()
18
+ self.__validate_retries()
19
19
 
20
- def __check_max_retries_positive(self) -> None:
20
+ def __validate_retries(self) -> None:
21
21
  if self.__max_retries < 0:
22
22
  raise InvalidMaxRetriesParamException(self.__max_retries)
23
23
 
@@ -26,7 +26,9 @@ class MaxRetriesConsumeRetrier(ConsumeRetrier):
26
26
  event,
27
27
  subscribers,
28
28
  )
29
- return consumed_event_retry.retries < self.__max_retries
29
+
30
+ # The number of executions is 1 (the initial execution) + the number of retries
31
+ return consumed_event_retry.retries < (self.__max_retries + 1)
30
32
 
31
33
  def register_retry(self, event: Event, subscribers: Sequence[MetaSubscriber]) -> None:
32
34
  consumed_event_retry = self.__consumed_event_retry_repository.find_one_by_event_and_subscriber(
@@ -22,10 +22,10 @@ from buz.kafka.infrastructure.kafka_python.kafka_python_producer import KafkaPyt
22
22
  from buz.kafka.infrastructure.serializers.byte_serializer import ByteSerializer
23
23
  from buz.kafka.infrastructure.serializers.implementations.json_byte_serializer import JSONByteSerializer
24
24
  from buz.kafka.domain.models.kafka_supported_compression_type import KafkaSupportedCompressionType
25
+
25
26
  from buz.event.infrastructure.buz_kafka.exceptions.kafka_event_bus_config_not_valid_exception import (
26
27
  KafkaEventBusConfigNotValidException,
27
28
  )
28
- from buz.event.infrastructure.buz_kafka.async_buz_kafka_event_bus import AsyncBuzKafkaEventBus
29
29
  from buz.event.infrastructure.buz_kafka.buz_kafka_event_bus import BuzKafkaEventBus
30
30
 
31
31
 
@@ -46,7 +46,6 @@ __all__ = [
46
46
  "ConsumerInitialOffsetPosition",
47
47
  "KafkaSupportedCompressionType",
48
48
  "KafkaEventBusConfigNotValidException",
49
- "AsyncBuzKafkaEventBus",
50
49
  "BuzKafkaEventBus",
51
50
  "AutoCreateTopicConfiguration",
52
51
  "NotAllPartitionAssignedException",
@@ -52,6 +52,7 @@ class AIOKafkaProducer(AsyncKafkaProducer, Generic[T]):
52
52
  self.__kafka_producer = NativeAIOKafkaProducer(
53
53
  client_id=self.__connection_config.client_id,
54
54
  bootstrap_servers=",".join(self.__connection_config.bootstrap_servers),
55
+ security_protocol=self.__connection_config.credentials.security_protocol.value,
55
56
  sasl_mechanism=sasl_mechanism,
56
57
  ssl_context=ssl_context,
57
58
  sasl_plain_username=self.__connection_config.credentials.user,
@@ -91,8 +92,3 @@ class AIOKafkaProducer(AsyncKafkaProducer, Generic[T]):
91
92
  headers=serialized_headers,
92
93
  key=partition_key.encode("utf-8") if partition_key else None,
93
94
  )
94
-
95
- async def close(self) -> None:
96
- if self.__kafka_producer is not None:
97
- await self.__kafka_producer.stop()
98
- self.__kafka_producer = None
@@ -79,8 +79,7 @@ class KafkaPythonAdminTestClient(KafkaPythonAdminClient, KafkaAdminTestClient):
79
79
  )
80
80
 
81
81
  consumer.close()
82
-
83
- topic_records = records[0] if len(records) > 0 else []
82
+ topic_records = list(sum(records, []))
84
83
 
85
84
  return topic_records
86
85
 
@@ -3,7 +3,7 @@ from dataclasses import field, dataclass
3
3
  from datetime import datetime
4
4
  from inspect import signature, Parameter
5
5
  from types import MappingProxyType
6
- from typing import Any, ClassVar, get_origin, get_args, Union
6
+ from typing import Any, ClassVar, NewType, get_origin, get_args, Union
7
7
  from typing_extensions import Self
8
8
 
9
9
  from uuid_utils.compat import uuid7
@@ -11,6 +11,9 @@ from uuid_utils.compat import uuid7
11
11
  from buz.metadata import Metadata
12
12
 
13
13
 
14
+ MessageId = NewType("MessageId", str)
15
+
16
+
14
17
  @dataclass(frozen=True)
15
18
  class Message(ABC):
16
19
  DATE_TIME_FORMAT: ClassVar[str] = "%Y-%m-%d %H:%M:%S.%f"
@@ -1,108 +0,0 @@
1
- from logging import Logger
2
- from typing import Collection, Optional
3
-
4
- from buz.event import Event
5
- from buz.event.async_event_bus import AsyncEventBus
6
- from buz.event.exceptions.event_not_published_exception import EventNotPublishedException
7
- from buz.event.infrastructure.buz_kafka.exceptions.kafka_event_bus_config_not_valid_exception import (
8
- KafkaEventBusConfigNotValidException,
9
- )
10
- from buz.event.infrastructure.buz_kafka.publish_strategy.publish_strategy import KafkaPublishStrategy
11
- from buz.event.middleware.async_publish_middleware import AsyncPublishMiddleware
12
- from buz.event.middleware.async_publish_middleware_chain_resolver import AsyncPublishMiddlewareChainResolver
13
- from buz.kafka.domain.exceptions.topic_already_created_exception import KafkaTopicsAlreadyCreatedException
14
- from buz.kafka.domain.models.auto_create_topic_configuration import AutoCreateTopicConfiguration
15
- from buz.kafka.domain.models.create_kafka_topic import CreateKafkaTopic
16
- from buz.kafka.domain.services.async_kafka_producer import AsyncKafkaProducer
17
- from buz.kafka.domain.services.kafka_admin_client import KafkaAdminClient
18
-
19
-
20
- class AsyncBuzKafkaEventBus(AsyncEventBus):
21
- def __init__(
22
- self,
23
- *,
24
- publish_strategy: KafkaPublishStrategy,
25
- producer: AsyncKafkaProducer,
26
- logger: Logger,
27
- kafka_admin_client: Optional[KafkaAdminClient] = None,
28
- publish_middlewares: Optional[list[AsyncPublishMiddleware]] = None,
29
- auto_create_topic_configuration: Optional[AutoCreateTopicConfiguration] = None,
30
- ):
31
- self.__publish_middleware_chain_resolver = AsyncPublishMiddlewareChainResolver(publish_middlewares or [])
32
- self.__publish_strategy = publish_strategy
33
- self.__producer = producer
34
- self.__topics_checked: dict[str, bool] = {}
35
- self.__kafka_admin_client = kafka_admin_client
36
- self.__auto_create_topic_configuration = auto_create_topic_configuration
37
- self.__logger = logger
38
- self.__check_kafka_admin_client_is_needed()
39
-
40
- def __check_kafka_admin_client_is_needed(self) -> None:
41
- if self.__kafka_admin_client is None and self.__auto_create_topic_configuration is not None:
42
- raise KafkaEventBusConfigNotValidException(
43
- "A KafkaAdminClient is needed to create topics when 'auto_create_topic_configuration' is set."
44
- )
45
-
46
- async def publish(self, event: Event) -> None:
47
- await self.__publish_middleware_chain_resolver.resolve(event, self.__perform_publish)
48
-
49
- async def __perform_publish(self, event: Event) -> None:
50
- try:
51
- topic = self.__publish_strategy.get_topic(event)
52
-
53
- if self.__auto_create_topic_configuration is not None and self.__is_topic_created(topic) is False:
54
- try:
55
- self.__logger.info(f"Creating missing topic: {topic}..")
56
- self.__get_kafka_admin_client().create_topics(
57
- topics=[
58
- CreateKafkaTopic(
59
- name=topic,
60
- partitions=self.__auto_create_topic_configuration.partitions,
61
- replication_factor=self.__auto_create_topic_configuration.replication_factor,
62
- configs=self.__auto_create_topic_configuration.configs,
63
- )
64
- ]
65
- )
66
- self.__logger.info(f"Created missing topic: {topic}")
67
- self.__topics_checked[topic] = True
68
- except KafkaTopicsAlreadyCreatedException:
69
- pass
70
-
71
- headers = self.__get_event_headers(event)
72
- await self.__producer.produce(
73
- message=event,
74
- headers=headers,
75
- topic=topic,
76
- partition_key=event.partition_key(),
77
- )
78
- except Exception as exc:
79
- raise EventNotPublishedException(event) from exc
80
-
81
- def __get_kafka_admin_client(self) -> KafkaAdminClient:
82
- if self.__kafka_admin_client is None:
83
- raise KafkaEventBusConfigNotValidException("KafkaAdminClient is not set.")
84
- return self.__kafka_admin_client
85
-
86
- def __is_topic_created(self, topic: str) -> bool:
87
- is_topic_created = self.__topics_checked.get(topic, None)
88
-
89
- if is_topic_created is not None:
90
- return is_topic_created
91
-
92
- is_topic_created = self.__get_kafka_admin_client().is_topic_created(topic)
93
- self.__topics_checked[topic] = is_topic_created
94
-
95
- return is_topic_created
96
-
97
- async def bulk_publish(self, events: Collection[Event]) -> None:
98
- for event in events:
99
- await self.publish(event)
100
-
101
- def __get_event_headers(self, event: Event) -> dict:
102
- return {"id": event.id}
103
-
104
- async def connect(self) -> None:
105
- await self.__producer.connect()
106
-
107
- async def disconnect(self) -> None:
108
- await self.__producer.disconnect()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes