buz 2.15.10rc6__tar.gz → 2.15.12__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.
- {buz-2.15.10rc6 → buz-2.15.12}/LICENSE +1 -1
- buz-2.15.12/PKG-INFO +438 -0
- buz-2.15.12/README.md +400 -0
- {buz-2.15.10rc6 → buz-2.15.12}/pyproject.toml +1 -1
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/asynchronous/base_command_handler.py +13 -6
- buz-2.15.12/src/buz/command/asynchronous/command_handler.py +19 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/synchronous/base_command_handler.py +14 -6
- buz-2.15.12/src/buz/command/synchronous/command_handler.py +18 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/kafka_event_async_subscriber_executor.py +20 -3
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/kafka_event_sync_subscriber_executor.py +20 -5
- buz-2.15.12/src/buz/event/infrastructure/buz_kafka/models/kafka_delivery_context.py +10 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/kombu/kombu_consumer.py +10 -2
- buz-2.15.12/src/buz/event/infrastructure/kombu/models/kombu_delivery_context.py +7 -0
- buz-2.15.12/src/buz/event/infrastructure/models/delivery_context.py +6 -0
- buz-2.15.12/src/buz/event/infrastructure/models/execution_context.py +8 -0
- buz-2.15.12/src/buz/event/middleware/async_consume_middleware.py +21 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/middleware/async_consume_middleware_chain_resolver.py +16 -5
- buz-2.15.12/src/buz/event/middleware/base_async_consume_middleware.py +37 -0
- buz-2.15.12/src/buz/event/middleware/base_consume_middleware.py +22 -0
- buz-2.15.12/src/buz/event/middleware/consume_middleware.py +16 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/middleware/consume_middleware_chain_resolver.py +13 -4
- buz-2.15.12/src/buz/event/sync/models/sync_delivery_context.py +7 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/sync/sync_event_bus.py +10 -2
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/handler.py +6 -3
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/models/kafka_poll_record.py +1 -0
- buz-2.15.12/src/buz/py.typed +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/asynchronous/base_query_handler.py +15 -6
- buz-2.15.12/src/buz/query/asynchronous/query_handler.py +20 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/synchronous/base_query_handler.py +15 -6
- buz-2.15.12/src/buz/query/synchronous/query_handler.py +19 -0
- buz-2.15.12/src/buz/queue/__init__.py +0 -0
- buz-2.15.10rc6/PKG-INFO +0 -41
- buz-2.15.10rc6/README.md +0 -4
- buz-2.15.10rc6/src/buz/command/asynchronous/command_handler.py +0 -16
- buz-2.15.10rc6/src/buz/command/synchronous/command_handler.py +0 -16
- buz-2.15.10rc6/src/buz/event/middleware/async_consume_middleware.py +0 -14
- buz-2.15.10rc6/src/buz/event/middleware/base_async_consume_middleware.py +0 -20
- buz-2.15.10rc6/src/buz/event/middleware/base_consume_middleware.py +0 -19
- buz-2.15.10rc6/src/buz/event/middleware/consume_middleware.py +0 -13
- buz-2.15.10rc6/src/buz/query/asynchronous/query_handler.py +0 -16
- buz-2.15.10rc6/src/buz/query/synchronous/query_handler.py +0 -16
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/asynchronous/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/asynchronous/command_bus.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/asynchronous/middleware/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/asynchronous/middleware/base_handle_middleware.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/asynchronous/middleware/handle_middleware.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/asynchronous/middleware/handle_middleware_chain_resolver.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/asynchronous/self_process/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/asynchronous/self_process/self_process_command_bus.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/command.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/more_than_one_command_handler_related_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/synchronous/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/synchronous/command_bus.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/synchronous/middleware/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/synchronous/middleware/base_handle_middleware.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/synchronous/middleware/handle_middleware.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/synchronous/middleware/handle_middleware_chain_resolver.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/synchronous/self_process/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/synchronous/self_process/self_process_command_bus.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/synchronous/synced_async/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/command/synchronous/synced_async/synced_async_command_bus.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/async_consumer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/async_event_bus.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/async_subscriber.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/async_worker.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/base_async_subscriber.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/base_subscriber.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/consumer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/dead_letter_queue/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/dead_letter_queue/dlq_criteria.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/dead_letter_queue/dlq_record.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/dead_letter_queue/dlq_repository.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/event.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/event_bus.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/exceptions/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/exceptions/event_not_published_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/exceptions/event_restore_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/exceptions/subscribers_not_found_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/exceptions/term_signal_interruption_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/exceptions/worker_execution_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/async_buz_kafka_event_bus.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/base_buz_aiokafka_async_consumer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/buz_aiokafka_async_consumer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/buz_aiokafka_multi_threaded_consumer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/buz_kafka_event_bus.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/consume_strategy/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/consume_strategy/consume_strategy.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/consume_strategy/kafka_on_fail_strategy.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/consume_strategy/topic_and_subscription_group_per_subscriber_kafka_consumer_strategy.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/exceptions/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/exceptions/kafka_event_bus_config_not_valid_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/exceptions/max_consumer_retry_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/exceptions/retry_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/kafka_event_subscriber_executor.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/publish_strategy/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/publish_strategy/publish_strategy.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/buz_kafka/publish_strategy/topic_per_event_kafka_publish_strategy.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/kombu/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/kombu/allowed_kombu_serializer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/kombu/consume_strategy/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/kombu/consume_strategy/consume_strategy.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/kombu/consume_strategy/queue_per_subscriber_consume_strategy.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/kombu/kombu_event_bus.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/kombu/publish_strategy/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/kombu/publish_strategy/fanout_exchange_per_event_publish_strategy.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/kombu/publish_strategy/publish_strategy.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/kombu/retry_strategy/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/kombu/retry_strategy/publish_retry_policy.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/kombu/retry_strategy/simple_publish_retry_policy.py +0 -0
- {buz-2.15.10rc6/src/buz/event/infrastructure/queue → buz-2.15.12/src/buz/event/infrastructure/models}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/infrastructure/models/consuming_task.py +0 -0
- {buz-2.15.10rc6/src/buz/event/middleware/exceptions → buz-2.15.12/src/buz/event/infrastructure/queue}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/meta_base_subscriber.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/meta_subscriber.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/middleware/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/middleware/async_publish_middleware.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/middleware/async_publish_middleware_chain_resolver.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/middleware/base_publish_middleware.py +0 -0
- {buz-2.15.10rc6/src/buz/event/strategies → buz-2.15.12/src/buz/event/middleware/exceptions}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/middleware/exceptions/event_already_in_progress_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/middleware/publish_middleware.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/middleware/publish_middleware_chain_resolver.py +0 -0
- {buz-2.15.10rc6/src/buz/event/strategies/execution_strategy → buz-2.15.12/src/buz/event/strategies}/__init__.py +0 -0
- {buz-2.15.10rc6/src/buz/event/strategies/retry → buz-2.15.12/src/buz/event/strategies/execution_strategy}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/strategies/execution_strategy/async_execution_strategy.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/strategies/execution_strategy/async_self_process_execution_strategy.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/strategies/execution_strategy/cyclic_iterator_execution_strategy.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/strategies/execution_strategy/execution_strategy.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/strategies/execution_strategy/self_process_execution_strategy.py +0 -0
- {buz-2.15.10rc6/src/buz/event/transactional_outbox/outbox_record_validation → buz-2.15.12/src/buz/event/strategies/retry}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/strategies/retry/consume_retrier.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/strategies/retry/consumed_event_retry.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/strategies/retry/consumed_event_retry_repository.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/strategies/retry/max_retries_consume_retrier.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/strategies/retry/max_retries_negative_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/strategies/retry/reject_callback.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/subscriber.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/sync/__init__.py +0 -0
- {buz-2.15.10rc6/src/buz/kafka/domain/exceptions → buz-2.15.12/src/buz/event/sync/models}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/event_to_outbox_record_translator.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/fqn_to_event_mapper.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/outbox_criteria/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/outbox_criteria/deliverable_records_outbox_criteria_factory.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/outbox_criteria/outbox_criteria.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/outbox_criteria/outbox_criteria_factory.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/outbox_criteria/outbox_sorting_criteria.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/outbox_record.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/outbox_record_finder/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/outbox_record_finder/outbox_record_stream_finder.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/outbox_record_finder/polling_outbox_record_stream_finder.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/outbox_record_to_event_translator.py +0 -0
- {buz-2.15.10rc6/src/buz/kafka/domain/models → buz-2.15.12/src/buz/event/transactional_outbox/outbox_record_validation}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/outbox_record_validation/abstract_outbox_record_validator.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/outbox_record_validation/outbox_record_size_not_allowed_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/outbox_record_validation/outbox_record_validation_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/outbox_record_validation/outbox_record_validator.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/outbox_record_validation/size_outbox_record_validator.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/outbox_repository.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/transactional_outbox_event_bus.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/transactional_outbox/transactional_outbox_worker.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/event/worker.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/__init__.py +0 -0
- {buz-2.15.10rc6/src/buz/kafka/domain/services → buz-2.15.12/src/buz/kafka/domain/exceptions}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/exceptions/not_all_partition_assigned_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/exceptions/not_valid_kafka_message_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/exceptions/not_valid_partition_number_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/exceptions/topic_already_created_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/exceptions/topic_not_found_exception.py +0 -0
- {buz-2.15.10rc6/src/buz/kafka/infrastructure → buz-2.15.12/src/buz/kafka/domain/models}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/models/auto_create_topic_configuration.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/models/consumer_initial_offset_position.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/models/create_kafka_topic.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/models/kafka_connection_config.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/models/kafka_connection_credentials.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/models/kafka_connection_plain_text_credentials.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/models/kafka_connection_sasl_credentials.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/models/kafka_consumer_record.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/models/kafka_supported_compression_type.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/models/kafka_supported_sasl_mechanisms.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/models/kafka_supported_security_protocols.py +0 -0
- {buz-2.15.10rc6/src/buz/kafka/infrastructure/aiokafka → buz-2.15.12/src/buz/kafka/domain/services}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/services/async_kafka_producer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/services/kafka_admin_client.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/services/kafka_admin_test_client.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/domain/services/kafka_producer.py +0 -0
- {buz-2.15.10rc6/src/buz/kafka/infrastructure/aiokafka/rebalance → buz-2.15.12/src/buz/kafka/infrastructure}/__init__.py +0 -0
- {buz-2.15.10rc6/src/buz/kafka/infrastructure/aiokafka/translators → buz-2.15.12/src/buz/kafka/infrastructure/aiokafka}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/aiokafka/aiokafka_consumer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/aiokafka/aiokafka_producer.py +0 -0
- {buz-2.15.10rc6/src/buz/kafka/infrastructure/cdc → buz-2.15.12/src/buz/kafka/infrastructure/aiokafka/rebalance}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/aiokafka/rebalance/kafka_callback_rebalancer.py +0 -0
- {buz-2.15.10rc6/src/buz/kafka/infrastructure/deserializers → buz-2.15.12/src/buz/kafka/infrastructure/aiokafka/translators}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/aiokafka/translators/consumer_initial_offset_position_translator.py +0 -0
- {buz-2.15.10rc6/src/buz/kafka/infrastructure/deserializers/implementations → buz-2.15.12/src/buz/kafka/infrastructure/cdc}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/cdc/cdc_message.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/cdc/cdc_payload.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/cdc/cdc_schema.py +0 -0
- {buz-2.15.10rc6/src/buz/kafka/infrastructure/interfaces → buz-2.15.12/src/buz/kafka/infrastructure/deserializers}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/deserializers/byte_deserializer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/deserializers/bytes_to_message_deserializer.py +0 -0
- {buz-2.15.10rc6/src/buz/kafka/infrastructure/kafka_python → buz-2.15.12/src/buz/kafka/infrastructure/deserializers/implementations}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/deserializers/implementations/cdc/cdc_record_bytes_to_event_deserializer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/deserializers/implementations/cdc/not_valid_cdc_message_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/deserializers/implementations/json_byte_deserializer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/deserializers/implementations/json_bytes_to_message_deserializer.py +0 -0
- {buz-2.15.10rc6/src/buz/kafka/infrastructure/kafka_python/translators → buz-2.15.12/src/buz/kafka/infrastructure/interfaces}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/interfaces/async_connection_manager.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/interfaces/connection_manager.py +0 -0
- {buz-2.15.10rc6/src/buz/queue → buz-2.15.12/src/buz/kafka/infrastructure/kafka_python}/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/kafka_python/exception/consumer_interrupted_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/kafka_python/kafka_python_admin_client.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/kafka_python/kafka_python_admin_test_client.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/kafka_python/kafka_python_producer.py +0 -0
- /buz-2.15.10rc6/src/buz/py.typed → /buz-2.15.12/src/buz/kafka/infrastructure/kafka_python/translators/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/kafka_python/translators/consumer_initial_offset_position_translator.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/serializers/byte_serializer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/serializers/implementations/cdc_record_bytes_to_event_serializer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/serializers/implementations/json_byte_serializer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/kafka/infrastructure/serializers/kafka_header_serializer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/locator/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/locator/handler_fqn_not_found_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/locator/locator.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/locator/message_fqn_not_found_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/locator/pypendency/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/locator/pypendency/container_locator.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/locator/pypendency/container_locator_resolution_configuration.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/locator/pypendency/handler_not_found_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/locator/pypendency/handler_not_registered_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/locator/sync/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/locator/sync/handler_already_registered_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/locator/sync/handler_not_registered_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/locator/sync/instance_locator.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/message.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/middleware/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/middleware/middleware.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/middleware/middleware_chain_builder.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/asynchronous/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/asynchronous/middleware/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/asynchronous/middleware/base_handle_middleware.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/asynchronous/middleware/handle_middleware.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/asynchronous/middleware/handle_middleware_chain_resolver.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/asynchronous/query_bus.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/asynchronous/self_process/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/asynchronous/self_process/self_process_query_bus.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/more_than_one_query_handler_related_exception.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/query.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/query_response.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/synchronous/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/synchronous/middleware/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/synchronous/middleware/base_handle_middleware.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/synchronous/middleware/handle_middleware.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/synchronous/middleware/handle_middleware_chain_resolver.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/synchronous/query_bus.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/synchronous/self_process/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/synchronous/self_process/self_process_query_bus.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/synchronous/synced_async/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/query/synchronous/synced_async/synced_async_query_bus.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/queue/in_memory/in_memory_multiqueue_repository.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/queue/in_memory/in_memory_queue_repository.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/queue/multiqueue_repository.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/queue/queue_repository.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/serializer/message_to_bytes_serializer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/serializer/message_to_json_bytes_serializer.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/wrapper/__init__.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/wrapper/async_to_sync.py +0 -0
- {buz-2.15.10rc6 → buz-2.15.12}/src/buz/wrapper/event_loop.py +0 -0
buz-2.15.12/PKG-INFO
ADDED
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: buz
|
|
3
|
+
Version: 2.15.12
|
|
4
|
+
Summary: Buz is a set of light, simple and extensible implementations of event, command and query buses.
|
|
5
|
+
License: MIT
|
|
6
|
+
Author: Luis Pintado Lozano
|
|
7
|
+
Author-email: luis.pintado.lozano@gmail.com
|
|
8
|
+
Maintainer: Fever - Platform Squad
|
|
9
|
+
Maintainer-email: platform@feverup.com
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Provides-Extra: aiokafka
|
|
23
|
+
Provides-Extra: kombu
|
|
24
|
+
Provides-Extra: pypendency
|
|
25
|
+
Requires-Dist: aiohttp (>=3.12.15,<4.0.0)
|
|
26
|
+
Requires-Dist: aiokafka[lz4] (==0.12.0) ; extra == "aiokafka"
|
|
27
|
+
Requires-Dist: asgiref (>=3.8.1,<4.0.0) ; extra == "aiokafka"
|
|
28
|
+
Requires-Dist: cachetools (>=5.5.0,<6.0.0)
|
|
29
|
+
Requires-Dist: dacite (>=1.8.1,<2.0.0)
|
|
30
|
+
Requires-Dist: kafka-python-ng (==2.2.3)
|
|
31
|
+
Requires-Dist: kombu (>=4.6.11) ; extra == "kombu"
|
|
32
|
+
Requires-Dist: orjson (>=3.10.1,<4.0.0)
|
|
33
|
+
Requires-Dist: pympler (==1.0.1)
|
|
34
|
+
Requires-Dist: pypendency (>=0,<1) ; extra == "pypendency"
|
|
35
|
+
Requires-Dist: uuid-utils (>=0.9.0,<0.10.0)
|
|
36
|
+
Description-Content-Type: text/markdown
|
|
37
|
+
|
|
38
|
+
# Buz
|
|
39
|
+
|
|
40
|
+
[](https://badge.fury.io/py/buz)
|
|
41
|
+
[](https://pypi.org/project/buz/)
|
|
42
|
+
[](https://opensource.org/licenses/MIT)
|
|
43
|
+
[](https://github.com/psf/black)
|
|
44
|
+
|
|
45
|
+
**Buz** is a lightweight, simple, and extensible Python library that provides implementations of **Event**, **Command**, and **Query** buses following CQRS and Event-Driven Architecture patterns.
|
|
46
|
+
|
|
47
|
+
## 📋 Table of Contents
|
|
48
|
+
|
|
49
|
+
- [Buz](#buz)
|
|
50
|
+
- [📋 Table of Contents](#-table-of-contents)
|
|
51
|
+
- [✨ Key Features](#-key-features)
|
|
52
|
+
- [🚀 Quick Start](#-quick-start)
|
|
53
|
+
- [Installation](#installation)
|
|
54
|
+
- [Basic Usage](#basic-usage)
|
|
55
|
+
- [Event Bus Example](#event-bus-example)
|
|
56
|
+
- [Command Bus Example](#command-bus-example)
|
|
57
|
+
- [Query Bus Example](#query-bus-example)
|
|
58
|
+
- [🏗️ Architecture](#️-architecture)
|
|
59
|
+
- [Event Bus](#event-bus)
|
|
60
|
+
- [Command Bus](#command-bus)
|
|
61
|
+
- [Query Bus](#query-bus)
|
|
62
|
+
- [🔧 Advanced Features](#-advanced-features)
|
|
63
|
+
- [Middleware System](#middleware-system)
|
|
64
|
+
- [Transactional Outbox Pattern](#transactional-outbox-pattern)
|
|
65
|
+
- [RabbitMQ](#rabbitmq)
|
|
66
|
+
- [Kafka Integration](#kafka-integration)
|
|
67
|
+
- [Async Support](#async-support)
|
|
68
|
+
- [📦 Message Brokers](#-message-brokers)
|
|
69
|
+
- [Supported Brokers](#supported-brokers)
|
|
70
|
+
- [🧪 Testing](#-testing)
|
|
71
|
+
- [🔗 Related Projects](#-related-projects)
|
|
72
|
+
- [📋 Requirements](#-requirements)
|
|
73
|
+
- [🤝 Contributing](#-contributing)
|
|
74
|
+
- [Development Setup](#development-setup)
|
|
75
|
+
- [📄 License](#-license)
|
|
76
|
+
- [📚 Documentation](#-documentation)
|
|
77
|
+
- [🙋♀️ Support](#️-support)
|
|
78
|
+
|
|
79
|
+
## ✨ Key Features
|
|
80
|
+
|
|
81
|
+
- 🚌 **Bus Types**: Event, Command, and Query buses for clean architecture
|
|
82
|
+
- 🔄 **Sync & Async Support**: Both synchronous and asynchronous implementations
|
|
83
|
+
- 🔧 **Middleware System**: Extensible middleware for cross-cutting concerns
|
|
84
|
+
- 📦 **Message Brokers**: Support for Kafka, RabbitMQ (via Kombu), and in-memory
|
|
85
|
+
- 🔒 **Transactional Outbox**: Reliable event publishing with transactional guarantees
|
|
86
|
+
- 🎯 **Dependency Injection**: Built-in locator pattern for handler resolution
|
|
87
|
+
- 📝 **Type Safety**: Fully typed with mypy support
|
|
88
|
+
- 🪶 **Lightweight**: Minimal dependencies, maximum flexibility
|
|
89
|
+
|
|
90
|
+
## 🚀 Quick Start
|
|
91
|
+
|
|
92
|
+
### Installation
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Basic installation
|
|
96
|
+
pip install buz
|
|
97
|
+
|
|
98
|
+
# With Kafka support
|
|
99
|
+
pip install buz[aiokafka]
|
|
100
|
+
|
|
101
|
+
# With RabbitMQ support
|
|
102
|
+
pip install buz[kombu]
|
|
103
|
+
|
|
104
|
+
# With dependency injection
|
|
105
|
+
pip install buz[pypendency]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Basic Usage
|
|
109
|
+
|
|
110
|
+
#### Event Bus Example
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from dataclasses import dataclass
|
|
114
|
+
from buz import Message
|
|
115
|
+
from buz.event import Event, BaseSubscriber
|
|
116
|
+
from buz.event.sync import SyncEventBus
|
|
117
|
+
from buz.locator.sync import InstanceLocator
|
|
118
|
+
|
|
119
|
+
@dataclass(frozen=True)
|
|
120
|
+
class UserCreated(Event):
|
|
121
|
+
user_id: str
|
|
122
|
+
email: str
|
|
123
|
+
|
|
124
|
+
class EmailSubscriber(BaseSubscriber):
|
|
125
|
+
def consume(self, event: UserCreated) -> None:
|
|
126
|
+
print(f"Sending welcome email to {event.email}")
|
|
127
|
+
|
|
128
|
+
class AnalyticsSubscriber(BaseSubscriber):
|
|
129
|
+
def consume(self, event: UserCreated) -> None:
|
|
130
|
+
print(f"Tracking user creation: {event.user_id}")
|
|
131
|
+
|
|
132
|
+
# Setup
|
|
133
|
+
locator: InstanceLocator = InstanceLocator()
|
|
134
|
+
locator.register(EmailSubscriber())
|
|
135
|
+
locator.register(AnalyticsSubscriber())
|
|
136
|
+
|
|
137
|
+
event_bus = SyncEventBus(locator)
|
|
138
|
+
|
|
139
|
+
# Usage
|
|
140
|
+
event = UserCreated(user_id="123", email="user@example.com")
|
|
141
|
+
event_bus.publish(event)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
#### Command Bus Example
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
from dataclasses import dataclass
|
|
148
|
+
from buz.command import Command
|
|
149
|
+
from buz.command.synchronous import BaseCommandHandler
|
|
150
|
+
from buz.command.synchronous.self_process import SelfProcessCommandBus
|
|
151
|
+
from buz.locator.sync import InstanceLocator
|
|
152
|
+
|
|
153
|
+
@dataclass(frozen=True)
|
|
154
|
+
class CreateUser(Command):
|
|
155
|
+
email: str
|
|
156
|
+
name: str
|
|
157
|
+
|
|
158
|
+
class CreateUserCommandHandler(BaseCommandHandler):
|
|
159
|
+
def handle(self, command: CreateUser) -> None:
|
|
160
|
+
# Business logic here
|
|
161
|
+
print(f"Creating user: {command.name} ({command.email})")
|
|
162
|
+
|
|
163
|
+
# Setup
|
|
164
|
+
locator = InstanceLocator()
|
|
165
|
+
locator.register(CreateUserCommandHandler())
|
|
166
|
+
|
|
167
|
+
command_bus = SelfProcessCommandBus(locator)
|
|
168
|
+
|
|
169
|
+
# Usage
|
|
170
|
+
command = CreateUser(email="user@example.com", name="John Doe")
|
|
171
|
+
command_bus.handle(command)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
#### Query Bus Example
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
from dataclasses import dataclass
|
|
178
|
+
from buz.query import Query, QueryResponse
|
|
179
|
+
from buz.query.synchronous import BaseQueryHandler
|
|
180
|
+
from buz.query.synchronous.self_process import SelfProcessQueryBus
|
|
181
|
+
from buz.locator.sync import InstanceLocator
|
|
182
|
+
|
|
183
|
+
@dataclass(frozen=True)
|
|
184
|
+
class GetUser(Query):
|
|
185
|
+
user_id: str
|
|
186
|
+
|
|
187
|
+
@dataclass(frozen=True)
|
|
188
|
+
class User:
|
|
189
|
+
user_id: str
|
|
190
|
+
name: str
|
|
191
|
+
email: str
|
|
192
|
+
|
|
193
|
+
class GetUserQueryHandler(BaseQueryHandler):
|
|
194
|
+
def handle(self, query: GetUser) -> QueryResponse:
|
|
195
|
+
# Business logic here
|
|
196
|
+
return QueryResponse(
|
|
197
|
+
content=User(
|
|
198
|
+
user_id=query.user_id,
|
|
199
|
+
name="John Doe",
|
|
200
|
+
email="john@example.com"
|
|
201
|
+
)
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
# Setup
|
|
205
|
+
locator = InstanceLocator()
|
|
206
|
+
locator.register(GetUserQueryHandler())
|
|
207
|
+
|
|
208
|
+
query_bus = SelfProcessQueryBus(locator)
|
|
209
|
+
|
|
210
|
+
# Usage
|
|
211
|
+
query = GetUser(user_id="123")
|
|
212
|
+
query_response = query_bus.handle(query)
|
|
213
|
+
user = query_response.content
|
|
214
|
+
print(f"User: {user.name}")
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## 🏗️ Architecture
|
|
218
|
+
|
|
219
|
+
Buz implements the **Command Query Responsibility Segregation (CQRS)** pattern with distinct buses:
|
|
220
|
+
|
|
221
|
+
### Event Bus
|
|
222
|
+
|
|
223
|
+
- **Purpose**: Publish domain events and notify multiple subscribers
|
|
224
|
+
- **Pattern**: Pub/Sub with multiple handlers per event
|
|
225
|
+
- **Use Cases**: Domain event broadcasting, eventual consistency, integration events
|
|
226
|
+
|
|
227
|
+
### Command Bus
|
|
228
|
+
|
|
229
|
+
- **Purpose**: Execute business operations and commands
|
|
230
|
+
- **Pattern**: Single handler per command
|
|
231
|
+
- **Use Cases**: Business logic execution, write operations, state changes
|
|
232
|
+
|
|
233
|
+
### Query Bus
|
|
234
|
+
|
|
235
|
+
- **Purpose**: Retrieve data and execute queries
|
|
236
|
+
- **Pattern**: Single handler per query with typed responses
|
|
237
|
+
- **Use Cases**: Data retrieval, read operations, projections
|
|
238
|
+
|
|
239
|
+
## 🔧 Advanced Features
|
|
240
|
+
|
|
241
|
+
### Middleware System
|
|
242
|
+
|
|
243
|
+
Add cross-cutting concerns like logging, validation, and metrics:
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
from datetime import datetime
|
|
247
|
+
from buz.event import Event, Subscriber
|
|
248
|
+
from buz.event.middleware import BasePublishMiddleware, BaseConsumeMiddleware
|
|
249
|
+
from buz.event.infrastructure.models.execution_context import ExecutionContext
|
|
250
|
+
|
|
251
|
+
class LoggingPublishMiddleware(BasePublishMiddleware):
|
|
252
|
+
def _before_on_publish(self, event: Event) -> None:
|
|
253
|
+
print(f"Publishing event {event}")
|
|
254
|
+
|
|
255
|
+
def _after_on_publish(self, event: Event) -> None:
|
|
256
|
+
return
|
|
257
|
+
|
|
258
|
+
class MetricsConsumeMiddleware(BaseConsumeMiddleware):
|
|
259
|
+
def __init__(self) -> None:
|
|
260
|
+
self.__consumption_start_time: datetime = datetime.now()
|
|
261
|
+
|
|
262
|
+
def _before_on_consume(
|
|
263
|
+
self,
|
|
264
|
+
event: Event,
|
|
265
|
+
subscriber: Subscriber,
|
|
266
|
+
execution_context: ExecutionContext,
|
|
267
|
+
) -> None:
|
|
268
|
+
self.__consumption_start_time = datetime.now()
|
|
269
|
+
|
|
270
|
+
def _after_on_consume(
|
|
271
|
+
self,
|
|
272
|
+
event: Event,
|
|
273
|
+
subscriber: Subscriber,
|
|
274
|
+
execution_context: ExecutionContext,
|
|
275
|
+
) -> None:
|
|
276
|
+
consumption_time_ms = int((datetime.now() - self.__consumption_start_time).total_seconds() * 1000)
|
|
277
|
+
print(
|
|
278
|
+
f"Subscriber {subscriber.fqn()} consumed event {event.id} successfully in {consumption_time_ms} ms"
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
# Apply middleware
|
|
282
|
+
event_bus = SyncEventBus(
|
|
283
|
+
locator=locator,
|
|
284
|
+
publish_middlewares=[LoggingPublishMiddleware()],
|
|
285
|
+
consume_middlewares=[MetricsConsumeMiddleware()]
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
# Usage
|
|
289
|
+
event = UserCreated(user_id="123", email="user@example.com")
|
|
290
|
+
event_bus.publish(event)
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Transactional Outbox Pattern
|
|
294
|
+
|
|
295
|
+
Ensure reliable event publishing with database transactions:
|
|
296
|
+
|
|
297
|
+
```python
|
|
298
|
+
from buz.event.transactional_outbox import TransactionalOutboxEventBus
|
|
299
|
+
|
|
300
|
+
# Configure with your database and event bus
|
|
301
|
+
transactional_outbox_bus = TransactionalOutboxEventBus(
|
|
302
|
+
outbox_repository=your_outbox_repository,
|
|
303
|
+
event_to_outbox_record_translator=your_outbox_record_translator,
|
|
304
|
+
...
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
# Events are stored in database, published later by worker
|
|
308
|
+
transactional_outbox_bus.publish(event)
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### RabbitMQ
|
|
312
|
+
|
|
313
|
+
```python
|
|
314
|
+
from buz.event.infrastructure.kombu.kombu_event_bus import KombuEventBus
|
|
315
|
+
|
|
316
|
+
kombu_event_bus = KombuEventBus(
|
|
317
|
+
connection=your_connection,
|
|
318
|
+
publish_strategy=your_publish_strategy,
|
|
319
|
+
publish_retry_policy=you_publish_retry_policy,
|
|
320
|
+
...
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
# Published and consumed in RabbitMQ
|
|
324
|
+
kombu_event_bus.publish(event)
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Kafka Integration
|
|
328
|
+
|
|
329
|
+
```python
|
|
330
|
+
from buz.kafka import BuzKafkaEventBus
|
|
331
|
+
|
|
332
|
+
kafka_bus = KafkaEventBus(
|
|
333
|
+
publish_strategy=your_publish_strategy,
|
|
334
|
+
producer=your_producer,
|
|
335
|
+
logger=your_logger,
|
|
336
|
+
...
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
# Published and consumed in Kafka
|
|
340
|
+
kafka_bus.publish(event)
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Async Support
|
|
344
|
+
|
|
345
|
+
```python
|
|
346
|
+
from buz.event.async_event_bus import AsyncEventBus
|
|
347
|
+
from buz.query.asynchronous import QueryBus as AsyncQueryBus
|
|
348
|
+
from buz.command.asynchronous import CommandHandler as AsyncCommandHandler
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
# Async event bus
|
|
352
|
+
async_event_bus = AsyncEventBus(locator)
|
|
353
|
+
await async_event_bus.publish(event)
|
|
354
|
+
|
|
355
|
+
# Async query bus
|
|
356
|
+
async_query_bus = AsyncQueryBus(locator)
|
|
357
|
+
await async_query_bus.handle(event)
|
|
358
|
+
|
|
359
|
+
# Async command bus
|
|
360
|
+
async_command_bus = AsyncCommandBus(locator)
|
|
361
|
+
await async_command_bus.handle(command)
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## 📦 Message Brokers
|
|
365
|
+
|
|
366
|
+
### Supported Brokers
|
|
367
|
+
|
|
368
|
+
| Broker | Sync | Async | Installation |
|
|
369
|
+
| --------- | ---- | ----- | --------------------------- |
|
|
370
|
+
| In-Memory | ✅ | ✅ | Built-in |
|
|
371
|
+
| Kafka | ✅ | ✅ | `pip install buz[aiokafka]` |
|
|
372
|
+
| RabbitMQ | ✅ | ❌ | `pip install buz[kombu]` |
|
|
373
|
+
|
|
374
|
+
## 🧪 Testing
|
|
375
|
+
|
|
376
|
+
Buz includes testing utilities for unit and integration tests:
|
|
377
|
+
|
|
378
|
+
```python
|
|
379
|
+
from buz.event.sync import SyncEventBus
|
|
380
|
+
from buz.locator.sync import InstanceLocator
|
|
381
|
+
|
|
382
|
+
test_locator = InstanceLocator()
|
|
383
|
+
test_bus = SyncEventBus(test_locator)
|
|
384
|
+
|
|
385
|
+
test_locator.register(EmailSubscriber())
|
|
386
|
+
test_bus.publish(UserCreated(user_id="123", email="test@example.com"))
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
## 🔗 Related Projects
|
|
390
|
+
|
|
391
|
+
- **[buz-fever-shared](https://github.com/Feverup/buz-fever-shared)**: Opinionated utilities and standards for Buz
|
|
392
|
+
- **[buz-basic-example](https://github.com/Feverup/buz-basic-example)**: Complete example project with Docker setup
|
|
393
|
+
|
|
394
|
+
## 📋 Requirements
|
|
395
|
+
|
|
396
|
+
- Python 3.9+
|
|
397
|
+
- Optional dependencies based on features used
|
|
398
|
+
|
|
399
|
+
## 🤝 Contributing
|
|
400
|
+
|
|
401
|
+
We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.
|
|
402
|
+
|
|
403
|
+
### Development Setup
|
|
404
|
+
|
|
405
|
+
```bash
|
|
406
|
+
# Clone the repository
|
|
407
|
+
git clone https://github.com/Feverup/buz.git
|
|
408
|
+
cd buz
|
|
409
|
+
|
|
410
|
+
# Install with development dependencies
|
|
411
|
+
make build
|
|
412
|
+
|
|
413
|
+
# Run tests
|
|
414
|
+
make test
|
|
415
|
+
|
|
416
|
+
# Run linting
|
|
417
|
+
make lint
|
|
418
|
+
|
|
419
|
+
# Format code
|
|
420
|
+
make format
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
## 📄 License
|
|
424
|
+
|
|
425
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
426
|
+
|
|
427
|
+
## 📚 Documentation
|
|
428
|
+
|
|
429
|
+
- [Changelog](CHANGELOG.md) - Release notes and version history
|
|
430
|
+
|
|
431
|
+
## 🙋♀️ Support
|
|
432
|
+
|
|
433
|
+
- Create an [Issue](https://github.com/Feverup/buz/issues) for bug reports or feature requests
|
|
434
|
+
|
|
435
|
+
---
|
|
436
|
+
|
|
437
|
+
Made with ❤️ by the [Fever Platform Team](platform@feverup.com)
|
|
438
|
+
|