PyBooster
Warning
This project is still under development - use at your own risk.
Dependency injection without the boilerplate.
Installation
At a Glance
Getting started with PyBooster involves a few steps:
- Define a provider function for a dependency.
- Add an injector to a function that will use that dependency.
- Activate a solution and call the dependent function in its context.
The example below injects a sqlite3.Connection into a function that executes SQL:
import sqlite3
from collections.abc import Iterator
from tempfile import NamedTemporaryFile
from pybooster import injector
from pybooster import provider
from pybooster import required
from pybooster import solution
@provider.contextmanager
def sqlite_connection(database: str) -> Iterator[sqlite3.Connection]:
    with sqlite3.connect(database) as conn:
        yield conn
@injector.function
def sql(cmd: str, *, conn: sqlite3.Connection = required) -> sqlite3.Cursor:
    return conn.execute(cmd)
tempfile = NamedTemporaryFile()
with solution(sqlite_connection(tempfile.name)):
    sql("CREATE TABLE example (id INTEGER PRIMARY KEY, name TEXT)")
    sql("INSERT INTO example (name) VALUES ('alice')")
    cursor = sql("SELECT * FROM example")
    assert cursor.fetchone() == (1, "alice")
This works by inspecting the type hints of the provider sqlite_connection to see that
it produces a sqlite3.Connection. Simarly, the signature of the dependant function
query_database is inspected to see that it requires a sqlite3.Connection. At that
point, when query_database is called it checks to see if there's a
sqlite3.Connection provider in the current solution and, if so, injects it into the
function.