Skip to content
Advertisement

Trouble with injecting Callable

I’m using python-dependency-injector.

I tried this code and it worked perfectly: https://python-dependency-injector.ets-labs.org/providers/callable.html

that page also mentioned next:

Callable provider handles an injection of the dependencies the same way like a Factory provider.

So I went and wrote this code:

import passlib.hash

from dependency_injector import containers, providers
from dependency_injector.wiring import Provide, inject


class Container(containers.DeclarativeContainer):
    password_verifier = providers.Callable(passlib.hash.sha256_crypt.verify)


@inject
def bar(password_verifier=Provide[Container.password_verifier]):
    pass


if __name__ == "__main__":
    container = Container()
    container.wire(modules=[__name__])

    bar()

And it — as you might expect — didn’t work. I received this error:

Traceback (most recent call last):
  File "/home/common/learning_2022/code/python/blog_engine/test.py", line 20, in <module>
    bar()
  File "src/dependency_injector/_cwiring.pyx", line 26, in dependency_injector._cwiring._get_sync_patched._patched
  File "src/dependency_injector/providers.pyx", line 225, in dependency_injector.providers.Provider.__call__
  File "src/dependency_injector/providers.pyx", line 1339, in dependency_injector.providers.Callable._provide
  File "src/dependency_injector/providers.pxd", line 635, in dependency_injector.providers.__callable_call
  File "src/dependency_injector/providers.pxd", line 608, in dependency_injector.providers.__call
TypeError: GenericHandler.verify() missing 2 required positional arguments: 'secret' and 'hash'

Advertisement

Answer

I ran into this problem too and after much search I found the answer.

You can inject the callable by using the provider attribute:

import passlib.hash

from dependency_injector import containers, providers
from dependency_injector.wiring import Provide, inject


class Container(containers.DeclarativeContainer):
    # Use the 'provider' attribute on the provider in the container
    password_verifier = providers.Callable(passlib.hash.sha256_crypt.verify).provider


@inject
def bar(password_verifier=Provide[Container.password_verifier]):
    password_verifier(...) 


if __name__ == "__main__":
    container = Container()
    container.wire(modules=[__name__])

    bar()
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement