Making Python's Asyncio Synchronous

Python 3.4 introduced asyncio — asynchronous I/O and coroutines which are very powerful tools for writing concurrent code in a sequential fashion. As these tools become more powerful, we are seeing more libraries and frameworks that depend on asyncio. More asyncio is a good thing; but, unfortunately many older frameworks such as Django and Flask don’t play nicely with coroutines.

Here’s a snippet that will run your coroutine synchronously:

# eventloop.py

import asyncio

def run(coroutine):
    event_loop = None
    try:
        event_loop = asyncio.get_event_loop()
    except RuntimeError:
        event_loop = asyncio.new_event_loop()
        asyncio.set_event_loop(event_loop)
    return event_loop.run_until_complete(coro)

Now in a function —- defined by a framework that you are using and not marked as async – you can do this to run the coroutine sync:

from . import eventloop
# If you can't `await coroutine()`, then you can: 
eventloop.run(coroutine())

This may not always be the best idea for long running tasks, but it can be useful in a pinch.

Comments