The Botox is a lightweight dependency injection pattern implementation for Python.
Project description
Botox
Botox is a lightweight dependency injection implementation based on Python typing. It helps deliver the configured functional objects, decreasing coupling between a class and its dependencies.
Delivery
Global variables? Proxy objects? Application context?
There should be one (and preferably only one) obvious way to do it.
Botox helps you isolate a class from the impact of different design changes and defects. Meaning that, instead of thinking about interdependence between software modules you will now find yourself spending much of your time having to focus a class on the task it is designed for.
Configuration
Monkey-patching? Decorators?
Explicit is better than implicit.
Botox allows a class the flexibility of being configurable. The class may act on anything that supports the intrinsic interface the class expects. Explicit configurations can be written separately for different situations that require different implementations of dependencies.
Usage
Now is better than never.
Botox doesn’t require any change in code behavior it can be applied to legacy code as a refactoring.
Installation
Install and update using pip:
pip install -U botox-di
Examples
Class Injection
Can be used to reduce boilerplate code in the application classes since all work to initialize or set up dependencies is handled separately.
class PaymentService:
...
class BillingService:
...
class SalesService:
def __init__(self, payment_service: PaymentService, billing_service: BillingService):
self.payment_service = payment_service
self.billing_service = billing_service
...
injector = Injector()
injector.prepare(PaymentService)
injector.prepare(BillingService)
injector.prepare(SalesService)
sales = injector.deliver(SalesService)
sales.do_something()
The result is class that is easier to unit test in isolation using stubs or mock objects that simulate other objects.
# test_sales.py
injector.prepare(PaymentService, PaymentServiceStub)
Value Injection
Can be used when exactly one object is needed to coordinate actions across the system.
class AppSettings:
...
settings = AppSettings()
injector = Injector()
injector.prepare(AppSettings, settings)
assert injector.deliver(AppSettings) is settings
Lambda Injection
Can be used to wrap Proxy objects in legacy code as refactoring.
from flask import g, current_app
injector = Injector()
injector.prepare(Flask, lambda: current_app)
injector.prepare(Something, lambda: g.something)
Function Injection
Can be used to make factory functions with dependencies.
def create_api_client(settings: Settings):
with open(settings.api_configuration_file) as file:
key, url = file.read(...)
return ApiClient(key, url)
injector = Injector()
injector.provide(Settings)
injector.provide(ApiClient, create_api_client)
Advanced
from aiohttp import web
from botox import Injector
class TemplateRepository:
def get_template(self):
return "Hello, {}!"
class HelloService:
def __init__(self, template_repository: TemplateRepository):
self.template_repository = template_repository
def get_hello_message(self, name):
template = self.template_repository.get_template()
return template.format(name)
async def handle(request):
service = request.app.injector.deliver(HelloService)
name = request.match_info.get('name', "Anonymous")
text = service.get_hello_message(name)
return web.Response(text=text)
app = web.Application()
app.injector = Injector()
app.injector.prepare(HelloService)
app.injector.prepare(TemplateRepository)
app.add_routes([
web.get('/', handle),
web.get('/{name}', handle)
])
web.run_app(app)
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 botox-di-1.4.0.tar.gz
.
File metadata
- Download URL: botox-di-1.4.0.tar.gz
- Upload date:
- Size: 4.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.11.0 pkginfo/1.4.2 requests/2.11.1 setuptools/39.1.0 requests-toolbelt/0.8.0 tqdm/4.24.0 CPython/3.7.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ded50a2c5eccc13d811e662dbf9f2920d4341d188c24fee9cc5f157c4d0817d4 |
|
MD5 | 449bdc43bd13069f3f5da68f1a14b34c |
|
BLAKE2b-256 | 765ef661443d65efc43b763e6b32b75c5fafee15883678fd26f20c6bf0ef4fc9 |
File details
Details for the file botox_di-1.4.0-py3-none-any.whl
.
File metadata
- Download URL: botox_di-1.4.0-py3-none-any.whl
- Upload date:
- Size: 4.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.11.0 pkginfo/1.4.2 requests/2.11.1 setuptools/39.1.0 requests-toolbelt/0.8.0 tqdm/4.24.0 CPython/3.7.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | efe1622455a38cea3a53f8fb1ab590ad25a262bbf0fd90652c88681d5da239a1 |
|
MD5 | 93f71d0f37a75f23866f89fb3ee7e963 |
|
BLAKE2b-256 | 00905614648cfa2b381c630962ed3127bdf9e0afa89d7dd0358c0ea1c5f77f5a |