Overview
枠 · framework for Python backends that grow
Python makes it easy to build a backend. waku makes it easy to keep growing one.
As your project scales, problems creep in: services import each other freely, swapping a database means editing dozens of files, and nobody can tell which module depends on what. Python has no built-in way to enforce component boundaries — so what starts as clean code quietly becomes a tangle of implicit dependencies that discipline alone can't prevent.
waku gives you modules with explicit boundaries, type-safe DI powered by Dishka, and integrated CQRS and event sourcing — so your codebase stays manageable as it scales.
Installation¶
Structure that scales¶
-
Package by Component
Each module is a self-contained unit with its own providers. Explicit imports and exports control what crosses boundaries — validated at startup, not discovered in production.
-
Dependency Inversion
Define interfaces in your application core, bind adapters in infrastructure modules. Swap a database, a cache, or an API client by changing one provider — powered by Dishka.
-
One Core, Any Entrypoint
Build your module tree once with
WakuFactory. Plug it into FastAPI, Litestar, FastStream, Aiogram, CLI, or workers — same logic everywhere.
Built-in capabilities¶
-
CQRS & Mediator
DI alone doesn't decouple components — you need events. The mediator dispatches commands, queries, and events so components never reference each other directly. Pipeline behaviors handle cross-cutting concerns.
-
Event Sourcing
Full event sourcing support — aggregates, projections, snapshots, upcasting, and the decider pattern with built-in SQLAlchemy adapters.
-
Lifecycle & Extensions
Hook into startup, shutdown, and module initialization with extensions. Add validation, logging, or custom behaviors — decoupled from your business logic.
How it works¶
Group related providers into modules with explicit imports and exports.
WakuFactory wires the module tree into a DI container. Plug it into your
framework — FastAPI, Litestar, or anything else — and you're done.
Recommended project structure
Following Explicit Architecture and its code reflection, only UI and shared infrastructure live at the top level — each feature component is a vertical slice with its own domain, application, and infrastructure layers, wired together by a waku module:
your_app/
├── core/
│ ├── components/
│ │ ├── users/ # feature component
│ │ │ ├── domain/ # entities, value objects, events
│ │ │ ├── application/ # use cases, handlers, ports
│ │ │ ├── infra/ # repositories, adapters
│ │ │ └── module.py # waku module
│ │ └── orders/
│ │ ├── domain/
│ │ ├── application/
│ │ ├── infra/
│ │ └── module.py
│ ├── ports/ # shared system ports
│ └── shared_kernel/ # cross-component contracts
├── infra/ # cross-cutting infrastructure
│ └── module.py
├── ui/ # API routes, CLI handlers
└── app.py # composition root
Quick example¶
A service, a module, and a container — the minimal waku app:
Modules control visibility. InfrastructureModule exports ILogger —
UserModule imports it. Dependencies are explicit, not implicit.
Next steps¶
-
Install waku, build a modular app, and connect it to your framework
-
Working projects showing real usage patterns with FastAPI, Litestar, and more
-
Full module, class, and function reference