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()
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.
You can create multiple threads and run different event loops in each of them.
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 .
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.
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())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With