Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use async/await in Python 3.5?

#!/usr/bin/env python3 # -*- coding: utf-8 -*- import time  async def foo():   await time.sleep(1)  foo() 

I couldn't make this dead simple example to run:

RuntimeWarning: coroutine 'foo' was never awaited foo() 
like image 529
smilingpoplar Avatar asked Sep 27 '15 14:09

smilingpoplar


People also ask

Is there async await in Python?

Python's asyncio package (introduced in Python 3.4) and its two keywords, async and await , serve different purposes but come together to help you declare, build, execute, and manage asynchronous code.

How the heck does async await work in Python?

An async function uses the await keyword to denote a coroutine. When using the await keyword, coroutines release the flow of control back to the event loop. To run a coroutine, we need to schedule it on the event loop. After scheduling, coroutines are wrapped in Tasks as a Future object.

Can Python run async?

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.


2 Answers

Running coroutines requires an event loop. Use the asyncio() library to create one:

import asyncio  # Python 3.7+ asyncio.run(foo()) 

or

# Python 3.6 and older loop = asyncio.get_event_loop() loop.run_until_complete(foo()) 

Also see the Tasks and Coroutines chapter of the asyncio documentation. If you already have a loop running, you'd want to run additional coroutines concurrently by creating a task (asyncio.create_task(...) in Python 3.7+, asyncio.ensure_future(...) in older versions).

Note however that time.sleep() is not an awaitable object. It returns None so you get an exception after 1 second:

>>> asyncio.run(foo()) Traceback (most recent call last):   File "<stdin>", line 1, in <module>   File "/.../lib/python3.7/asyncio/runners.py", line 43, in run     return loop.run_until_complete(main)   File "/.../lib/python3.7/asyncio/base_events.py", line 573, in run_until_complete     return future.result()   File "<stdin>", line 2, in foo TypeError: object NoneType can't be used in 'await' expression 

In this case you should use the asyncio.sleep() coroutine instead:

async def foo():     await asyncio.sleep(1) 

which is cooperates with the loop to enable other tasks to run. For blocking code from third-party libraries that do not have asyncio equivalents, you could run that code in an executor pool. See Running Blocking Code in the asyncio development guide.

like image 159
Martijn Pieters Avatar answered Oct 01 '22 04:10

Martijn Pieters


If you already have a loop running (with some other tasks), you can add new tasks with:

asyncio.ensure_future(foo()) 

otherwise you might get

The event loop is already running 

error.

like image 26
lenooh Avatar answered Oct 01 '22 04:10

lenooh