dependency

A dependency injection framework for Python.


License
BSD-3-Clause
Install
pip install dependency==0.0.3

Documentation

Dependency

A dependency injection library, using Python type annotations.

Dependency Injection is a pattern that can help with managing complexity and testability in large codebases.

The dependency package provides the building blocks required to implement type-annotation based dependency injection.

Examples

Web framework

Let's take a look at the sort of code the dependency package allows you to write.

In this case we've got a web framework that supports dependency injected components to provide the information that each view uses:

from web_framework import Method, Path, Headers, App, Response
import json


def echo_request_info(method: Method, path: Path, headers: Headers):
    content = json.dumps({
        'method': method,
        'path': path,
        'headers': dict(headers)
    }, indent=4).encode('utf-8')
    return Response(content)


def echo_user_agent(user_agent: Header):
    content = json.dumps({
        'User-Agent': user_agent
    }, indent=4).encode('utf-8')
    return Response(content)


app = App({
    '/request/': echo_request_info,
    '/user-agent/': echo_user_agent
})


if __name__ == '__main__':
    app.run()

You can see that the views have more expressive interfaces and are more easily testable, than if every function accepted a single request argument.

The framework source code is available here: /examples/web_framework.py

The dependency package supports context managers, so you could also provide components such as a Session that automatically handles commit/rollback depending on if a view returns normally or raises an exception.

Test framework

Here's another example, of using dependency to create a testing framework that supports dependency-injection of reusable components into test cases...

from tempfile import TemporaryDirectory
from examples.test_framework import run_tests
import dependency
import os


@dependency.provider
def get_temp_dir() -> TemporaryDirectory:
    """
    A temporary directory component that may be injected into test cases.
    Each directory will only exist for the lifetime of a single test.
    """
    return TemporaryDirectory()


def test_list_empty_directory(tmp_dir: TemporaryDirectory):
    assert len(os.listdir(tmp_dir.name)) == 0


def test_list_nonempty_directory(tmp_dir: TemporaryDirectory):
    path = os.path.join(tmp_dir.name, 'example.txt')
    open(path, 'w').close()
    assert len(os.listdir(tmp_dir.name)) == 1


if __name__ == "__main__":
    run_tests()

The framework source code is available here: /examples/test_framework.py


API Reference

...