# waku
<p align="center" markdown="1">
<sup><i>waku</i> [<b>枠</b> or <b>わく</b>] <i>means framework in Japanese.</i></sup>
<br/>
</p>
-----
<div align="center" markdown="1">
<!-- Project Status -->
[](https://github.com/waku-py/waku/actions?query=event%3Apush+branch%3Amaster+workflow%3ACI/CD)
[](https://codecov.io/gh/waku-py/waku)
[](https://github.com/waku-py/waku/issues)
[](https://github.com/waku-py/waku/graphs/contributors)
[](https://github.com/waku-py/waku/graphs/commit-activity)
[](https://github.com/waku-py/waku/blob/master/LICENSE)
<!-- Package Info -->
[](https://pypi.python.org/pypi/waku)
[](https://www.python.org/downloads/)
[](https://pepy.tech/projects/waku)
<!-- Tools -->
[](https://github.com/astral-sh/uv)
[](https://github.com/astral-sh/ruff/)
[](https://mypy-lang.org/)
[](https://docs.basedpyright.com)
<!-- Social -->
[](https://t.me/wakupy)
</div>
-----
> **waku** is a modular, type-safe Python framework for scalable, maintainable applications.
> Inspired by [NestJS](https://nestjs.com/), powered by [Dishka](https://github.com/reagento/dishka/) IoC.
<!-- Separate quote blocks -->
> [!WARNING]
> `waku` is going through a major rewrite, so docs aren't fully up-to-date yet.
> Stick to this **README** and our [**examples**](https://github.com/waku-py/waku/tree/master/examples) for now.
>
> For more details, check out our [`waku` deepwiki](https://deepwiki.com/waku-py/waku/) page.
## Why `waku`?
- 🧩 [Modular architecture](https://waku-py.github.io/waku/usage/modules/): Group related code with explicit imports/exports for clear boundaries and responsibilities.
- 💉 [First-class Dependency Injection](https://waku-py.github.io/waku/usage/providers/): Built on [Dishka](https://github.com/reagento/dishka/) with flexible provider patterns (singleton, scoped, transient); swap implementations easily.
- 📨 [Event-driven & CQRS](https://waku-py.github.io/waku/usage/cqrs/): Handle commands, queries, and events with a comprehensive CQRS implementation, pipeline chains, and centralized processing inspired by [MediatR (C#)](https://github.com/jbogard/MediatR).
- 🔌 [Framework-agnostic & Integrations](https://waku-py.github.io/waku/integrations/): Works with FastAPI, Litestar, FastStream, Aiogram, and more - no vendor lock-in.
- 🧰 [Extensions & Lifecycle Hooks](https://waku-py.github.io/waku/usage/extensions/): Hook into the app lifecycle for logging, validation, and custom logic; [precise startup/shutdown management](https://waku-py.github.io/waku/usage/lifespan/).
- 🛡️ Production-ready: Type-safe APIs, robust validation, and scalable testing support.
## Who is it for?
- 👥 **Enterprise development teams** building modular, maintainable backend services or microservices
- 🏗️ **Architects and tech leads** seeking a structured framework with clear dependency boundaries and testability
- 🐍 **Python developers** frustrated with monolithic codebases and looking for better separation of concerns
- 🌏 **Engineers from other ecosystems** (Java Spring, C# ASP.NET, TypeScript NestJS) wanting familiar patterns in Python
- 📈 **Projects requiring scalability** both in codebase organization and team collaboration
## Quick Start
### Installation
```sh
uv add waku
# or
pip install waku
```
### Understanding the Basics
Waku is built around a few core concepts:
- 🧩 **Modules:** Classes decorated with `@module()` that define boundaries for application components and establish clear dependency relationships.
- 🧑🔧 **Providers:** Injectable services and logic registered within modules.
- 💉 **Dependency Injection:** Type-safe, flexible wiring powered by [Dishka](https://github.com/reagento/dishka/) IoC container.
- 🏭 **WakuFactory:** The entry point that creates a `WakuApplication` instance from your root module.
- 🔄 **Application Lifecycle:** Initialization and shutdown phases, enhanced with extension hooks.
This structure keeps your code clean and your dependencies explicit.
> `waku` is **framework-agnostic** - entrypoints (such as HTTP handlers) are provided by integrations, not the core.
### Basic Example
Here's a minimal example showing the core concepts:
```python
import asyncio
from waku import WakuFactory, module
from waku.di import scoped
# 1. Define a provider (service)
class GreetingService:
async def greet(self, name: str) -> str:
return f'Hello, {name}!'
# 2. Create a module and register the provider
@module(providers=[scoped(GreetingService)])
class GreetingModule:
pass
# 3. Create a root module that imports other modules
@module(imports=[GreetingModule])
class AppModule:
pass
async def main() -> None:
# 4. Bootstrap the application with WakuFactory
app = WakuFactory(AppModule).create()
# 5. Use the application with a properly scoped container
async with app, app.container() as c:
# 6. Resolve and use dependencies
svc = await c.get(GreetingService)
print(await svc.greet('waku'))
if __name__ == '__main__':
asyncio.run(main())
```
### More Realistic Example
Let's add protocols and module exports:
```python
import asyncio
from typing import Protocol
from waku import WakuFactory, module
from waku.di import scoped, singleton
# Define a protocol for loose coupling
class Logger(Protocol):
async def log(self, message: str) -> None: ...
# Implementation of the logger
class ConsoleLogger:
async def log(self, message: str) -> None:
print(f'[LOG] {message}')
# Service that depends on the logger
class UserService:
def __init__(self, logger: Logger) -> None:
self.logger = logger
async def create_user(self, username: str) -> str:
user_id = f'user_{username}'
await self.logger.log(f'Created user: {username}')
return user_id
# Infrastructure module provides core services
@module(
providers=[singleton(ConsoleLogger, provided_type=Logger)],
exports=[Logger], # Export to make available to other modules
)
class InfrastructureModule:
pass
# Feature module for user management
@module(
imports=[InfrastructureModule], # Import dependencies from other modules
providers=[scoped(UserService)],
)
class UserModule:
pass
# Application root module
@module(imports=[UserModule])
class AppModule:
pass
async def main() -> None:
app = WakuFactory(AppModule).create()
async with app, app.container() as c:
user_service = await c.get(UserService)
user_id = await user_service.create_user('alice')
print(f'Created user with ID: {user_id}')
if __name__ == '__main__':
asyncio.run(main())
```
### Next Steps
Want to learn more? Here's where to go next:
- Get familiar with [module exports and imports](https://waku-py.github.io/waku/usage/modules/)
- Try different [provider scopes](https://waku-py.github.io/waku/usage/providers/)
- Add [CQRS](https://waku-py.github.io/waku/usage/cqrs/) for clean command handling
- Use [extension hooks](https://waku-py.github.io/waku/usage/extensions/) to customize your app
- Connect with your [favorite framework](https://waku-py.github.io/waku/integrations/)
Check our [Getting Started](https://waku-py.github.io/waku/getting-started) guide and browse the [examples directory](https://github.com/waku-py/waku/tree/master/examples) for inspiration.
## Documentation
- [Getting Started](https://waku-py.github.io/waku/getting-started/)
- [Module System](https://waku-py.github.io/waku/usage/modules/)
- [Providers](https://waku-py.github.io/waku/usage/providers/)
- [Extensions](https://waku-py.github.io/waku/usage/extensions/)
- [CQRS](https://waku-py.github.io/waku/usage/cqrs/)
- [API Reference](https://waku-py.github.io/waku/reference/)
- [Dishka Documentation](https://dishka.readthedocs.io/en/stable/index.html/)
## Contributing
- [Contributing Guide](https://waku-py.github.io/waku/contributing/)
- [Development Setup](https://waku-py.github.io/waku/contributing/#development-setup)
### Top contributors
<a href="https://github.com/waku-py/waku/graphs/contributors">
<img src="https://contrib.rocks/image?repo=waku-py/waku" alt="contrib.rocks image" />
</a>
## Roadmap
- [ ] Create logo
- [ ] Improve inner architecture
- [ ] Improve documentation
- [ ] Add new and improve existing validation rules
- [ ] Provide example projects for common architectures
## Support
- [RU Telegram group](https://t.me/wakupy)
- [GitHub Issues](https://github.com/waku-py/waku/issues)
- [Discussions](https://github.com/waku-py/waku/discussions)
## License
This project is licensed under the terms of the [MIT License](https://github.com/waku-py/waku/blob/master/LICENSE).
## Acknowledgements
- [Dishka](https://github.com/reagento/dishka/) – Dependency Injection framework powering `waku` IoC container.
- [NestJS](https://nestjs.com/) – Primary inspiration for modular architecture, design patterns and some implementation details.
- [MediatR (C#)](https://github.com/jbogard/MediatR) – Inspiration and implementation details for the CQRS subsystem.
Raw data
{
"_id": null,
"home_page": null,
"name": "waku",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": null,
"keywords": "architecture, modular, decoupled, framework, dishka",
"author": "Daniil Kharkov, Doctor",
"author_email": "Daniil Kharkov <fadeddexofan@gmail.com>, Doctor <thirvondukr@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/71/f7/47f2ffdc1eaf617ab4fffd312420770bd0d1c83eb9ac53ef10df41c81448/waku-0.21.0.tar.gz",
"platform": null,
"description": "# waku\n\n<p align=\"center\" markdown=\"1\">\n <sup><i>waku</i> [<b>\u67a0</b> or <b>\u308f\u304f</b>] <i>means framework in Japanese.</i></sup>\n <br/>\n</p>\n\n-----\n\n<div align=\"center\" markdown=\"1\">\n\n<!-- Project Status -->\n[](https://github.com/waku-py/waku/actions?query=event%3Apush+branch%3Amaster+workflow%3ACI/CD)\n[](https://codecov.io/gh/waku-py/waku)\n[](https://github.com/waku-py/waku/issues)\n[](https://github.com/waku-py/waku/graphs/contributors)\n[](https://github.com/waku-py/waku/graphs/commit-activity)\n[](https://github.com/waku-py/waku/blob/master/LICENSE)\n\n<!-- Package Info -->\n[](https://pypi.python.org/pypi/waku)\n[](https://www.python.org/downloads/)\n[](https://pepy.tech/projects/waku)\n\n<!-- Tools -->\n[](https://github.com/astral-sh/uv)\n[](https://github.com/astral-sh/ruff/)\n[](https://mypy-lang.org/)\n[](https://docs.basedpyright.com)\n\n<!-- Social -->\n[](https://t.me/wakupy)\n\n</div>\n\n-----\n\n> **waku** is a modular, type-safe Python framework for scalable, maintainable applications.\n> Inspired by [NestJS](https://nestjs.com/), powered by [Dishka](https://github.com/reagento/dishka/) IoC.\n\n<!-- Separate quote blocks -->\n\n> [!WARNING]\n> `waku` is going through a major rewrite, so docs aren't fully up-to-date yet.\n> Stick to this **README** and our [**examples**](https://github.com/waku-py/waku/tree/master/examples) for now.\n>\n> For more details, check out our [`waku` deepwiki](https://deepwiki.com/waku-py/waku/) page.\n\n## Why `waku`?\n\n- \ud83e\udde9 [Modular architecture](https://waku-py.github.io/waku/usage/modules/): Group related code with explicit imports/exports for clear boundaries and responsibilities.\n- \ud83d\udc89 [First-class Dependency Injection](https://waku-py.github.io/waku/usage/providers/): Built on [Dishka](https://github.com/reagento/dishka/) with flexible provider patterns (singleton, scoped, transient); swap implementations easily.\n- \ud83d\udce8 [Event-driven & CQRS](https://waku-py.github.io/waku/usage/cqrs/): Handle commands, queries, and events with a comprehensive CQRS implementation, pipeline chains, and centralized processing inspired by [MediatR (C#)](https://github.com/jbogard/MediatR).\n- \ud83d\udd0c [Framework-agnostic & Integrations](https://waku-py.github.io/waku/integrations/): Works with FastAPI, Litestar, FastStream, Aiogram, and more - no vendor lock-in.\n- \ud83e\uddf0 [Extensions & Lifecycle Hooks](https://waku-py.github.io/waku/usage/extensions/): Hook into the app lifecycle for logging, validation, and custom logic; [precise startup/shutdown management](https://waku-py.github.io/waku/usage/lifespan/).\n- \ud83d\udee1\ufe0f Production-ready: Type-safe APIs, robust validation, and scalable testing support.\n\n## Who is it for?\n\n- \ud83d\udc65 **Enterprise development teams** building modular, maintainable backend services or microservices\n- \ud83c\udfd7\ufe0f **Architects and tech leads** seeking a structured framework with clear dependency boundaries and testability\n- \ud83d\udc0d **Python developers** frustrated with monolithic codebases and looking for better separation of concerns\n- \ud83c\udf0f **Engineers from other ecosystems** (Java Spring, C# ASP.NET, TypeScript NestJS) wanting familiar patterns in Python\n- \ud83d\udcc8 **Projects requiring scalability** both in codebase organization and team collaboration\n\n## Quick Start\n\n### Installation\n\n```sh\nuv add waku\n# or\npip install waku\n```\n\n### Understanding the Basics\n\nWaku is built around a few core concepts:\n\n- \ud83e\udde9 **Modules:** Classes decorated with `@module()` that define boundaries for application components and establish clear dependency relationships.\n- \ud83e\uddd1\u200d\ud83d\udd27 **Providers:** Injectable services and logic registered within modules.\n- \ud83d\udc89 **Dependency Injection:** Type-safe, flexible wiring powered by [Dishka](https://github.com/reagento/dishka/) IoC container.\n- \ud83c\udfed **WakuFactory:** The entry point that creates a `WakuApplication` instance from your root module.\n- \ud83d\udd04 **Application Lifecycle:** Initialization and shutdown phases, enhanced with extension hooks.\n\nThis structure keeps your code clean and your dependencies explicit.\n\n> `waku` is **framework-agnostic** - entrypoints (such as HTTP handlers) are provided by integrations, not the core.\n\n### Basic Example\n\nHere's a minimal example showing the core concepts:\n\n```python\nimport asyncio\n\nfrom waku import WakuFactory, module\nfrom waku.di import scoped\n\n\n# 1. Define a provider (service)\nclass GreetingService:\n async def greet(self, name: str) -> str:\n return f'Hello, {name}!'\n\n\n# 2. Create a module and register the provider\n@module(providers=[scoped(GreetingService)])\nclass GreetingModule:\n pass\n\n\n# 3. Create a root module that imports other modules\n@module(imports=[GreetingModule])\nclass AppModule:\n pass\n\n\nasync def main() -> None:\n # 4. Bootstrap the application with WakuFactory\n app = WakuFactory(AppModule).create()\n\n # 5. Use the application with a properly scoped container\n async with app, app.container() as c:\n # 6. Resolve and use dependencies\n svc = await c.get(GreetingService)\n print(await svc.greet('waku'))\n\n\nif __name__ == '__main__':\n asyncio.run(main())\n\n```\n\n### More Realistic Example\n\nLet's add protocols and module exports:\n\n```python\nimport asyncio\nfrom typing import Protocol\n\nfrom waku import WakuFactory, module\nfrom waku.di import scoped, singleton\n\n\n# Define a protocol for loose coupling\nclass Logger(Protocol):\n async def log(self, message: str) -> None: ...\n\n\n# Implementation of the logger\nclass ConsoleLogger:\n async def log(self, message: str) -> None:\n print(f'[LOG] {message}')\n\n\n# Service that depends on the logger\nclass UserService:\n def __init__(self, logger: Logger) -> None:\n self.logger = logger\n\n async def create_user(self, username: str) -> str:\n user_id = f'user_{username}'\n await self.logger.log(f'Created user: {username}')\n return user_id\n\n\n# Infrastructure module provides core services\n@module(\n providers=[singleton(ConsoleLogger, provided_type=Logger)],\n exports=[Logger], # Export to make available to other modules\n)\nclass InfrastructureModule:\n pass\n\n\n# Feature module for user management\n@module(\n imports=[InfrastructureModule], # Import dependencies from other modules\n providers=[scoped(UserService)],\n)\nclass UserModule:\n pass\n\n\n# Application root module\n@module(imports=[UserModule])\nclass AppModule:\n pass\n\n\nasync def main() -> None:\n app = WakuFactory(AppModule).create()\n\n async with app, app.container() as c:\n user_service = await c.get(UserService)\n user_id = await user_service.create_user('alice')\n print(f'Created user with ID: {user_id}')\n\n\nif __name__ == '__main__':\n asyncio.run(main())\n\n```\n\n### Next Steps\n\nWant to learn more? Here's where to go next:\n\n- Get familiar with [module exports and imports](https://waku-py.github.io/waku/usage/modules/)\n- Try different [provider scopes](https://waku-py.github.io/waku/usage/providers/)\n- Add [CQRS](https://waku-py.github.io/waku/usage/cqrs/) for clean command handling\n- Use [extension hooks](https://waku-py.github.io/waku/usage/extensions/) to customize your app\n- Connect with your [favorite framework](https://waku-py.github.io/waku/integrations/)\n\nCheck our [Getting Started](https://waku-py.github.io/waku/getting-started) guide and browse the [examples directory](https://github.com/waku-py/waku/tree/master/examples) for inspiration.\n\n## Documentation\n\n- [Getting Started](https://waku-py.github.io/waku/getting-started/)\n- [Module System](https://waku-py.github.io/waku/usage/modules/)\n- [Providers](https://waku-py.github.io/waku/usage/providers/)\n- [Extensions](https://waku-py.github.io/waku/usage/extensions/)\n- [CQRS](https://waku-py.github.io/waku/usage/cqrs/)\n- [API Reference](https://waku-py.github.io/waku/reference/)\n- [Dishka Documentation](https://dishka.readthedocs.io/en/stable/index.html/)\n\n## Contributing\n\n- [Contributing Guide](https://waku-py.github.io/waku/contributing/)\n- [Development Setup](https://waku-py.github.io/waku/contributing/#development-setup)\n\n### Top contributors\n\n<a href=\"https://github.com/waku-py/waku/graphs/contributors\">\n <img src=\"https://contrib.rocks/image?repo=waku-py/waku\" alt=\"contrib.rocks image\" />\n</a>\n\n## Roadmap\n\n- [ ] Create logo\n- [ ] Improve inner architecture\n- [ ] Improve documentation\n- [ ] Add new and improve existing validation rules\n- [ ] Provide example projects for common architectures\n\n## Support\n\n- [RU Telegram group](https://t.me/wakupy)\n- [GitHub Issues](https://github.com/waku-py/waku/issues)\n- [Discussions](https://github.com/waku-py/waku/discussions)\n\n## License\n\nThis project is licensed under the terms of the [MIT License](https://github.com/waku-py/waku/blob/master/LICENSE).\n\n## Acknowledgements\n\n- [Dishka](https://github.com/reagento/dishka/) \u2013 Dependency Injection framework powering `waku` IoC container.\n- [NestJS](https://nestjs.com/) \u2013 Primary inspiration for modular architecture, design patterns and some implementation details.\n- [MediatR (C#)](https://github.com/jbogard/MediatR) \u2013 Inspiration and implementation details for the CQRS subsystem.\n",
"bugtrack_url": null,
"license": null,
"summary": "Framework for building modular and loosely coupled applications",
"version": "0.21.0",
"project_urls": {
"Changelog": "https://github.com/waku-py/waku/blob/master/CHANGELOG.md",
"Documentation": "https://waku-py.github.io/waku/",
"Issues": "https://github.com/waku-py/waku/issues",
"Repository": "https://github.com/waku-py/waku"
},
"split_keywords": [
"architecture",
" modular",
" decoupled",
" framework",
" dishka"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "5efc406e7ac2722c91e1ed37f3fe42b50f315c403e08800f48f4a1b4fd1c7a62",
"md5": "1c44f6e9db7bbcba8e63838ae48a67d4",
"sha256": "71e4d45744632d53823b2ab4c686b8960921bca628faeb5c92aa4f241af70e6b"
},
"downloads": -1,
"filename": "waku-0.21.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "1c44f6e9db7bbcba8e63838ae48a67d4",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 37231,
"upload_time": "2025-07-20T17:20:22",
"upload_time_iso_8601": "2025-07-20T17:20:22.079380Z",
"url": "https://files.pythonhosted.org/packages/5e/fc/406e7ac2722c91e1ed37f3fe42b50f315c403e08800f48f4a1b4fd1c7a62/waku-0.21.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "71f747f2ffdc1eaf617ab4fffd312420770bd0d1c83eb9ac53ef10df41c81448",
"md5": "1e20812584b48cace3cf2c008b9dd681",
"sha256": "d454fb9c21ba8440f7e3f884c1f17ba20dc5938df177415e03df74218a254257"
},
"downloads": -1,
"filename": "waku-0.21.0.tar.gz",
"has_sig": false,
"md5_digest": "1e20812584b48cace3cf2c008b9dd681",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 24196,
"upload_time": "2025-07-20T17:20:23",
"upload_time_iso_8601": "2025-07-20T17:20:23.399387Z",
"url": "https://files.pythonhosted.org/packages/71/f7/47f2ffdc1eaf617ab4fffd312420770bd0d1c83eb9ac53ef10df41c81448/waku-0.21.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-20 17:20:23",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "waku-py",
"github_project": "waku",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "waku"
}