A simple dependency injection library that allows you to provide and resolve dependencies.
Project description
Wireflow - DI Container for Python
- What is Wireflow?
- Installation
- Quick Start
- Advanced Usage
- Code of Conduct
- Working Language
- Support and Feedback
- How to Contribute
- 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:
pip install wireflow
And import it into your Python code:
import wireflow
Quick Start
Getting started with Wireflow is straightforward. Here’s a basic example:
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:
- Register the
Greeter
class as a dependency in the container. - Resolve the dependency when needed.
- 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:
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?
- Interface Definition: We define a
Greeter
interface using Python’sabc
module. - Service Implementation: The
WelcomeService
class implements theGreeter
interface. - Lifecycle Hooks:
on_init
andon_destroy
methods are defined to perform actions when the service is initialized or destroyed. - Dependency Registration: The
WelcomeService
is registered with the container as a singleton under theGreeter
interface. - Automatic Injection: The
say_hello
function receives theWelcomeService
instance automatically, thanks to theinject
decorator. - 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 version 2.1 as our code of conduct. Please see the details in our 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:
Type | Channel |
---|---|
Issues |
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. By participating in this project, you agree to abide by its Code of Conduct 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 for the specific language governing permissions and limitations under the License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file wireflow-0.1.0.tar.gz
.
File metadata
- Download URL: wireflow-0.1.0.tar.gz
- Upload date:
- Size: 11.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.12.4 Linux/5.15.153.1-microsoft-standard-WSL2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1658fceb85f5d6d69f95a45d1370941100752d726698743c75b3158b66fba860 |
|
MD5 | 71d0f47d813abed748e2ae72edca0c4a |
|
BLAKE2b-256 | d67e6227ada303bf848358b57a47d484bbaec922ab7925a62c4ee0b382f5ce86 |
File details
Details for the file wireflow-0.1.0-py3-none-any.whl
.
File metadata
- Download URL: wireflow-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.12.4 Linux/5.15.153.1-microsoft-standard-WSL2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | c58407a97491acc77d4742a3fcea6fc13bcfdc58b65881ab26147b1e3061b727 |
|
MD5 | 95b6a96c7fbcece07e51b4ff5df4888f |
|
BLAKE2b-256 | 19ee491ada20b7eaf97b0ea89b2beda349eb6d7c0378a3c86e9475331fe0b6a4 |