Knot is a small do-it-yourself (DIY) dependency container for Python.
Getting started
Unlike other existing implementations, knot does not make use of introspection. Therefore, dependencies are manually defined in a straight forward manner. The container acts as a central registry for providers and configuration settings.
Configuration settings
The container is just an ordinary dictionary with some additional methods. As a result, it is very easy to assign or retrieve data from it. Probably the most common way to assign configuration settings is passing a dict to the constructor.
from knot import Container c = Container({'host': 'localhost', 'port': 6379})
Obviously it is also possible to add configuration settings to an existing container.
c = Container() c['host'] = 'localhost' c['port'] = 6379
Providers
A provider creates and returns a particular value or object. It has the ability to utilize an injected container to retrieve the necessary configuration settings and dependencies.
The container expects a provider to adhere to the following rules:
- It must be callable.
- It must accept the container as the only argument.
- It must return anything except
None.
Assigning a provider to a container is easy.
def connection(c): from redis import Redis return Redis(host=c['host'], port=c['port']) c.add_provider(connection, True)
It is also possible to use a decorator.
from knot import provider @provider(c, True) def connection(c): from redis import Redis return Redis(host=c['host'], port=c['port'])
The second argument in c.add_provider(connection, True) and in
@provider(c, True) indicates whether or not the return value of a provider
must be cached.
Retrieve what you have defined.
conn = c.provide('connection')
For convenience, you can also use the shortcut.
Services
A service is just a provider with the cache argument set to True.
Basically this means the return value is created only once.
def connection(c): from redis import Redis return Redis(host=c['host'], port=c['port']) c.add_service(connection)
Or with a decorator.
from knot import service @service(c) def connection(c): from redis import Redis return Redis(host=c['host'], port=c['port']) conn1 = c('connection') conn2 = c('connection') print conn1 is conn2 # True
Factories
A factory is just a provider with the cache argument set to False.
Basically this means the return value is created on every call.
def urgent_job(c): from somewhere import Job connection = c('connection') return Job(connection=connection, queue='urgent') c.add_factory(urgent_job) job1 = c('urgent_job') job1.enqueue('send_activation_mail', username='johndoe') job2 = c('urgent_job') job2.enqueue('send_activation_mail', username='janedoe') print job1 is job2 # False
Or with a decorator.
from knot import @factory @factory(c) def urgent_job(c): from somewhere import Job connection = c('connection') return Job(connection=connection, queue='urgent')
Installation
Install Knot with the following command:
Tests
To run the tests, install tox first:
Then, run the tests with the following command:
Inspiration
Pimple (http://pimple.sensiolabs.org/)
License
MIT, see LICENSE for more details.