# Wireflow - DI Container for Python
<!-- markdownlint-disable MD033 -->
<p align="center">
<a href="/../../commits/" title="Last Commit"><img alt="Last Commit" src="https://img.shields.io/github/last-commit/lvlcn-t/wireflow?style=flat"></a>
<a href="/../../issues" title="Open Issues"><img alt="Open Issues" src="https://img.shields.io/github/issues/lvlcn-t/wireflow?style=flat"></a>
</p>
<!-- markdownlint-enable MD033 -->
- [What is Wireflow?](#what-is-wireflow)
- [Why Use Dependency Injection?](#why-use-dependency-injection)
- [Key Features of Wireflow](#key-features-of-wireflow)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Advanced Usage](#advanced-usage)
- [Example with Interface and Lifecycle Hooks](#example-with-interface-and-lifecycle-hooks)
- [What’s Happening Here?](#whats-happening-here)
- [Code of Conduct](#code-of-conduct)
- [Working Language](#working-language)
- [Support and Feedback](#support-and-feedback)
- [How to Contribute](#how-to-contribute)
- [Licensing](#licensing)
## What is Wireflow?
Wireflow is a simple yet powerful **Dependency Injection (DI)** container for Python. It helps you manage and organize dependencies in your Python applications, making your code cleaner, more modular, and easier to maintain.
Whether you're building a small script or a large application, Wireflow lets you register, resolve, and inject dependencies effortlessly, avoiding common pitfalls like tightly coupled code or manual dependency management.
### Why Use Dependency Injection?
Dependency Injection is a design pattern used to implement Inversion of Control (IoC) between classes and their dependencies. Instead of creating dependencies manually within a class, you "inject" them from the outside. This makes your code more flexible and easier to test.
### Key Features of Wireflow
- **Easy to Use**: Simple API that anyone can pick up quickly.
- **Singleton Support**: Manage dependencies as singletons to ensure only one instance exists.
- **Automatic Injection**: Use the `inject` decorator to automatically inject dependencies into your functions.
- **Lifecycle Hooks**: Define custom initialization and destruction behaviors for your dependencies.
- **Scoped Dependencies**: Manage dependencies within specific scopes, like per-request or per-session.
## Installation
To install Wireflow, simply run:
```bash
pip install wireflow
```
And import it into your Python code:
```python
import wireflow
```
## Quick Start
Getting started with Wireflow is straightforward. Here’s a basic example:
```python
import asyncio
from wireflow import container
class Greeter:
def greet(self) -> str:
return "Hello, World!"
async def main() -> None:
# Register the Greeter class as a dependency
await container.provide(
dependency=Greeter(),
singleton=True, # Ensures only one instance is created
)
# Resolve the dependency and use it
greeter = await container.resolve(Greeter)
print(greeter.greet())
# Run the example
if __name__ == "__main__":
asyncio.run(main())
```
In this example, we:
1. **Register** the `Greeter` class as a dependency in the container.
2. **Resolve** the dependency when needed.
3. **Use** the resolved dependency.
## Advanced Usage
Wireflow's flexibility shines in more complex scenarios, where you might need to work with interfaces, manage lifecycles, or inject dependencies automatically.
### Example with Interface and Lifecycle Hooks
Let’s look at a more advanced example:
```python
from __future__ import annotations
import asyncio
import abc
from wireflow import container, inject, Provide
# Define a greeter interface
class Greeter(abc.ABC):
@abc.abstractmethod
def greet(self) -> str: ...
# Define a service that implements the greeter interface
class WelcomeService(Greeter):
def greet(self) -> str:
return "Hello from MyService!"
# Define static methods for initialization and destruction hooks
@staticmethod
async def on_init(service: WelcomeService):
print(f"Service {service.__class__.__name__} initialized")
@staticmethod
async def on_destroy(service: WelcomeService):
print(f"Service {service.__class__.__name__} destroyed")
async def main() -> None:
# Register the service with lifecycle hooks and a request scope
await container.provide(
dependency=WelcomeService(),
singleton=True,
interface=Greeter, # Registering as the Greeter interface
on_init=WelcomeService.on_init,
on_destroy=WelcomeService.on_destroy,
scope="request", # Scoped to "request"
)
# Call a function without manually passing the service
await say_hello()
# Destroy the request scope after use
await container.destroy_scope("request")
# Function that automatically receives the injected service
@inject
async def say_hello(service: Greeter = Provide[WelcomeService]):
print(service.greet())
# Run the example
if __name__ == "__main__":
asyncio.run(main())
```
### What’s Happening Here?
1. **Interface Definition**: We define a `Greeter` interface using Python’s `abc` module.
2. **Service Implementation**: The `WelcomeService` class implements the `Greeter` interface.
3. **Lifecycle Hooks**: `on_init` and `on_destroy` methods are defined to perform actions when the service is initialized or destroyed.
4. **Dependency Registration**: The `WelcomeService` is registered with the container as a singleton under the `Greeter` interface.
5. **Automatic Injection**: The `say_hello` function receives the `WelcomeService` instance automatically, thanks to the `inject` decorator.
6. **Scope Management**: The service is scoped to a "request", and the scope is destroyed after use.
This approach makes it easy to swap out implementations, manage complex lifecycles, and keep your codebase clean and maintainable.
## Code of Conduct
This project has adopted the [Contributor Covenant](https://www.contributor-covenant.org/) version 2.1 as our code of conduct. Please see the details in our [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md). All contributors must abide by the code of conduct.
## Working Language
The primary language for this project is **English**. All content will be available in English, and we ask that all communication, issues, and contributions be made in English to ensure consistency and accessibility.
## Support and Feedback
For discussions, feedback, or support, please use the following channels:
<!-- markdownlint-disable MD033 -->
| Type | Channel |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Issues** | <a href="/../../issues/new/choose" title="General Discussion"><img alt="General Discussion" src="https://img.shields.io/github/issues/lvlcn-t/meta?style=flat-square"></a> |
<!-- markdownlint-enable MD033 -->
## How to Contribute
Contribution and feedback is encouraged and always welcome. For more information about how to contribute, the project
structure, as well as additional contribution information, see our [Contribution Guidelines](./CONTRIBUTING.md). By
participating in this project, you agree to abide by its [Code of Conduct](./CODE_OF_CONDUCT.md) at all times.
## Licensing
Copyright (c) 2024 lvlcn-t.
Licensed under the **MIT** (the "License"); you may not use this file except in compliance with
the License.
You may obtain a copy of the License at <https://www.mit.edu/~amini/LICENSE.md>.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "
AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the [LICENSE](./LICENSE) for
the specific language governing permissions and limitations under the License.
Raw data
{
"_id": null,
"home_page": "https://github.com/lvlcn-t/wireflow",
"name": "wireflow",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.11",
"maintainer_email": null,
"keywords": "dependency-injection, DI, dependency-injection-container, dependency-injection-framework, dependency-injection-library, dependency-injection-python, dependency-injection-python-library, dependency-injection-python-framework, dependency-injection-python-container",
"author": "lvlcn-t",
"author_email": "75443136+lvlcn-t@users.noreply.github.com",
"download_url": "https://files.pythonhosted.org/packages/d6/7e/6227ada303bf848358b57a47d484bbaec922ab7925a62c4ee0b382f5ce86/wireflow-0.1.0.tar.gz",
"platform": null,
"description": "# Wireflow - DI Container for Python\n\n<!-- markdownlint-disable MD033 -->\n<p align=\"center\">\n <a href=\"/../../commits/\" title=\"Last Commit\"><img alt=\"Last Commit\" src=\"https://img.shields.io/github/last-commit/lvlcn-t/wireflow?style=flat\"></a>\n <a href=\"/../../issues\" title=\"Open Issues\"><img alt=\"Open Issues\" src=\"https://img.shields.io/github/issues/lvlcn-t/wireflow?style=flat\"></a>\n</p>\n<!-- markdownlint-enable MD033 -->\n\n- [What is Wireflow?](#what-is-wireflow)\n - [Why Use Dependency Injection?](#why-use-dependency-injection)\n - [Key Features of Wireflow](#key-features-of-wireflow)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Advanced Usage](#advanced-usage)\n - [Example with Interface and Lifecycle Hooks](#example-with-interface-and-lifecycle-hooks)\n - [What\u2019s Happening Here?](#whats-happening-here)\n- [Code of Conduct](#code-of-conduct)\n- [Working Language](#working-language)\n- [Support and Feedback](#support-and-feedback)\n- [How to Contribute](#how-to-contribute)\n- [Licensing](#licensing)\n\n## What is Wireflow?\n\nWireflow is a simple yet powerful **Dependency Injection (DI)** container for Python. It helps you manage and organize dependencies in your Python applications, making your code cleaner, more modular, and easier to maintain.\n\nWhether you're building a small script or a large application, Wireflow lets you register, resolve, and inject dependencies effortlessly, avoiding common pitfalls like tightly coupled code or manual dependency management.\n\n### Why Use Dependency Injection?\n\nDependency Injection is a design pattern used to implement Inversion of Control (IoC) between classes and their dependencies. Instead of creating dependencies manually within a class, you \"inject\" them from the outside. This makes your code more flexible and easier to test.\n\n### Key Features of Wireflow\n\n- **Easy to Use**: Simple API that anyone can pick up quickly.\n- **Singleton Support**: Manage dependencies as singletons to ensure only one instance exists.\n- **Automatic Injection**: Use the `inject` decorator to automatically inject dependencies into your functions.\n- **Lifecycle Hooks**: Define custom initialization and destruction behaviors for your dependencies.\n- **Scoped Dependencies**: Manage dependencies within specific scopes, like per-request or per-session.\n\n## Installation\n\nTo install Wireflow, simply run:\n\n```bash\npip install wireflow\n```\n\nAnd import it into your Python code:\n\n```python\nimport wireflow\n```\n\n## Quick Start\n\nGetting started with Wireflow is straightforward. Here\u2019s a basic example:\n\n```python\nimport asyncio\n\nfrom wireflow import container\n\n\nclass Greeter:\n def greet(self) -> str:\n return \"Hello, World!\"\n\n\nasync def main() -> None:\n # Register the Greeter class as a dependency\n await container.provide(\n dependency=Greeter(),\n singleton=True, # Ensures only one instance is created\n )\n\n # Resolve the dependency and use it\n greeter = await container.resolve(Greeter)\n print(greeter.greet())\n\n\n# Run the example\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\nIn this example, we:\n\n1. **Register** the `Greeter` class as a dependency in the container.\n2. **Resolve** the dependency when needed.\n3. **Use** the resolved dependency.\n\n## Advanced Usage\n\nWireflow's flexibility shines in more complex scenarios, where you might need to work with interfaces, manage lifecycles, or inject dependencies automatically.\n\n### Example with Interface and Lifecycle Hooks\n\nLet\u2019s look at a more advanced example:\n\n```python\nfrom __future__ import annotations\n\nimport asyncio\nimport abc\n\nfrom wireflow import container, inject, Provide\n\n# Define a greeter interface\nclass Greeter(abc.ABC):\n @abc.abstractmethod\n def greet(self) -> str: ...\n\n\n# Define a service that implements the greeter interface\nclass WelcomeService(Greeter):\n def greet(self) -> str:\n return \"Hello from MyService!\"\n\n # Define static methods for initialization and destruction hooks\n @staticmethod\n async def on_init(service: WelcomeService):\n print(f\"Service {service.__class__.__name__} initialized\")\n\n @staticmethod\n async def on_destroy(service: WelcomeService):\n print(f\"Service {service.__class__.__name__} destroyed\")\n\n\nasync def main() -> None:\n # Register the service with lifecycle hooks and a request scope\n await container.provide(\n dependency=WelcomeService(),\n singleton=True,\n interface=Greeter, # Registering as the Greeter interface\n on_init=WelcomeService.on_init,\n on_destroy=WelcomeService.on_destroy,\n scope=\"request\", # Scoped to \"request\"\n )\n\n # Call a function without manually passing the service\n await say_hello()\n\n # Destroy the request scope after use\n await container.destroy_scope(\"request\")\n\n\n# Function that automatically receives the injected service\n@inject\nasync def say_hello(service: Greeter = Provide[WelcomeService]):\n print(service.greet())\n\n\n# Run the example\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\n### What\u2019s Happening Here?\n\n1. **Interface Definition**: We define a `Greeter` interface using Python\u2019s `abc` module.\n2. **Service Implementation**: The `WelcomeService` class implements the `Greeter` interface.\n3. **Lifecycle Hooks**: `on_init` and `on_destroy` methods are defined to perform actions when the service is initialized or destroyed.\n4. **Dependency Registration**: The `WelcomeService` is registered with the container as a singleton under the `Greeter` interface.\n5. **Automatic Injection**: The `say_hello` function receives the `WelcomeService` instance automatically, thanks to the `inject` decorator.\n6. **Scope Management**: The service is scoped to a \"request\", and the scope is destroyed after use.\n\nThis approach makes it easy to swap out implementations, manage complex lifecycles, and keep your codebase clean and maintainable.\n\n## Code of Conduct\n\nThis project has adopted the [Contributor Covenant](https://www.contributor-covenant.org/) version 2.1 as our code of conduct. Please see the details in our [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md). All contributors must abide by the code of conduct.\n\n## Working Language\n\nThe primary language for this project is **English**. All content will be available in English, and we ask that all communication, issues, and contributions be made in English to ensure consistency and accessibility.\n\n## Support and Feedback\n\nFor discussions, feedback, or support, please use the following channels:\n\n<!-- markdownlint-disable MD033 -->\n| Type | Channel |\n| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **Issues** | <a href=\"/../../issues/new/choose\" title=\"General Discussion\"><img alt=\"General Discussion\" src=\"https://img.shields.io/github/issues/lvlcn-t/meta?style=flat-square\"></a> |\n<!-- markdownlint-enable MD033 -->\n\n## How to Contribute\n\nContribution and feedback is encouraged and always welcome. For more information about how to contribute, the project\nstructure, as well as additional contribution information, see our [Contribution Guidelines](./CONTRIBUTING.md). By\nparticipating in this project, you agree to abide by its [Code of Conduct](./CODE_OF_CONDUCT.md) at all times.\n\n## Licensing\n\nCopyright (c) 2024 lvlcn-t.\n\nLicensed under the **MIT** (the \"License\"); you may not use this file except in compliance with\nthe License.\n\nYou may obtain a copy of the License at <https://www.mit.edu/~amini/LICENSE.md>.\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"\nAS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the [LICENSE](./LICENSE) for\nthe specific language governing permissions and limitations under the License.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A simple dependency injection library that allows you to provide and resolve dependencies.",
"version": "0.1.0",
"project_urls": {
"Homepage": "https://github.com/lvlcn-t/wireflow",
"Release Notes": "https://github.com/lvlcn-t/wireflow/releases",
"Repository": "https://github.com/lvlcn-t/wireflow",
"Source Code": "https://github.com/lvlcn-t/wireflow"
},
"split_keywords": [
"dependency-injection",
" di",
" dependency-injection-container",
" dependency-injection-framework",
" dependency-injection-library",
" dependency-injection-python",
" dependency-injection-python-library",
" dependency-injection-python-framework",
" dependency-injection-python-container"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "19ee491ada20b7eaf97b0ea89b2beda349eb6d7c0378a3c86e9475331fe0b6a4",
"md5": "95b6a96c7fbcece07e51b4ff5df4888f",
"sha256": "c58407a97491acc77d4742a3fcea6fc13bcfdc58b65881ab26147b1e3061b727"
},
"downloads": -1,
"filename": "wireflow-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "95b6a96c7fbcece07e51b4ff5df4888f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.11",
"size": 9667,
"upload_time": "2024-08-15T20:37:38",
"upload_time_iso_8601": "2024-08-15T20:37:38.264801Z",
"url": "https://files.pythonhosted.org/packages/19/ee/491ada20b7eaf97b0ea89b2beda349eb6d7c0378a3c86e9475331fe0b6a4/wireflow-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "d67e6227ada303bf848358b57a47d484bbaec922ab7925a62c4ee0b382f5ce86",
"md5": "71d0f47d813abed748e2ae72edca0c4a",
"sha256": "1658fceb85f5d6d69f95a45d1370941100752d726698743c75b3158b66fba860"
},
"downloads": -1,
"filename": "wireflow-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "71d0f47d813abed748e2ae72edca0c4a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.11",
"size": 11201,
"upload_time": "2024-08-15T20:37:39",
"upload_time_iso_8601": "2024-08-15T20:37:39.899556Z",
"url": "https://files.pythonhosted.org/packages/d6/7e/6227ada303bf848358b57a47d484bbaec922ab7925a62c4ee0b382f5ce86/wireflow-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-08-15 20:37:39",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "lvlcn-t",
"github_project": "wireflow",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "wireflow"
}