buz 2.15.12__tar.gz → 2.17.0__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 (270) hide show
  1. {buz-2.15.12 → buz-2.17.0}/PKG-INFO +2 -4
  2. {buz-2.15.12 → buz-2.17.0}/pyproject.toml +22 -19
  3. buz-2.17.0/src/buz/event/async_subscriber.py +13 -0
  4. buz-2.17.0/src/buz/event/base_async_subscriber.py +12 -0
  5. buz-2.17.0/src/buz/event/base_subscriber.py +12 -0
  6. {buz-2.15.12 → buz-2.17.0}/src/buz/event/meta_base_subscriber.py +10 -7
  7. buz-2.17.0/src/buz/event/meta_subscriber.py +18 -0
  8. buz-2.17.0/src/buz/event/subscriber.py +13 -0
  9. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/event_to_outbox_record_translator.py +2 -0
  10. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_record.py +1 -0
  11. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_record_to_event_translator.py +1 -0
  12. buz-2.17.0/src/buz/event/transactional_outbox/transactional_outbox_event_bus.py +56 -0
  13. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/cdc/cdc_payload.py +4 -0
  14. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/cdc/cdc_schema.py +7 -0
  15. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/deserializers/implementations/cdc/cdc_record_bytes_to_event_deserializer.py +7 -1
  16. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/serializers/implementations/cdc_record_bytes_to_event_serializer.py +6 -1
  17. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/serializers/implementations/json_byte_serializer.py +3 -1
  18. {buz-2.15.12 → buz-2.17.0}/src/buz/message.py +9 -0
  19. buz-2.17.0/src/buz/metadata.py +8 -0
  20. {buz-2.15.12 → buz-2.17.0}/src/buz/query/asynchronous/query_handler.py +3 -4
  21. buz-2.15.12/src/buz/event/async_subscriber.py +0 -10
  22. buz-2.15.12/src/buz/event/base_async_subscriber.py +0 -8
  23. buz-2.15.12/src/buz/event/base_subscriber.py +0 -7
  24. buz-2.15.12/src/buz/event/meta_subscriber.py +0 -16
  25. buz-2.15.12/src/buz/event/subscriber.py +0 -10
  26. buz-2.15.12/src/buz/event/transactional_outbox/transactional_outbox_event_bus.py +0 -34
  27. {buz-2.15.12 → buz-2.17.0}/LICENSE +0 -0
  28. {buz-2.15.12 → buz-2.17.0}/README.md +0 -0
  29. {buz-2.15.12 → buz-2.17.0}/src/buz/__init__.py +0 -0
  30. {buz-2.15.12 → buz-2.17.0}/src/buz/command/__init__.py +0 -0
  31. {buz-2.15.12 → buz-2.17.0}/src/buz/command/asynchronous/__init__.py +0 -0
  32. {buz-2.15.12 → buz-2.17.0}/src/buz/command/asynchronous/base_command_handler.py +0 -0
  33. {buz-2.15.12 → buz-2.17.0}/src/buz/command/asynchronous/command_bus.py +0 -0
  34. {buz-2.15.12 → buz-2.17.0}/src/buz/command/asynchronous/command_handler.py +0 -0
  35. {buz-2.15.12 → buz-2.17.0}/src/buz/command/asynchronous/middleware/__init__.py +0 -0
  36. {buz-2.15.12 → buz-2.17.0}/src/buz/command/asynchronous/middleware/base_handle_middleware.py +0 -0
  37. {buz-2.15.12 → buz-2.17.0}/src/buz/command/asynchronous/middleware/handle_middleware.py +0 -0
  38. {buz-2.15.12 → buz-2.17.0}/src/buz/command/asynchronous/middleware/handle_middleware_chain_resolver.py +0 -0
  39. {buz-2.15.12 → buz-2.17.0}/src/buz/command/asynchronous/self_process/__init__.py +0 -0
  40. {buz-2.15.12 → buz-2.17.0}/src/buz/command/asynchronous/self_process/self_process_command_bus.py +0 -0
  41. {buz-2.15.12 → buz-2.17.0}/src/buz/command/command.py +0 -0
  42. {buz-2.15.12 → buz-2.17.0}/src/buz/command/more_than_one_command_handler_related_exception.py +0 -0
  43. {buz-2.15.12 → buz-2.17.0}/src/buz/command/synchronous/__init__.py +0 -0
  44. {buz-2.15.12 → buz-2.17.0}/src/buz/command/synchronous/base_command_handler.py +0 -0
  45. {buz-2.15.12 → buz-2.17.0}/src/buz/command/synchronous/command_bus.py +0 -0
  46. {buz-2.15.12 → buz-2.17.0}/src/buz/command/synchronous/command_handler.py +0 -0
  47. {buz-2.15.12 → buz-2.17.0}/src/buz/command/synchronous/middleware/__init__.py +0 -0
  48. {buz-2.15.12 → buz-2.17.0}/src/buz/command/synchronous/middleware/base_handle_middleware.py +0 -0
  49. {buz-2.15.12 → buz-2.17.0}/src/buz/command/synchronous/middleware/handle_middleware.py +0 -0
  50. {buz-2.15.12 → buz-2.17.0}/src/buz/command/synchronous/middleware/handle_middleware_chain_resolver.py +0 -0
  51. {buz-2.15.12 → buz-2.17.0}/src/buz/command/synchronous/self_process/__init__.py +0 -0
  52. {buz-2.15.12 → buz-2.17.0}/src/buz/command/synchronous/self_process/self_process_command_bus.py +0 -0
  53. {buz-2.15.12 → buz-2.17.0}/src/buz/command/synchronous/synced_async/__init__.py +0 -0
  54. {buz-2.15.12 → buz-2.17.0}/src/buz/command/synchronous/synced_async/synced_async_command_bus.py +0 -0
  55. {buz-2.15.12 → buz-2.17.0}/src/buz/event/__init__.py +0 -0
  56. {buz-2.15.12 → buz-2.17.0}/src/buz/event/async_consumer.py +0 -0
  57. {buz-2.15.12 → buz-2.17.0}/src/buz/event/async_event_bus.py +0 -0
  58. {buz-2.15.12 → buz-2.17.0}/src/buz/event/async_worker.py +0 -0
  59. {buz-2.15.12 → buz-2.17.0}/src/buz/event/consumer.py +0 -0
  60. {buz-2.15.12 → buz-2.17.0}/src/buz/event/dead_letter_queue/__init__.py +0 -0
  61. {buz-2.15.12 → buz-2.17.0}/src/buz/event/dead_letter_queue/dlq_criteria.py +0 -0
  62. {buz-2.15.12 → buz-2.17.0}/src/buz/event/dead_letter_queue/dlq_record.py +0 -0
  63. {buz-2.15.12 → buz-2.17.0}/src/buz/event/dead_letter_queue/dlq_repository.py +0 -0
  64. {buz-2.15.12 → buz-2.17.0}/src/buz/event/event.py +0 -0
  65. {buz-2.15.12 → buz-2.17.0}/src/buz/event/event_bus.py +0 -0
  66. {buz-2.15.12 → buz-2.17.0}/src/buz/event/exceptions/__init__.py +0 -0
  67. {buz-2.15.12 → buz-2.17.0}/src/buz/event/exceptions/event_not_published_exception.py +0 -0
  68. {buz-2.15.12 → buz-2.17.0}/src/buz/event/exceptions/event_restore_exception.py +0 -0
  69. {buz-2.15.12 → buz-2.17.0}/src/buz/event/exceptions/subscribers_not_found_exception.py +0 -0
  70. {buz-2.15.12 → buz-2.17.0}/src/buz/event/exceptions/term_signal_interruption_exception.py +0 -0
  71. {buz-2.15.12 → buz-2.17.0}/src/buz/event/exceptions/worker_execution_exception.py +0 -0
  72. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/__init__.py +0 -0
  73. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/__init__.py +0 -0
  74. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/async_buz_kafka_event_bus.py +0 -0
  75. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/base_buz_aiokafka_async_consumer.py +0 -0
  76. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/buz_aiokafka_async_consumer.py +0 -0
  77. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/buz_aiokafka_multi_threaded_consumer.py +0 -0
  78. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/buz_kafka_event_bus.py +0 -0
  79. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/consume_strategy/__init__.py +0 -0
  80. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/consume_strategy/consume_strategy.py +0 -0
  81. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/consume_strategy/kafka_on_fail_strategy.py +0 -0
  82. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/consume_strategy/topic_and_subscription_group_per_subscriber_kafka_consumer_strategy.py +0 -0
  83. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/exceptions/__init__.py +0 -0
  84. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/exceptions/kafka_event_bus_config_not_valid_exception.py +0 -0
  85. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/exceptions/max_consumer_retry_exception.py +0 -0
  86. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/exceptions/retry_exception.py +0 -0
  87. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/kafka_event_async_subscriber_executor.py +0 -0
  88. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/kafka_event_subscriber_executor.py +0 -0
  89. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/kafka_event_sync_subscriber_executor.py +0 -0
  90. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/models/kafka_delivery_context.py +0 -0
  91. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/publish_strategy/__init__.py +0 -0
  92. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/publish_strategy/publish_strategy.py +0 -0
  93. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/buz_kafka/publish_strategy/topic_per_event_kafka_publish_strategy.py +0 -0
  94. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/kombu/__init__.py +0 -0
  95. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/kombu/allowed_kombu_serializer.py +0 -0
  96. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/kombu/consume_strategy/__init__.py +0 -0
  97. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/kombu/consume_strategy/consume_strategy.py +0 -0
  98. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/kombu/consume_strategy/queue_per_subscriber_consume_strategy.py +0 -0
  99. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/kombu/kombu_consumer.py +0 -0
  100. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/kombu/kombu_event_bus.py +0 -0
  101. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/kombu/models/kombu_delivery_context.py +0 -0
  102. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/kombu/publish_strategy/__init__.py +0 -0
  103. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/kombu/publish_strategy/fanout_exchange_per_event_publish_strategy.py +0 -0
  104. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/kombu/publish_strategy/publish_strategy.py +0 -0
  105. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/kombu/retry_strategy/__init__.py +0 -0
  106. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/kombu/retry_strategy/publish_retry_policy.py +0 -0
  107. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/kombu/retry_strategy/simple_publish_retry_policy.py +0 -0
  108. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/models/__init__.py +0 -0
  109. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/models/consuming_task.py +0 -0
  110. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/models/delivery_context.py +0 -0
  111. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/models/execution_context.py +0 -0
  112. {buz-2.15.12 → buz-2.17.0}/src/buz/event/infrastructure/queue/__init__.py +0 -0
  113. {buz-2.15.12 → buz-2.17.0}/src/buz/event/middleware/__init__.py +0 -0
  114. {buz-2.15.12 → buz-2.17.0}/src/buz/event/middleware/async_consume_middleware.py +0 -0
  115. {buz-2.15.12 → buz-2.17.0}/src/buz/event/middleware/async_consume_middleware_chain_resolver.py +0 -0
  116. {buz-2.15.12 → buz-2.17.0}/src/buz/event/middleware/async_publish_middleware.py +0 -0
  117. {buz-2.15.12 → buz-2.17.0}/src/buz/event/middleware/async_publish_middleware_chain_resolver.py +0 -0
  118. {buz-2.15.12 → buz-2.17.0}/src/buz/event/middleware/base_async_consume_middleware.py +0 -0
  119. {buz-2.15.12 → buz-2.17.0}/src/buz/event/middleware/base_consume_middleware.py +0 -0
  120. {buz-2.15.12 → buz-2.17.0}/src/buz/event/middleware/base_publish_middleware.py +0 -0
  121. {buz-2.15.12 → buz-2.17.0}/src/buz/event/middleware/consume_middleware.py +0 -0
  122. {buz-2.15.12 → buz-2.17.0}/src/buz/event/middleware/consume_middleware_chain_resolver.py +0 -0
  123. {buz-2.15.12 → buz-2.17.0}/src/buz/event/middleware/exceptions/__init__.py +0 -0
  124. {buz-2.15.12 → buz-2.17.0}/src/buz/event/middleware/exceptions/event_already_in_progress_exception.py +0 -0
  125. {buz-2.15.12 → buz-2.17.0}/src/buz/event/middleware/publish_middleware.py +0 -0
  126. {buz-2.15.12 → buz-2.17.0}/src/buz/event/middleware/publish_middleware_chain_resolver.py +0 -0
  127. {buz-2.15.12 → buz-2.17.0}/src/buz/event/strategies/__init__.py +0 -0
  128. {buz-2.15.12 → buz-2.17.0}/src/buz/event/strategies/execution_strategy/__init__.py +0 -0
  129. {buz-2.15.12 → buz-2.17.0}/src/buz/event/strategies/execution_strategy/async_execution_strategy.py +0 -0
  130. {buz-2.15.12 → buz-2.17.0}/src/buz/event/strategies/execution_strategy/async_self_process_execution_strategy.py +0 -0
  131. {buz-2.15.12 → buz-2.17.0}/src/buz/event/strategies/execution_strategy/cyclic_iterator_execution_strategy.py +0 -0
  132. {buz-2.15.12 → buz-2.17.0}/src/buz/event/strategies/execution_strategy/execution_strategy.py +0 -0
  133. {buz-2.15.12 → buz-2.17.0}/src/buz/event/strategies/execution_strategy/self_process_execution_strategy.py +0 -0
  134. {buz-2.15.12 → buz-2.17.0}/src/buz/event/strategies/retry/__init__.py +0 -0
  135. {buz-2.15.12 → buz-2.17.0}/src/buz/event/strategies/retry/consume_retrier.py +0 -0
  136. {buz-2.15.12 → buz-2.17.0}/src/buz/event/strategies/retry/consumed_event_retry.py +0 -0
  137. {buz-2.15.12 → buz-2.17.0}/src/buz/event/strategies/retry/consumed_event_retry_repository.py +0 -0
  138. {buz-2.15.12 → buz-2.17.0}/src/buz/event/strategies/retry/max_retries_consume_retrier.py +0 -0
  139. {buz-2.15.12 → buz-2.17.0}/src/buz/event/strategies/retry/max_retries_negative_exception.py +0 -0
  140. {buz-2.15.12 → buz-2.17.0}/src/buz/event/strategies/retry/reject_callback.py +0 -0
  141. {buz-2.15.12 → buz-2.17.0}/src/buz/event/sync/__init__.py +0 -0
  142. {buz-2.15.12 → buz-2.17.0}/src/buz/event/sync/models/__init__.py +0 -0
  143. {buz-2.15.12 → buz-2.17.0}/src/buz/event/sync/models/sync_delivery_context.py +0 -0
  144. {buz-2.15.12 → buz-2.17.0}/src/buz/event/sync/sync_event_bus.py +0 -0
  145. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/__init__.py +0 -0
  146. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/fqn_to_event_mapper.py +0 -0
  147. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_criteria/__init__.py +0 -0
  148. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_criteria/deliverable_records_outbox_criteria_factory.py +0 -0
  149. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_criteria/outbox_criteria.py +0 -0
  150. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_criteria/outbox_criteria_factory.py +0 -0
  151. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_criteria/outbox_sorting_criteria.py +0 -0
  152. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_record_finder/__init__.py +0 -0
  153. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_record_finder/outbox_record_stream_finder.py +0 -0
  154. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_record_finder/polling_outbox_record_stream_finder.py +0 -0
  155. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_record_validation/__init__.py +0 -0
  156. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_record_validation/abstract_outbox_record_validator.py +0 -0
  157. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_record_validation/outbox_record_size_not_allowed_exception.py +0 -0
  158. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_record_validation/outbox_record_validation_exception.py +0 -0
  159. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_record_validation/outbox_record_validator.py +0 -0
  160. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_record_validation/size_outbox_record_validator.py +0 -0
  161. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/outbox_repository.py +0 -0
  162. {buz-2.15.12 → buz-2.17.0}/src/buz/event/transactional_outbox/transactional_outbox_worker.py +0 -0
  163. {buz-2.15.12 → buz-2.17.0}/src/buz/event/worker.py +0 -0
  164. {buz-2.15.12 → buz-2.17.0}/src/buz/handler.py +0 -0
  165. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/__init__.py +0 -0
  166. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/exceptions/__init__.py +0 -0
  167. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/exceptions/not_all_partition_assigned_exception.py +0 -0
  168. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/exceptions/not_valid_kafka_message_exception.py +0 -0
  169. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/exceptions/not_valid_partition_number_exception.py +0 -0
  170. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/exceptions/topic_already_created_exception.py +0 -0
  171. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/exceptions/topic_not_found_exception.py +0 -0
  172. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/models/__init__.py +0 -0
  173. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/models/auto_create_topic_configuration.py +0 -0
  174. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/models/consumer_initial_offset_position.py +0 -0
  175. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/models/create_kafka_topic.py +0 -0
  176. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/models/kafka_connection_config.py +0 -0
  177. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/models/kafka_connection_credentials.py +0 -0
  178. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/models/kafka_connection_plain_text_credentials.py +0 -0
  179. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/models/kafka_connection_sasl_credentials.py +0 -0
  180. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/models/kafka_consumer_record.py +0 -0
  181. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/models/kafka_poll_record.py +0 -0
  182. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/models/kafka_supported_compression_type.py +0 -0
  183. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/models/kafka_supported_sasl_mechanisms.py +0 -0
  184. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/models/kafka_supported_security_protocols.py +0 -0
  185. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/services/__init__.py +0 -0
  186. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/services/async_kafka_producer.py +0 -0
  187. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/services/kafka_admin_client.py +0 -0
  188. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/services/kafka_admin_test_client.py +0 -0
  189. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/domain/services/kafka_producer.py +0 -0
  190. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/__init__.py +0 -0
  191. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/aiokafka/__init__.py +0 -0
  192. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/aiokafka/aiokafka_consumer.py +0 -0
  193. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/aiokafka/aiokafka_producer.py +0 -0
  194. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/aiokafka/rebalance/__init__.py +0 -0
  195. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/aiokafka/rebalance/kafka_callback_rebalancer.py +0 -0
  196. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/aiokafka/translators/__init__.py +0 -0
  197. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/aiokafka/translators/consumer_initial_offset_position_translator.py +0 -0
  198. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/cdc/__init__.py +0 -0
  199. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/cdc/cdc_message.py +0 -0
  200. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/deserializers/__init__.py +0 -0
  201. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/deserializers/byte_deserializer.py +0 -0
  202. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/deserializers/bytes_to_message_deserializer.py +0 -0
  203. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/deserializers/implementations/__init__.py +0 -0
  204. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/deserializers/implementations/cdc/not_valid_cdc_message_exception.py +0 -0
  205. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/deserializers/implementations/json_byte_deserializer.py +0 -0
  206. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/deserializers/implementations/json_bytes_to_message_deserializer.py +0 -0
  207. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/interfaces/__init__.py +0 -0
  208. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/interfaces/async_connection_manager.py +0 -0
  209. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/interfaces/connection_manager.py +0 -0
  210. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/kafka_python/__init__.py +0 -0
  211. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/kafka_python/exception/consumer_interrupted_exception.py +0 -0
  212. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/kafka_python/kafka_python_admin_client.py +0 -0
  213. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/kafka_python/kafka_python_admin_test_client.py +0 -0
  214. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/kafka_python/kafka_python_producer.py +0 -0
  215. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/kafka_python/translators/__init__.py +0 -0
  216. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/kafka_python/translators/consumer_initial_offset_position_translator.py +0 -0
  217. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/serializers/byte_serializer.py +0 -0
  218. {buz-2.15.12 → buz-2.17.0}/src/buz/kafka/infrastructure/serializers/kafka_header_serializer.py +0 -0
  219. {buz-2.15.12 → buz-2.17.0}/src/buz/locator/__init__.py +0 -0
  220. {buz-2.15.12 → buz-2.17.0}/src/buz/locator/handler_fqn_not_found_exception.py +0 -0
  221. {buz-2.15.12 → buz-2.17.0}/src/buz/locator/locator.py +0 -0
  222. {buz-2.15.12 → buz-2.17.0}/src/buz/locator/message_fqn_not_found_exception.py +0 -0
  223. {buz-2.15.12 → buz-2.17.0}/src/buz/locator/pypendency/__init__.py +0 -0
  224. {buz-2.15.12 → buz-2.17.0}/src/buz/locator/pypendency/container_locator.py +0 -0
  225. {buz-2.15.12 → buz-2.17.0}/src/buz/locator/pypendency/container_locator_resolution_configuration.py +0 -0
  226. {buz-2.15.12 → buz-2.17.0}/src/buz/locator/pypendency/handler_not_found_exception.py +0 -0
  227. {buz-2.15.12 → buz-2.17.0}/src/buz/locator/pypendency/handler_not_registered_exception.py +0 -0
  228. {buz-2.15.12 → buz-2.17.0}/src/buz/locator/sync/__init__.py +0 -0
  229. {buz-2.15.12 → buz-2.17.0}/src/buz/locator/sync/handler_already_registered_exception.py +0 -0
  230. {buz-2.15.12 → buz-2.17.0}/src/buz/locator/sync/handler_not_registered_exception.py +0 -0
  231. {buz-2.15.12 → buz-2.17.0}/src/buz/locator/sync/instance_locator.py +0 -0
  232. {buz-2.15.12 → buz-2.17.0}/src/buz/middleware/__init__.py +0 -0
  233. {buz-2.15.12 → buz-2.17.0}/src/buz/middleware/middleware.py +0 -0
  234. {buz-2.15.12 → buz-2.17.0}/src/buz/middleware/middleware_chain_builder.py +0 -0
  235. {buz-2.15.12 → buz-2.17.0}/src/buz/py.typed +0 -0
  236. {buz-2.15.12 → buz-2.17.0}/src/buz/query/__init__.py +0 -0
  237. {buz-2.15.12 → buz-2.17.0}/src/buz/query/asynchronous/__init__.py +0 -0
  238. {buz-2.15.12 → buz-2.17.0}/src/buz/query/asynchronous/base_query_handler.py +0 -0
  239. {buz-2.15.12 → buz-2.17.0}/src/buz/query/asynchronous/middleware/__init__.py +0 -0
  240. {buz-2.15.12 → buz-2.17.0}/src/buz/query/asynchronous/middleware/base_handle_middleware.py +0 -0
  241. {buz-2.15.12 → buz-2.17.0}/src/buz/query/asynchronous/middleware/handle_middleware.py +0 -0
  242. {buz-2.15.12 → buz-2.17.0}/src/buz/query/asynchronous/middleware/handle_middleware_chain_resolver.py +0 -0
  243. {buz-2.15.12 → buz-2.17.0}/src/buz/query/asynchronous/query_bus.py +0 -0
  244. {buz-2.15.12 → buz-2.17.0}/src/buz/query/asynchronous/self_process/__init__.py +0 -0
  245. {buz-2.15.12 → buz-2.17.0}/src/buz/query/asynchronous/self_process/self_process_query_bus.py +0 -0
  246. {buz-2.15.12 → buz-2.17.0}/src/buz/query/more_than_one_query_handler_related_exception.py +0 -0
  247. {buz-2.15.12 → buz-2.17.0}/src/buz/query/query.py +0 -0
  248. {buz-2.15.12 → buz-2.17.0}/src/buz/query/query_response.py +0 -0
  249. {buz-2.15.12 → buz-2.17.0}/src/buz/query/synchronous/__init__.py +0 -0
  250. {buz-2.15.12 → buz-2.17.0}/src/buz/query/synchronous/base_query_handler.py +0 -0
  251. {buz-2.15.12 → buz-2.17.0}/src/buz/query/synchronous/middleware/__init__.py +0 -0
  252. {buz-2.15.12 → buz-2.17.0}/src/buz/query/synchronous/middleware/base_handle_middleware.py +0 -0
  253. {buz-2.15.12 → buz-2.17.0}/src/buz/query/synchronous/middleware/handle_middleware.py +0 -0
  254. {buz-2.15.12 → buz-2.17.0}/src/buz/query/synchronous/middleware/handle_middleware_chain_resolver.py +0 -0
  255. {buz-2.15.12 → buz-2.17.0}/src/buz/query/synchronous/query_bus.py +0 -0
  256. {buz-2.15.12 → buz-2.17.0}/src/buz/query/synchronous/query_handler.py +0 -0
  257. {buz-2.15.12 → buz-2.17.0}/src/buz/query/synchronous/self_process/__init__.py +0 -0
  258. {buz-2.15.12 → buz-2.17.0}/src/buz/query/synchronous/self_process/self_process_query_bus.py +0 -0
  259. {buz-2.15.12 → buz-2.17.0}/src/buz/query/synchronous/synced_async/__init__.py +0 -0
  260. {buz-2.15.12 → buz-2.17.0}/src/buz/query/synchronous/synced_async/synced_async_query_bus.py +0 -0
  261. {buz-2.15.12 → buz-2.17.0}/src/buz/queue/__init__.py +0 -0
  262. {buz-2.15.12 → buz-2.17.0}/src/buz/queue/in_memory/in_memory_multiqueue_repository.py +0 -0
  263. {buz-2.15.12 → buz-2.17.0}/src/buz/queue/in_memory/in_memory_queue_repository.py +0 -0
  264. {buz-2.15.12 → buz-2.17.0}/src/buz/queue/multiqueue_repository.py +0 -0
  265. {buz-2.15.12 → buz-2.17.0}/src/buz/queue/queue_repository.py +0 -0
  266. {buz-2.15.12 → buz-2.17.0}/src/buz/serializer/message_to_bytes_serializer.py +0 -0
  267. {buz-2.15.12 → buz-2.17.0}/src/buz/serializer/message_to_json_bytes_serializer.py +0 -0
  268. {buz-2.15.12 → buz-2.17.0}/src/buz/wrapper/__init__.py +0 -0
  269. {buz-2.15.12 → buz-2.17.0}/src/buz/wrapper/async_to_sync.py +0 -0
  270. {buz-2.15.12 → buz-2.17.0}/src/buz/wrapper/event_loop.py +0 -0
@@ -1,22 +1,20 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: buz
3
- Version: 2.15.12
3
+ Version: 2.17.0
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
7
7
  Author-email: luis.pintado.lozano@gmail.com
8
8
  Maintainer: Fever - Platform Squad
9
9
  Maintainer-email: platform@feverup.com
10
- Requires-Python: >=3.9
10
+ Requires-Python: >=3.10
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: License :: OSI Approved :: MIT License
13
13
  Classifier: Operating System :: OS Independent
14
14
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.9
16
15
  Classifier: Programming Language :: Python :: 3.10
17
16
  Classifier: Programming Language :: Python :: 3.11
18
17
  Classifier: Programming Language :: Python :: 3.12
19
- Classifier: Programming Language :: Python :: 3.8
20
18
  Classifier: Topic :: Software Development :: Libraries
21
19
  Classifier: Typing :: Typed
22
20
  Provides-Extra: aiokafka
@@ -1,34 +1,37 @@
1
1
  [tool.poetry]
2
2
  name = "buz"
3
- version = "2.15.12"
3
+ version = "2.17.0"
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
- authors = ["Luis Pintado Lozano <luis.pintado.lozano@gmail.com>", "Gerardo Parra <gprauxiliar@gmail.com>"]
6
+ authors = [
7
+ "Luis Pintado Lozano <luis.pintado.lozano@gmail.com>",
8
+ "Gerardo Parra <gprauxiliar@gmail.com>",
9
+ ]
7
10
  maintainers = ["Fever - Platform Squad <platform@feverup.com>"]
8
11
  license = "MIT License"
9
- classifiers=[
10
- "Intended Audience :: Developers",
11
- "License :: OSI Approved :: MIT License",
12
- "Operating System :: OS Independent",
13
- "Programming Language :: Python :: 3.8",
14
- "Programming Language :: Python :: 3.9",
15
- "Operating System :: OS Independent",
16
- "Topic :: Software Development :: Libraries",
17
- "Typing :: Typed",
18
- ]
12
+ classifiers = [
13
+ "Intended Audience :: Developers",
14
+ "License :: OSI Approved :: MIT License",
15
+ "Operating System :: OS Independent",
16
+ "Programming Language :: Python :: 3.10",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Topic :: Software Development :: Libraries",
20
+ "Typing :: Typed",
21
+ ]
19
22
  include = ["py.typed"]
20
23
 
21
24
  [tool.poetry.dependencies]
22
- python = ">= 3.9"
25
+ python = ">= 3.10"
23
26
  pypendency = { version = "~0", optional = true }
24
27
  kombu = { version = ">= 4.6.11", optional = true }
25
- orjson = {version = "^3.10.1"}
26
- pympler = {version = "== 1.0.1"}
27
- kafka-python-ng= "2.2.3"
28
+ orjson = { version = "^3.10.1" }
29
+ pympler = { version = "== 1.0.1" }
30
+ kafka-python-ng = "2.2.3"
28
31
  uuid-utils = "^0.9.0"
29
32
  dacite = "^1.8.1"
30
- aiokafka = {version = "==0.12.0", extras = ["lz4"], optional = true}
31
- asgiref = {version = "^3.8.1", optional = true}
33
+ aiokafka = { version = "==0.12.0", extras = ["lz4"], optional = true }
34
+ asgiref = { version = "^3.8.1", optional = true }
32
35
  cachetools = "^5.5.0"
33
36
  aiohttp = "^3.12.15"
34
37
 
@@ -51,7 +54,7 @@ build-backend = "poetry.core.masonry.api"
51
54
 
52
55
  [tool.black]
53
56
  line-length = 120
54
- target_version = ['py38', 'py39']
57
+ target_version = ['py310', 'py311', 'py312']
55
58
  include = '\.pyi?$'
56
59
  exclude = '''
57
60
  /(
@@ -0,0 +1,13 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Generic, TypeVar
3
+
4
+ from buz.event.event import Event
5
+ from buz.event.meta_subscriber import MetaSubscriber
6
+
7
+ TEvent = TypeVar("TEvent", bound=Event)
8
+
9
+
10
+ class AsyncSubscriber(Generic[TEvent], MetaSubscriber[TEvent], ABC):
11
+ @abstractmethod
12
+ async def consume(self, event: TEvent) -> None:
13
+ pass
@@ -0,0 +1,12 @@
1
+ from abc import ABC
2
+ from typing import Generic, TypeVar
3
+
4
+ from buz.event.event import Event
5
+ from buz.event.async_subscriber import AsyncSubscriber
6
+ from buz.event.meta_base_subscriber import MetaBaseSubscriber
7
+
8
+ TEvent = TypeVar("TEvent", bound=Event)
9
+
10
+
11
+ class BaseAsyncSubscriber(Generic[TEvent], AsyncSubscriber[TEvent], MetaBaseSubscriber[TEvent], ABC):
12
+ pass
@@ -0,0 +1,12 @@
1
+ from abc import ABC
2
+ from typing import Generic, TypeVar
3
+
4
+ from buz.event.event import Event
5
+ from buz.event.subscriber import Subscriber
6
+ from buz.event.meta_base_subscriber import MetaBaseSubscriber
7
+
8
+ TEvent = TypeVar("TEvent", bound=Event)
9
+
10
+
11
+ class BaseSubscriber(Generic[TEvent], Subscriber[TEvent], MetaBaseSubscriber[TEvent], ABC):
12
+ pass
@@ -1,23 +1,26 @@
1
1
  from abc import ABC
2
- from typing import Type, get_type_hints
2
+ from typing import Generic, Type, TypeVar, cast, get_type_hints
3
3
 
4
- from buz.event import Event
4
+ from buz.event.event import Event
5
5
  from buz.event.meta_subscriber import MetaSubscriber
6
6
 
7
+ TEvent = TypeVar("TEvent", bound=Event)
7
8
 
8
- class MetaBaseSubscriber(MetaSubscriber, ABC):
9
+
10
+ class MetaBaseSubscriber(Generic[TEvent], MetaSubscriber[TEvent], ABC):
9
11
  @classmethod
10
12
  def fqn(cls) -> str:
11
13
  return f"subscriber.{cls.__module__}.{cls.__name__}"
12
14
 
13
15
  @classmethod
14
- def handles(cls) -> Type[Event]:
16
+ def handles(cls) -> Type[TEvent]:
15
17
  consume_types = get_type_hints(cls.consume)
16
18
 
17
- if "event" not in consume_types:
19
+ t_event = consume_types.get("event")
20
+ if t_event is None:
18
21
  raise TypeError("event parameter not found in consume method")
19
22
 
20
- if not issubclass(consume_types["event"], Event):
23
+ if not issubclass(t_event, Event):
21
24
  raise TypeError("event parameter is not an buz.event.Event subclass")
22
25
 
23
- return consume_types["event"]
26
+ return cast(Type[TEvent], t_event)
@@ -0,0 +1,18 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Awaitable, Generic, Type, TypeVar, Union
3
+
4
+ from buz import Handler
5
+ from buz.event.event import Event
6
+
7
+ TEvent = TypeVar("TEvent", bound=Event)
8
+
9
+
10
+ class MetaSubscriber(Generic[TEvent], Handler[TEvent], ABC):
11
+ @abstractmethod
12
+ def consume(self, event: TEvent) -> Union[None, Awaitable[None]]:
13
+ pass
14
+
15
+ @classmethod
16
+ @abstractmethod
17
+ def handles(cls) -> Type[TEvent]:
18
+ pass
@@ -0,0 +1,13 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Generic, TypeVar
3
+
4
+ from buz.event.event import Event
5
+ from buz.event.meta_subscriber import MetaSubscriber
6
+
7
+ TEvent = TypeVar("TEvent", bound=Event)
8
+
9
+
10
+ class Subscriber(Generic[TEvent], MetaSubscriber[TEvent], ABC):
11
+ @abstractmethod
12
+ def consume(self, event: TEvent) -> None:
13
+ pass
@@ -10,9 +10,11 @@ class EventToOutboxRecordTranslator:
10
10
  payload = dataclasses.asdict(event)
11
11
  payload.pop("id")
12
12
  payload.pop("created_at")
13
+ payload.pop("metadata")
13
14
  return OutboxRecord(
14
15
  event_id=UUID(event.id),
15
16
  event_fqn=event.fqn(),
16
17
  created_at=event.parsed_created_at(),
17
18
  event_payload=payload,
19
+ event_metadata=dict(event.metadata),
18
20
  )
@@ -12,6 +12,7 @@ class OutboxRecord: # type: ignore[misc]
12
12
  event_fqn: str
13
13
  event_payload: dict[str, Any] # type: ignore[misc]
14
14
  created_at: datetime
15
+ event_metadata: Optional[dict[str, Any]] = None
15
16
  delivered_at: Optional[datetime] = None
16
17
  delivery_errors: int = 0
17
18
  delivery_paused_at: Optional[datetime] = None
@@ -16,6 +16,7 @@ class OutboxRecordToEventTranslator:
16
16
  event_klass.restore(
17
17
  id=str(outbox_record.event_id),
18
18
  created_at=outbox_record.parsed_created_at(),
19
+ metadata=outbox_record.event_metadata,
19
20
  **outbox_record.event_payload,
20
21
  ),
21
22
  )
@@ -0,0 +1,56 @@
1
+ from typing import Optional, Iterable
2
+
3
+ from buz.event import Event, EventBus
4
+ from buz.event.middleware.publish_middleware import PublishMiddleware
5
+ from buz.event.middleware.publish_middleware_chain_resolver import PublishMiddlewareChainResolver
6
+ from buz.event.transactional_outbox import OutboxRecord
7
+ from buz.event.transactional_outbox.event_to_outbox_record_translator import EventToOutboxRecordTranslator
8
+ from buz.event.transactional_outbox.outbox_record_validation.outbox_record_validator import OutboxRecordValidator
9
+ from buz.event.transactional_outbox.outbox_repository import OutboxRepository
10
+
11
+
12
+ class TransactionalOutboxEventBus(EventBus):
13
+ def __init__(
14
+ self,
15
+ outbox_repository: OutboxRepository,
16
+ event_to_outbox_record_translator: EventToOutboxRecordTranslator,
17
+ outbox_record_validator: Optional[OutboxRecordValidator] = None,
18
+ publish_middlewares: Optional[list[PublishMiddleware]] = None,
19
+ ) -> None:
20
+ self.__outbox_repository = outbox_repository
21
+ self.__event_to_outbox_record_translator = event_to_outbox_record_translator
22
+ self.__outbox_record_validator = outbox_record_validator
23
+ self.__publish_middleware = publish_middlewares
24
+ self.__publish_middleware_chain_resolver = PublishMiddlewareChainResolver(self.__publish_middleware or [])
25
+
26
+ def publish(self, event: Event) -> None:
27
+ self.__publish_middleware_chain_resolver.resolve(event, self.__perform_publish)
28
+
29
+ def __perform_publish(self, event: Event) -> None:
30
+ outbox_record = self.__process_event(event)
31
+ self.__outbox_repository.save(outbox_record)
32
+
33
+ def bulk_publish(self, events: Iterable[Event]) -> None:
34
+ publish_middleware_chain_resolver = PublishMiddlewareChainResolver(self.__publish_middleware or [])
35
+ outbox_records: list[OutboxRecord] = []
36
+
37
+ for event in events:
38
+ publish_middleware_chain_resolver.resolve(event, lambda resolved_event: None)
39
+ outbox_records.append(self.__process_event(event))
40
+
41
+ if len(outbox_records) == 0:
42
+ return None
43
+
44
+ self.__outbox_repository.bulk_create(outbox_records)
45
+
46
+ def __process_event(self, event: Event) -> OutboxRecord:
47
+ outbox_record = self.__translate_event(event)
48
+ self.__validate_outbox_record(outbox_record)
49
+ return outbox_record
50
+
51
+ def __translate_event(self, event: Event) -> OutboxRecord:
52
+ return self.__event_to_outbox_record_translator.translate(event)
53
+
54
+ def __validate_outbox_record(self, outbox_record: OutboxRecord) -> None:
55
+ if self.__outbox_record_validator is not None:
56
+ self.__outbox_record_validator.validate(record=outbox_record)
@@ -1,4 +1,5 @@
1
1
  from dataclasses import dataclass
2
+ from typing import Optional
2
3
 
3
4
 
4
5
  @dataclass(frozen=True)
@@ -9,6 +10,7 @@ class CDCPayload:
9
10
  event_id: str # uuid
10
11
  created_at: str
11
12
  event_fqn: str
13
+ metadata: Optional[str] = None # json encoded
12
14
 
13
15
  def validate(self) -> None:
14
16
  if not isinstance(self.payload, str):
@@ -19,6 +21,8 @@ class CDCPayload:
19
21
  raise ValueError("The created_at value is not a value")
20
22
  if not isinstance(self.event_fqn, str):
21
23
  raise ValueError("The event_fqn value is not a valid value")
24
+ if self.metadata is not None and not isinstance(self.metadata, str):
25
+ raise ValueError("The metadata value is not a valid value")
22
26
 
23
27
  def __post_init__(self) -> None:
24
28
  self.validate()
@@ -22,6 +22,13 @@ def generate_cdc_schema(message: Message) -> dict:
22
22
  "optional": False,
23
23
  "field": "event_fqn",
24
24
  },
25
+ {
26
+ "type": "string",
27
+ "optional": True,
28
+ "name": "io.debezium.data.Json",
29
+ "version": 1,
30
+ "field": "metadata",
31
+ },
25
32
  {
26
33
  "type": "string",
27
34
  "optional": False,
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from datetime import datetime
4
- from typing import TypeVar, Type, Generic
4
+ from typing import Optional, TypeVar, Type, Generic
5
5
 
6
6
  import orjson
7
7
  from dacite import from_dict
@@ -29,6 +29,7 @@ class CDCRecordBytesToEventDeserializer(BytesToMessageDeserializer[Event], Gener
29
29
  return self.__event_class.restore(
30
30
  id=cdc_payload.event_id,
31
31
  created_at=self.__get_created_at_in_event_format(cdc_payload.created_at),
32
+ metadata=self.__deserialize_metadata(cdc_payload.metadata),
32
33
  **orjson.loads(cdc_payload.payload),
33
34
  )
34
35
  except Exception as exception:
@@ -47,3 +48,8 @@ class CDCRecordBytesToEventDeserializer(BytesToMessageDeserializer[Event], Gener
47
48
  raise ValueError("The provided payload value is not valid")
48
49
 
49
50
  return from_dict(CDCPayload, payload)
51
+
52
+ def __deserialize_metadata(self, metadata: Optional[str]) -> dict:
53
+ if metadata is None:
54
+ return {}
55
+ return orjson.loads(metadata)
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from dataclasses import asdict
4
4
  from datetime import datetime
5
+ from typing import Optional
5
6
 
6
7
  from buz.event import Event
7
8
  from buz.kafka.infrastructure.cdc.cdc_message import CDCMessage, CDCPayload
@@ -21,6 +22,7 @@ class CDCRecordBytesToEventSerializer(ByteSerializer):
21
22
  created_at=self.__adapt_created_to_cdc_format(data.created_at),
22
23
  event_fqn=data.fqn(),
23
24
  payload=self.__serialize_payload(data),
25
+ metadata=self.__serialize_metadata(data),
24
26
  ),
25
27
  schema=generate_cdc_schema(data),
26
28
  )
@@ -31,8 +33,11 @@ class CDCRecordBytesToEventSerializer(ByteSerializer):
31
33
  return created_at_datetime.strftime(CDCPayload.DATE_TIME_FORMAT)
32
34
 
33
35
  def __serialize_payload(self, event: Event) -> str:
34
- # Remove id and created at, because Transactional outbox is not adding them
35
36
  payload = asdict(event)
36
37
  del payload["id"]
37
38
  del payload["created_at"]
39
+ del payload["metadata"]
38
40
  return self.__json_serializer.serialize_as_json(payload)
41
+
42
+ def __serialize_metadata(self, event: Event) -> Optional[str]:
43
+ return self.__json_serializer.serialize_as_json(event.metadata) # type: ignore[arg-type]
@@ -15,7 +15,9 @@ ALLOWED_SERIALIZABLE_DICTIONARY_KEYS = str
15
15
 
16
16
  JSON_SERIALIZABLE_VALUE = Union[PRIMITIVES, list[PRIMITIVES], dict[ALLOWED_SERIALIZABLE_DICTIONARY_KEYS, PRIMITIVES]]
17
17
 
18
- JSON_SERIALIZABLE = dict[ALLOWED_SERIALIZABLE_DICTIONARY_KEYS, Union[JSON_SERIALIZABLE_VALUE, "JSON_SERIALIZABLE"]]
18
+ JSON_SERIALIZABLE = Union[
19
+ dict[ALLOWED_SERIALIZABLE_DICTIONARY_KEYS, Union[JSON_SERIALIZABLE_VALUE, "JSON_SERIALIZABLE"]]
20
+ ]
19
21
 
20
22
 
21
23
  class JSONByteSerializer(ByteSerializer[JSON_SERIALIZABLE]):
@@ -8,6 +8,8 @@ from typing_extensions import Self
8
8
 
9
9
  from uuid_utils.compat import uuid7
10
10
 
11
+ from buz.metadata import Metadata
12
+
11
13
 
12
14
  @dataclass(frozen=True)
13
15
  class Message(ABC):
@@ -17,6 +19,7 @@ class Message(ABC):
17
19
  created_at: str = field(
18
20
  init=False, default_factory=lambda: datetime.strftime(datetime.now(), Message.DATE_TIME_FORMAT)
19
21
  )
22
+ metadata: Metadata = field(init=False, default_factory=lambda: Metadata())
20
23
 
21
24
  @classmethod
22
25
  def fqn(cls) -> str:
@@ -26,11 +29,14 @@ class Message(ABC):
26
29
  def restore(cls, **kwargs: Any) -> Self:
27
30
  message_id = kwargs.pop("id")
28
31
  created_at = kwargs.pop("created_at")
32
+ metadata_kwargs = kwargs.pop("metadata", None) or {}
33
+ metadata = Metadata(**metadata_kwargs)
29
34
 
30
35
  instance = cls.__from_dict(kwargs) # type: ignore
31
36
 
32
37
  object.__setattr__(instance, "id", message_id)
33
38
  object.__setattr__(instance, "created_at", created_at)
39
+ object.__setattr__(instance, "metadata", metadata)
34
40
  return instance
35
41
 
36
42
  @classmethod
@@ -61,3 +67,6 @@ class Message(ABC):
61
67
 
62
68
  def parsed_created_at(self) -> datetime:
63
69
  return datetime.strptime(self.created_at, self.DATE_TIME_FORMAT)
70
+
71
+ def add_metadata(self, metadata: Metadata) -> None:
72
+ self.metadata.update(metadata)
@@ -0,0 +1,8 @@
1
+ from typing import Any, TypedDict
2
+
3
+
4
+ class Metadata(TypedDict):
5
+ def __init__(self, **kwargs: dict[str, Any]) -> None: # type: ignore[misc]
6
+ super().__init__()
7
+ for key, value in kwargs.items():
8
+ setattr(self, key, value)
@@ -1,20 +1,19 @@
1
- from abc import abstractmethod
1
+ from abc import ABC, abstractmethod
2
2
  from typing import Generic, Type, TypeVar
3
3
 
4
4
  from buz import Handler
5
5
  from buz.query import Query, QueryResponse
6
6
 
7
-
8
7
  TQuery = TypeVar("TQuery", bound=Query)
9
8
  TQueryResponse = TypeVar("TQueryResponse", bound=QueryResponse)
10
9
 
11
10
 
12
- class QueryHandler(Generic[TQuery, TQueryResponse], Handler[TQuery]):
11
+ class QueryHandler(Generic[TQuery, TQueryResponse], Handler[TQuery], ABC):
13
12
  @classmethod
14
13
  @abstractmethod
15
14
  def handles(cls) -> Type[TQuery]:
16
15
  pass
17
16
 
18
17
  @abstractmethod
19
- async def handle(self, query: Query) -> TQueryResponse:
18
+ async def handle(self, query: TQuery) -> TQueryResponse:
20
19
  pass
@@ -1,10 +0,0 @@
1
- from abc import ABC, abstractmethod
2
-
3
- from buz.event import Event
4
- from buz.event.meta_subscriber import MetaSubscriber
5
-
6
-
7
- class AsyncSubscriber(MetaSubscriber, ABC):
8
- @abstractmethod
9
- async def consume(self, event: Event) -> None:
10
- pass
@@ -1,8 +0,0 @@
1
- from abc import ABC
2
-
3
- from buz.event.async_subscriber import AsyncSubscriber
4
- from buz.event.meta_base_subscriber import MetaBaseSubscriber
5
-
6
-
7
- class BaseAsyncSubscriber(AsyncSubscriber, MetaBaseSubscriber, ABC):
8
- pass
@@ -1,7 +0,0 @@
1
- from abc import ABC
2
- from buz.event import Subscriber
3
- from buz.event.meta_base_subscriber import MetaBaseSubscriber
4
-
5
-
6
- class BaseSubscriber(Subscriber, MetaBaseSubscriber, ABC):
7
- pass
@@ -1,16 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from typing import Awaitable, Type, Union
3
-
4
- from buz import Handler
5
- from buz.event import Event
6
-
7
-
8
- class MetaSubscriber(Handler, ABC):
9
- @abstractmethod
10
- def consume(self, event: Event) -> Union[None, Awaitable[None]]:
11
- pass
12
-
13
- @classmethod
14
- @abstractmethod
15
- def handles(cls) -> Type[Event]:
16
- pass
@@ -1,10 +0,0 @@
1
- from abc import ABC, abstractmethod
2
-
3
- from buz.event import Event
4
- from buz.event.meta_subscriber import MetaSubscriber
5
-
6
-
7
- class Subscriber(MetaSubscriber, ABC):
8
- @abstractmethod
9
- def consume(self, event: Event) -> None:
10
- pass
@@ -1,34 +0,0 @@
1
- from typing import Optional, Iterable
2
-
3
- from buz.event import Event, EventBus
4
- from buz.event.transactional_outbox import OutboxRecord
5
- from buz.event.transactional_outbox.event_to_outbox_record_translator import EventToOutboxRecordTranslator
6
- from buz.event.transactional_outbox.outbox_record_validation.outbox_record_validator import OutboxRecordValidator
7
- from buz.event.transactional_outbox.outbox_repository import OutboxRepository
8
-
9
-
10
- class TransactionalOutboxEventBus(EventBus):
11
- def __init__(
12
- self,
13
- outbox_repository: OutboxRepository,
14
- event_to_outbox_record_translator: EventToOutboxRecordTranslator,
15
- outbox_record_validator: Optional[OutboxRecordValidator] = None,
16
- ):
17
- self.__outbox_repository = outbox_repository
18
- self.__event_to_outbox_record_translator = event_to_outbox_record_translator
19
- self.__outbox_record_validator = outbox_record_validator
20
-
21
- def publish(self, event: Event) -> None:
22
- outbox_record = self.__translate_and_validate(event)
23
- self.__outbox_repository.save(outbox_record)
24
-
25
- def bulk_publish(self, events: Iterable[Event]) -> None:
26
- outbox_records = map(self.__translate_and_validate, events)
27
- self.__outbox_repository.bulk_create(outbox_records)
28
-
29
- # Raises OutboxRecordValidationException: If any validation inside outbox_record_validator fails
30
- def __translate_and_validate(self, event: Event) -> OutboxRecord:
31
- outbox_record = self.__event_to_outbox_record_translator.translate(event)
32
- if self.__outbox_record_validator is not None:
33
- self.__outbox_record_validator.validate(record=outbox_record)
34
- return outbox_record
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes