Skip to main content

Dependency injection for python

Project description

drawing By: CenturyBoys

Witch-doctor

A simple dependency injection for python

Register

Witch Doctor provides a method to register interfaces, implementation, injection type, instance args and container name.

  • The interface and implementation inheritance will be checked and will raise a TypeError if was some issue.
  • The injection type will be checked and will raise a TypeError if was some issue. There are two types the singleton and factory types, the singleton will return the same instance for all injection and the factory will return a new instance for each injection.
  • If no values was giving will not pass the args to the class constructor.
  • The container name will segregate the injections by scopes.
class WitchDoctor:
    @classmethod
    def register(  # pylint: disable=R0913
        cls,
        interface: Type[ABC],
        class_ref: Any,
        injection_type: InjectionType,
        args: List[any] = None,
        container: str = DEFAULT,
    ):
        """
        WitchDoctor.register will check inherit of the interface and class_ref.
        Will raise a TypeError on validation error\n
        :param interface: Interface that inherits from ABC
        :param class_ref: A implementation of the interface
        :param injection_type: The injection type that must be used for this register. Allowed Factory or Singleton
        :param args: List of args tha will be used to instantiate the class object
        :param container: Container name where the reference will be saved.
        """
        pass

Container

You can register your injections using containers. The method contianer will provide a container register with the same signature as teh register without the container param. To use the created container you need to load it using load_container. The base work load will set all registers in the DEFAULT group

from abc import ABC, abstractmethod

from witch_doctor import WitchDoctor, InjectionType

class IStubFromABCClass(ABC):
    @abstractmethod
    def sum(self, a: int, b: int):
        pass
    
class StubFromABCClass(IStubFromABCClass):
    def sum(self, a: int, b: int):
        return a + b

container = WitchDoctor.container("prod")
WitchDoctor.register(IStubFromABCClass, StubFromABCClass, InjectionType.SINGLETON)   
WitchDoctor.load_container("prod")

Injection

Witch Doctor can be used as decorator. The function signature will ber check and if some values was not provide Witch Doctor will search on the registered interfaces to inject the dependencies.

class WitchDoctor:
    @classmethod
    def injection(cls, function: Callable):
        """
        WitchDoctor.injection is a function decorator that will match the
        function params signature and inject the  dependencies.
        Will raise AttributeError is some args was pass throw\n

        :type function: Callable
        """
        pass

Usage example

from abc import ABC, abstractmethod

from witch_doctor import WitchDoctor, InjectionType


# Abstract class
class IStubFromABCClass(ABC):
    @abstractmethod
    def sum(self, a: int, b: int):
        pass

    
# Implementation
class StubFromABCClass(IStubFromABCClass):
    def __init__(self, a: int):
        self.a = a

    def sum(self, a: int, b: int):
        return a + b + self.a

# Usage
@WitchDoctor.injection
def func_t(a: int, b: int, c: IStubFromABCClass):
    return c.sum(a, b)

# Containers
container = WitchDoctor.container()
container(IStubFromABCClass, StubFromABCClass, InjectionType.FACTORY, args=[10])

container = WitchDoctor.container("prod")
container(IStubFromABCClass, StubFromABCClass, InjectionType.SINGLETON, args=[20])

# Loading and using
WitchDoctor.load_container()

result_a1 = func_t(a=1, b=2)
result_a2 = func_t(a=2, b=2)

assert result_a1 == 13
assert result_a2 == 14

WitchDoctor.load_container("prod")

result_a1 = func_t(a=1, b=2)
result_a2 = func_t(a=2, b=2)

assert result_a1 == 23
assert result_a2 == 24

Resolve

Witch Doctor can be used by the method resolve. The class signature will ber check and search on the registered interfaces to inject the dependencies.

class WitchDoctor:
    @classmethod
    def resolve(cls, interface: T) -> Type[T]:
        """
        WitchDoctor.resolve will return an instance of the registered class_ref interface.
        Will raise a TypeError if interface is not registered\n
        :param interface: A implementation of the interface
        """
        pass

Usage example

from abc import ABC, abstractmethod

from witch_doctor import WitchDoctor, InjectionType


# Abstract class
class IStubFromABCClass(ABC):
    @abstractmethod
    def sum(self, a: int, b: int):
        pass

    
# Implementation
class StubFromABCClass(IStubFromABCClass):
    def __init__(self, a: int):
        self.a = a

    def sum(self, a: int, b: int):
        return a + b + self.a

# Usage
@WitchDoctor.injection
def func_t(a: int, b: int, c: IStubFromABCClass):
    return c.sum(a, b)

# Containers
container = WitchDoctor.container()
container(IStubFromABCClass, StubFromABCClass, InjectionType.FACTORY, args=[10])

# Loading and using
WitchDoctor.load_container()

result_a1 = WitchDoctor.resolve(IStubFromABCClass)
result_a2 = WitchDoctor.resolve(IStubFromABCClass)

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

witch_doctor-1.2.0.tar.gz (8.3 kB view details)

Uploaded Source

Built Distribution

witch_doctor-1.2.0-py3-none-any.whl (8.5 kB view details)

Uploaded Python 3

File details

Details for the file witch_doctor-1.2.0.tar.gz.

File metadata

  • Download URL: witch_doctor-1.2.0.tar.gz
  • Upload date:
  • Size: 8.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.3.2 CPython/3.11.2 Linux/6.1.0-17-amd64

File hashes

Hashes for witch_doctor-1.2.0.tar.gz
Algorithm Hash digest
SHA256 552302cdacc60b9321fd70c2e5af33956c1ea8f85ae2c970e4f204b910487b24
MD5 8407d9c4a5807ebe6f72e6502fcf930b
BLAKE2b-256 8f2c1a93617e314a4a62b0d3fe5c3a32adfa963f39b5d7204b3a44c2e60ae228

See more details on using hashes here.

File details

Details for the file witch_doctor-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: witch_doctor-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 8.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.3.2 CPython/3.11.2 Linux/6.1.0-17-amd64

File hashes

Hashes for witch_doctor-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8f2af5882fc25b7c15aa290da689686cc7b7839de71e7f5718e1b6b9f389800f
MD5 e13e375b644140b07647e4235746683a
BLAKE2b-256 6ed063ca1b316d4e8aecf18fad72ab539c0d09a652118aab0a810b11a5b9ba5d

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