Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python aiohttp into existing event loop

I'm testing aiohttp and asyncio. I want the same event loop to have a socket, http server, http client.

I'm using this sample code:

@routes.get('/')
async def hello(request):
    return web.Response(text="Hello, world")

app = web.Application()
app.add_routes(routes)
web.run_app(app)

The problem is run_app is blocking. I want to add the http server into an existing event loop, that I create using:

asyncio.get_event_loop()
like image 899
user3599803 Avatar asked Nov 25 '18 08:11

user3599803


People also ask

How do I stop Asyncio from looping events?

Run an asyncio Event Loop run_until_complete(<some Future object>) – this function runs a given Future object, usually a coroutine defined by the async / await pattern, until it's complete. run_forever() – this function runs the loop forever. stop() – the stop function stops a running loop.

Can you have multiple event loops python?

You can create multiple threads and run different event loops in each of them.

How does the Asyncio event loop work?

Deep inside asyncio, we have an event loop. An event loop of tasks. The event loop's job is to call tasks every time they are ready and coordinate all that effort into one single working machine. The IO part of the event loop is built upon a single crucial function called select .

Does Run_until_complete block?

run_until_complete is used to run a future until it's finished. It will block the execution of code following it. It does, however, cause the event loop to run.


1 Answers

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())
like image 126
user4815162342 Avatar answered Sep 19 '22 06:09

user4815162342