hexastack-cqrs
Command Query Responsibility Segregation (CQRS) buses, execution pipelines, and middleware for Hexastack.
Part of the Hexastack Framework · Governed by Hexaqual.
1. Overview & Capabilities
hexastack-cqrs powers the application logic layer of Hexastack applications, enforcing a strict separation between write operations (Commands) and read projections (Queries):
- Synchronous & Asynchronous Buses:
SynchronousCommandBus,SynchronousQueryBus,SynchronousEventBus, and async/distributed buses. - Composable Middleware Pipeline: Pluggable middlewares executed sequentially before and after command/query handling:
InOutMiddleware&AsyncInOutMiddleware: Standardized base class template withbefore,after, andon_errorlifecycle hooks.CorrelationMiddleware: Propagates correlation IDs across requests and async tasks.TimingMiddleware: Measures and records execution latency.LoggingMiddleware: Logs execution lifecycles and errors viaLoggerPort(dynamically gated viafeatures.cqrs.logging).CircuitBreakerMiddleware&AsyncCircuitBreakerMiddleware: Non-blocking fail-fast circuit breaker protecting commands/queries from cascading outages.StaminaRetryMiddleware: Modern exponential backoff with full jitter powered bystamina(dynamically gated viafeatures.cqrs.retry).TenacityRetryMiddleware: Exponential backoff and retry policies powered bytenacity(dynamically gated viafeatures.cqrs.retry).UnitOfWorkMiddleware: Automatic transaction scoping (commit()on success,rollback()on failure).ConditionalFeatureFlagMiddleware: Evaluates dynamic feature flags before dispatching commands/queries.
- Declarative Decorators & Scanning:
@command_handler,@query_handler,@event_handler,@circuit_breaker, and@feature_flagregistered via reflective module scanning. - Declarative Query Caching & Tag Invalidation:
@cached_query(ttl_seconds, tags, key_fields): Declaratively caches read projections inCachePort/AsyncCachePort.@invalidates_cache(tags): Automatically invalidates related cached tag groups when modifying Commands succeed.QueryCachingMiddleware&CommandCacheInvalidationMiddleware: Intercept query executions and command results to manage cache lifecycles transparently.
- Presenter & Response Mapping: Integration with
PresenterPortfor formatting outputs across CLI and REST adapters.
2. Package Anatomy & Key Components
hexastack_cqrs/
├── domain/ # Command, Query, Event, Handler protocols, CQRS exceptions
├── ports/ # CommandBusPort, QueryBusPort, EventBusPort, MiddlewarePort
├── adapters/ # Buses (Synchronous & Asynchronous with Huey)
└── infra/ # CqrsBootstrapper (order=20), Middleware pipeline, InOutMiddleware, Registries, @cached_query, @circuit_breaker, @feature_flag
Key Exports
| Category | Exports |
|---|---|
| Adapters | SynchronousCommandBus, SynchronousQueryBus, SynchronousEventBus, HueyCommandBus, HueyEventBus |
| Bootstrap | CqrsBootstrapper (order=20), CqrsConfig |
| Decorators | @command_handler, @query_handler, @event_handler, @circuit_breaker, @cached_query, @invalidates_cache, @feature_flag, @presenter |
| Domain | Command, Query, Event, CommandHandler, QueryHandler, EventHandler |
| Middlewares | AsyncCircuitBreakerMiddleware, AsyncInOutMiddleware, CircuitBreakerMiddleware, CommandCacheInvalidationMiddleware, ConditionalFeatureFlagMiddleware, CorrelationMiddleware, ExecutionPipeline, InOutMiddleware, LoggingMiddleware, QueryCachingMiddleware, StaminaRetryMiddleware, TenacityRetryMiddleware, TimingMiddleware, UnitOfWorkMiddleware |
| Ports | CommandBusPort, QueryBusPort, EventBusPort, MiddlewarePort |
3. Monorepo & Sibling Relationships
graph TD
subgraph DrivingAdapters ["Inbound Driving Adapters"]
FASTAPI["hexastack-fastapi"]
GRAPHQL["hexastack-graphql"]
MCP["hexastack-mcp"]
GRPC["hexastack-grpc"]
CLI["hexastack-cli"]
end
subgraph CQRS ["hexastack-cqrs"]
CBUS["CommandBusPort"]
QBUS["QueryBusPort"]
EBUS["EventBusPort"]
PIPE["Middleware Pipeline"]
end
subgraph DrivenDependencies ["Driven Subsystems & Kernel"]
CORE["hexastack-core (DI & Kernel)"]
DB["hexastack-db (UnitOfWorkPort)"]
LOG["hexastack-logging (LoggerPort)"]
end
FASTAPI -->|dispatches to| CBUS
FASTAPI -->|dispatches to| QBUS
GRAPHQL -->|dispatches to| CBUS
GRAPHQL -->|dispatches to| QBUS
MCP -->|dispatches to| CBUS
MCP -->|dispatches to| QBUS
GRPC -->|dispatches to| CBUS
GRPC -->|dispatches to| QBUS
CLI -->|dispatches to| CBUS
CLI -->|dispatches to| QBUS
CBUS --> PIPE
QBUS --> PIPE
EBUS --> PIPE
PIPE -->|managed by| CORE
PIPE -. consumes from DI .-> DB
PIPE -. consumes from DI .-> LOG
Explicit Dependencies (Direct)
hexastack-core: Core kernel, DI container, base exceptions, and ports.tenacity>=9.0.0: Resilient retry policies with exponential backoff.
Implied / Behavioral Relationships (DI-Mediated)
- UnitOfWork Scoping:
UnitOfWorkMiddlewaredynamically resolvesUnitOfWorkPortfrom the DI container (injected byhexastack-db) to manage transactions. - Telemetry Integration:
LoggingMiddlewaredynamically resolvesLoggerPortfrom the DI container (injected byhexastack-logging). - Driving Adapters: Consumed by
hexastack-fastapiandhexastack-clito route incoming user actions to business handlers.
Optional Integrations (Extras)
[huey]: Enables asynchronous, distributed task queue execution usingHueyCommandBusandHueyEventBus.
4. Installation
# Standalone installation
pip install hexastack-cqrs
# With asynchronous distributed background worker (Huey)
pip install "hexastack-cqrs[huey]"
# Via umbrella package
pip install hexastack
5. Configuration Reference
[hexastack.cqrs]
enable_correlation = true
enable_timing = true
enable_logging = true
enable_uow = true
retry_attempts = 3
retry_backoff_base = 0.5
6. Quickstart Example
from dataclasses import dataclass
from hexastack_core.infra.bootstrap import bootstrap
from hexastack_cqrs.domain.command import Command
from hexastack_cqrs.infra.decorators import command_handler
from hexastack_cqrs.ports.buses import CommandBusPort
@dataclass(frozen=True)
class CreateOrderCommand(Command):
order_id: str
amount: float
@command_handler(CreateOrderCommand)
class CreateOrderHandler:
def __call__(self, cmd: CreateOrderCommand) -> str:
return f"Order {cmd.order_id} created for ${cmd.amount:.2f}"
runtime = bootstrap(packages_to_scan=[__name__])
bus = runtime.container.get(CommandBusPort)
result = bus.dispatch(CreateOrderCommand(order_id="ord-99", amount=49.99))
print(result) # "Order ord-99 created for $49.99"
Metadata
Release files for hexastack-cqrs 0.8.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hexastack_cqrs-0.8.0.tar.gz | 27.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hexastack_cqrs-0.8.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 75.6 kB
Release files / hexastack_cqrs-0.8.0.tar.gz
| Download URL | hexastack_cqrs-0.8.0.tar.gz |
|---|---|
| Size | 27.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
898b522b22b278a4ad56db036d169c09cb84de06d9dc08d6dee96d4c73aad6e3
|
|
BLAKE2b-256 checksum How to use checksums |
c0cd553760adbd1ea1d960641792ae27d6b653427b8dfc6198c47e0aef1871f3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / hexastack_cqrs-0.8.0-py3-none-any.whl
| Download URL | hexastack_cqrs-0.8.0-py3-none-any.whl |
|---|---|
| Size | 48.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
415e270a202603bc9bda64094da79bbbe8a77eb0325c7fbb33349e6d4dce0683
|
|
BLAKE2b-256 checksum How to use checksums |
83fc04dae75a791a1d644fe1802473ed797e05dd8bbe7cf3fd820b3dd031ac07
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|