Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Await a method and assign a variable to the returned value with asyncio?

I'm using asyncio with requests to try to make a core module asynchronous program. I've ran into a difficulty when trying to do something like this

import asyncio
import requests
async def main():
    await r = requests.get(URL)

What I thought this would do is wait for the get request to finish, then take the return value and put it in r, but this error happens

  File "prog.py", line 20
    await r = requests.get(URL)
    ^
SyntaxError: can't assign to await expression

r = await requests.get(URL) doesn't seem to work either, giving

prog.py:31: RuntimeWarning: coroutine 'coroutine' was never awaited
  coroutine(args)

Does anyone know how to do this?

like image 639
hedwig Avatar asked Sep 09 '18 17:09

hedwig


People also ask

What does await do in Asyncio?

The keyword await passes function control back to the event loop. (It suspends the execution of the surrounding coroutine.) If Python encounters an await f() expression in the scope of g() , this is how await tells the event loop, “Suspend execution of g() until whatever I'm waiting on—the result of f() —is returned.

Can you await a variable?

The await keyword is used to get a value from a function where you would normally use . then() . Instead of calling . then() after the asynchronous function, you would simply assign a variable to the result using await .

How do I use async await 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.

What does an async function return Python?

Async functions always return an Awaitable, even with a plain return . You only get the actual result by calling await .


1 Answers

How to use await?

await can be used only to await coroutine - special object returned by calling function defined with async def:

import asyncio


async def test():
    return True


async def main():

    # test() returns coroutine:
    coro = test()
    print(coro)  # <coroutine object test at ...>


    # we can await for coroutine to get result:
    res = await coro    
    print(res)  # True



if __name__ ==  '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

Read also this answer about using asyncio.

Why await requests.get(URL) doesn't work?

Because requests.get is not a coroutine (it's not defined with async def), it's regular function by nature.

If you want to make request asynchronously you should either use special async module like aiohttp for this or wrap requests into coroutine using threads. See code snippets here for both examples.

like image 118
Mikhail Gerasimov Avatar answered Dec 26 '22 19:12

Mikhail Gerasimov