Skip to content

Type-hint-based Python dependency injection you can taste

License

Notifications You must be signed in to change notification settings

pyapp-kit/in-n-out

Repository files navigation

in-n-out

License PyPI Python Version CI codecov Benchmarks

Python dependency injection you can taste.

A lightweight dependency injection and result processing framework for Python using type hints. Emphasis is on simplicity, ease of use, and minimal impact on source code.

import in_n_out as ino


class Thing:
    def __init__(self, name: str):
        self.name = name


# use ino.inject to create a version of the function
# that will retrieve the required dependencies at call time
@ino.inject
def func(thing: Thing):
    return thing.name


def give_me_a_thing() -> Thing:
    return Thing("Thing")


# register a provider of Thing
ino.register_provider(give_me_a_thing)
print(func())  # prints "Thing"


def give_me_another_thing() -> Thing:
    return Thing("Another Thing")


with ino.register_provider(give_me_another_thing, weight=10):
    print(func())  # prints "Another Thing"

This also supports processing return values as well (injection of intentional side effects):

@ino.inject_processors
def func2(thing: Thing) -> str:
    return thing.name

def greet_name(name: str):
    print(f"Hello, {name}!")

ino.register_processor(greet_name)

func2(Thing('Bob'))  # prints "Hello, Bob!"

Alternatives

Lots of other python DI frameworks exist, here are a few alternatives to consider: