aiohttp server: run_app coroutine?

Created on 4 Dec 2019  路  3Comments  路  Source: aio-libs/aiohttp

Long story short

I think I'd like to do:

async with ClientSession() as session:
    await web.run_app(app)

to reuse an aiohttp client session during the whole life of a server. Or any other asyncornous context manager like a connection to a database and so on.

Expected behaviour

To easily run an aiohttp server inside an asyncronous context manager.

Actual behaviour

I'm actually doing:

    async def on_startup_wrapper(app):
        app["aiohttp_client_session"] = await ClientSession().__aenter__()

    async def on_cleanup_wrapper(app):
        await app["aiohttp_client_session"].__aexit__(None, None, None)

    app.on_startup.append(on_startup_wrapper)
    app.on_cleanup.append(on_cleanup_wrapper)

but I'm not proud of it.

Obviously it can't be done with the actual run_app, and probably easily done with the _run_app, but, _.

Maybe the AppRunner could eat some code from _run_app allowing one to completly bypass _run_app with something like:

runner = AppRunner(app, ...)
await runner.setup(host, path, sock, port)  # Doing most of _run_app current code here
async with Something() as something:
    app["something"] = something
    await runner.run_forever()  # The while True of the current _run_app

Does it looks like a good idea? Should I try a PR? Or am I getting something wrong?

pr-merged question

Most helpful comment

Hey @JulienPalard, are you aware of the cleanup context? https://docs.aiohttp.org/en/stable/web_advanced.html#cleanup-context

Would this work for you?

async def init_session_ctx(app):
    async with ClientSession() as session:
        app["aiohttp_client_session"] = session
        try:
            yield
        finally:
            del app["aiohttp_client_session"]

app.cleanup_ctx.append(init_session_ctx)

All 3 comments

Hey @JulienPalard, are you aware of the cleanup context? https://docs.aiohttp.org/en/stable/web_advanced.html#cleanup-context

Would this work for you?

async def init_session_ctx(app):
    async with ClientSession() as session:
        app["aiohttp_client_session"] = session
        try:
            yield
        finally:
            del app["aiohttp_client_session"]

app.cleanup_ctx.append(init_session_ctx)

I missed cleanup_ctx while reading the doc, thanks!

In my current case I'm having two context managers, using cleanup_ctx instead of on_startup and on_cleanup gives me 13 new lines for 18 lines removed, and I'm no longer calling __aenter__ and __aexit__ myself, so it's better, yes.

It probably miss a link somewhere, to this, to make it easier to find from maybe on_startup?

Do you imply that the discoverability can be improved? You're welcome to try improving the doc.

Was this page helpful?
0 / 5 - 0 ratings