Skip to main content

Another Python Dependency injector framework.

Project description

Python Injection Framework (PIF)

python version coverage pytest ruff

A simple Python dependency injection framework.

Usage

This project is under active development. The following example does not represent the final state for the project.

You can install this project from pypi.

pip install python-injection-framework

Dependency Injection

The injection framework is configured to inject any default values for method arguments that are instances of providers.Provider.

This implementation works by wrapping decorators around methods any patching any unfilled providers.Provider default arguments at runtime.

All dependency injection is lazily evaluated so providers are only evaluated when a method is called. This approach is optimal as it reduces necessary computation for expensive services and reduces

Decorator Injection

With this approach you can automatically inject functions at load time using the @wiring.inject decorator.

from pif import wiring, providers


@wiring.inject  # <- automatically injects providers.Provider default arguments!
def my_function(a: str = providers.ExistingSingleton("hello world")):
    return a


if __name__ == "__main__":
    assert "hello world" == my_function()

Module Injection

With this approach you can wire all methods in the specified modules.

from pif import wiring, providers


def my_function(a: str = providers.ExistingSingleton("hello world")):
    return a


if __name__ == "__main__":
    wiring.wire([__name__])  # <- dynamically inject methods with providers.Provider default arguments!

    assert "hello world" == my_function()

Overriding

This package provides a simple mechanism to override providers. This can be very useful when it comes to mocking services for testing or dynamically patching application behavior based on application configuration.

Standard Overriding

If you want to patch a value all you need to do is call .override() on the provider in question. If you are wanting to override an existing singleton you may call the convenience method .override_existing().

from pif import wiring, providers

StringProvider = providers.ExistingSingleton("hello world")


@wiring.inject
def my_function(a: str = StringProvider):
    return a


if __name__ == "__main__":
    assert "hello world" == my_function()

    override = StringProvider.override_existing("overridden_1")

    assert "overridden_1"

Context Managers

If you want more control around the override lifecycles then you may use the Override context manager.

from pif import wiring, providers

StringProvider = providers.ExistingSingleton("hello world")


@wiring.inject
def my_function(a: str = StringProvider):
    return a


if __name__ == "__main__":
    assert "hello world" == my_function()

    OverrideProvider = providers.ExistingSingleton("overridden_1")

    with StringProvider.override(OverrideProvider):
        assert "overridden_1" == my_function()

        with OverrideProvider.override_existing("overridden_2"):
            assert "overridden_2" == my_function()  # You can even stack overrides!!

        assert "overridden_1" == my_function()

    assert "hello world" == my_function()

Examples

If you would like to see more examples, feel free to check out examples/.

Contributing

  1. Clone the repository and configure Poetry 🪄

    git clone git@github.com:scottzach1/Python-Injection-Framework.git
    cd Python-Injection-Framework
    poetry install
    
  2. Configure pre-commit hooks 🪝

    pre-commit install
    
  3. Write your changes! 💻️

  4. Run test cases 🧪

    pytest tests/
    
  5. Submit a Pull Request ↖️

Authors

Zac Scott
Zac Scott (scottzach1)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

python_injection_framework-0.0.2.tar.gz (7.5 kB view details)

Uploaded Source

Built Distribution

File details

Details for the file python_injection_framework-0.0.2.tar.gz.

File metadata

File hashes

Hashes for python_injection_framework-0.0.2.tar.gz
Algorithm Hash digest
SHA256 58f5206c42507ae161e692e0c3114b532f4224191fd004fb53b9514bc712ce84
MD5 33ab271bcfac3fe933cbd64d34f367dd
BLAKE2b-256 4fd89c08c1b7b1f8002e79d71b894f00f746a8ec3b3a0b093dd08f39fc105d2b

See more details on using hashes here.

File details

Details for the file python_injection_framework-0.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for python_injection_framework-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 da0a7c03407a74736d560a085db0e195213a2348cfd61e5b404c93fa886d17fc
MD5 bfb92b7ca012cc741a2f9dbb4ab4643f
BLAKE2b-256 531e23f9b6bb3ee033ed864ce483632a0a228975f1ef631c4c918c6d3b575106

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page