python aiohttp into existing event loop

The problem is run_app is blocking. I want to add the http server into an existing event loop

run_app is just a convenience API. To hook into an existing event loop, you can directly instantiate the AppRunner:

loop = asyncio.get_event_loop()
# add stuff to the loop
...

# set up aiohttp - like run_app, but non-blocking
runner = aiohttp.web.AppRunner(app)
loop.run_until_complete(runner.setup())
site = aiohttp.web.TCPSite(runner)    
loop.run_until_complete(site.start())

# add more stuff to the loop
...

loop.run_forever()

In asyncio 3.8 and later you can use asyncio.run():

async def main():
    # add stuff to the loop, e.g. using asyncio.create_task()
    ...

    runner = aiohttp.web.AppRunner(app)
    await runner.setup()
    site = aiohttp.web.TCPSite(runner)    
    await site.start()

    # add more stuff to the loop, if needed
    ...

    # wait forever
    await asyncio.Event().wait()

asyncio.run(main())

For the future traveler from Google, here is a simpler way.

async def main():
    await aio.gather(
        web._run_app(app, port=args.port),
        SomeotherTask(),
        AndAnotherTask()
    )

aio.run(main())

Explanation: web.runapp is a thin wrapper over internal function web._runapp. The function uses the old style way of getting the eventloop and then calling loop.run_until_complete.

We replace it with aio.gather alongside other tasks that we want to run concurrently and use the aio.run to schedule them

Source