python-dependency-injector icon indicating copy to clipboard operation
python-dependency-injector copied to clipboard

Using `Provider.disable_async_mode()`

Open misuzu opened this issue 1 year ago • 2 comments
trafficstars

I need to be able to get a service in a sync function. I've tried

import asyncio

from dependency_injector import containers, providers


async def init_async_resource():
    await asyncio.sleep(0.1)
    yield "Initialized"


class Service:
    def __init__(self, resource):
        self.resource = resource


class Container(containers.DeclarativeContainer):

    resource = providers.Resource(init_async_resource)

    service = providers.Factory(
        Service,
        resource=resource,
    )


async def main(container: Container):
    container = Container()
    await container.init_resources()

    container.service.disable_async_mode()
    service = container.service()
    assert isinstance(service, Service)

    await container.shutdown_resources()


if __name__ == "__main__":
    container = Container()

    asyncio.run(main(container))

While this works, I don't want to do this everywhere:

    container.service.disable_async_mode()
    service = container.service()

I've tried to call disable_async_mode in init_resources, but it doesn't work:

import asyncio

from dependency_injector import containers, providers


async def init_async_resource():
    await asyncio.sleep(0.1)
    yield "Initialized"


class Service:
    def __init__(self, resource):
        self.resource = resource


class Container(containers.DeclarativeContainer):

    resource = providers.Resource(init_async_resource)

    service = providers.Factory(
        Service,
        resource=resource,
    )

    async def init_resources(self, *args, **kwargs):
        await super().init_resources(*args, **kwargs)
        self.service.disable_async_mode()


async def main(container: Container):
    container = Container()
    await container.init_resources()

    service = container.service()
    assert isinstance(service, Service)

    await container.shutdown_resources()


if __name__ == "__main__":
    container = Container()

    asyncio.run(main(container))
$ python test.py
Traceback (most recent call last):
  File "test.py", line 43, in <module>
    asyncio.run(main(container))
  File "/usr/local/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/local/lib/python3.9/asyncio/base_events.py", line 647, in run_until_complete
    return future.result()
  File "test.py", line 35, in main
    assert isinstance(service, Service)
AssertionError

So where do I need to call disable_async_mode for it to work as I need?

misuzu avatar Jul 01 '24 09:07 misuzu