I am using asyncio
for an application in a very basic way. Checking most tutorials around the internet (and even the official docs), I see that they use the get_event_loop()
and loop.run_until_complete()
:
import asyncio
async def say(what, when):
await asyncio.sleep(when)
print(what)
loop = asyncio.get_event_loop()
loop.run_until_complete(say('hello world', 1))
loop.close()
But in the Python 3.7 docs, we can read:
Application developers should typically use the high-level asyncio functions, such as asyncio.run(), and should rarely need to reference the loop object or call its methods. This section is intended mostly for authors of lower-level code, libraries, and frameworks, who need finer control over the event loop behavior.
I found it much cleaner and easier to use, but it only works for Python 3.7+. So here I would have to make a choice, whether to use Python 3.7+ and run()
or make it compatible with Python 3.6 and use the event loop. How would you manage this? Is there a simple way to make it backwards compatible with Python 3.6? Should I check Python version first and use either one way or another based on that, until Python 3.7 becomes a common version?
asyncio. run(main()) asyncio is a library to write concurrent code using the async/await syntax. asyncio is used as a foundation for multiple Python asynchronous frameworks that provide high-performance network and web-servers, database connection libraries, distributed task queues, etc.
It should be used as a main entry point for asyncio programs, and should ideally only be called once. New in version 3.7.
run_forever() to run multiple co-routines concurrently. run_until_complete doesn't block anything. The difference between it and run_forever is that the loop pauses at the completion of the coroutine. The only time it will block is if your coroutine never awaits.
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.
Is there a simple way to make [code making use of
asyncio.run
] backwards compatible with Python 3.6?
You can implement a simple substitute for asyncio.run
and call it on older Python versions:
import asyncio, sys, types
def run(coro):
if sys.version_info >= (3, 7):
return asyncio.run(coro)
# Emulate asyncio.run() on older versions
# asyncio.run() requires a coroutine, so require it here as well
if not isinstance(coro, types.CoroutineType):
raise TypeError("run() requires a coroutine object")
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
return loop.run_until_complete(coro)
finally:
loop.close()
asyncio.set_event_loop(None)
The advantage of this approach over just using loop.run_until_complete()
is that you're executing your code under the semantics close to those of the new asyncio.run
, even on older Python versions. (For example, you will always run on a freshly created event loop.) Dropping support for pre-3.7 Python will be as easy as removing the run
shim and calling asyncio.run
directly.
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