python-dependency-injector
python-dependency-injector copied to clipboard
create task for a coroutine that depends on an async factory
I have a dependency injection container that holds a coroutine. This coroutine takes some object as a parameter. Also that object is managed by the container - it is created via a factory method but the method itself is asynchronous. The code snippet below depicts clearly how it is done:
import asyncio
from dependency_injector import containers, providers
async def create_a():
await asyncio.sleep(1)
return 1
async def run(a: int):
await asyncio.sleep(1)
return a
class Container(containers.DeclarativeContainer):
a = providers.Factory(
create_a
)
run_a = providers.Coroutine(
run,
a=a,
)
async def main():
container = Container()
asyncio.create_task(container.run_a())
if __name__ == "__main__":
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(main())
If create_a was a normal synchronous function, then the code above would run as expected. However, with an async create_a an exception is raised while trying to create a task for container.run():
Traceback (most recent call last):
File "C:\Users\-\Desktop\coro\main.py", line 35, in <module>
loop.run_until_complete(main())
File "C:\Python310\lib\asyncio\base_events.py", line 641, in run_until_complete
return future.result()
File "C:\Users\-\Desktop\coro\main.py", line 29, in main
asyncio.create_task(container.run())
File "C:\Python310\lib\asyncio\tasks.py", line 337, in create_task
task = loop.create_task(coro)
File "C:\Python310\lib\asyncio\base_events.py", line 433, in create_task
task = tasks.Task(coro, loop=self, name=name)
TypeError: a coroutine was expected, got <Future pending>
At first glance, I thought that I need to await container.run() to acquire the actual coroutine object and then pass it to asyncio.create_task() but this way await just runs the run coroutine and blocks execution which is not what I want. What am I doing wrong?