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()