Search code examples
pythonaiohttpcontextmanager

Can I use a context manager for a whole module?


I'd like to have a context manager that is opened (entered?) for the lifetime of the application. It should be opened when a module loads and be closed when the module is destroyed.

Wrapping the whole module code won't work, since then the conetext manager is closed when the module is finished loading and is no longer open when the methods are actually called.

import aiohttp

with context as c:

  def f1():
    c.do_something('one')

  def f2():
    c.do_something('two')

Specifically, I want to create a aiohttp.ClientSession for the module which is reused for multiple different requests and cleanly closed when the application stops. Is it even a good idea to use a context manager for this or is there a better way?


Solution

  • A context manager is not suitable for managing the lifecycle of an object across modules.

    Instead, you can register the close method of your aiohttp.ClientSession instance with the atexit module so that it would be called when the app stops for any reason. Since in this case the close method is a coroutine, register the asyncio.run function with the close coroutine as an argument:

    import aiohttp
    import asyncio
    import atexit
    
    c = aiohttp.ClientSession(some_url)
    atexit.register(asyncio.run, c.close())