Sign Up

Have an account? Sign In Now

Sign In

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have a permission to ask a question, You must login to ask question.

Forgot Password?

Need An Account, Sign Up Here
Sign InSign Up

ErrorCorner

ErrorCorner Logo ErrorCorner Logo

ErrorCorner Navigation

  • Home
  • Contact Us
  • About Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Contact Us
  • About Us
Home/ Questions/Q 441
Next
Answered
Kenil Vasani
Kenil Vasani

Kenil Vasani

  • 646 Questions
  • 567 Answers
  • 77 Best Answers
  • 26 Points
View Profile
  • 3
Kenil Vasani
Asked: December 11, 20202020-12-11T20:37:02+00:00 2020-12-11T20:37:02+00:00In: Python

Learning asyncio: “coroutine was never awaited” warning error

  • 3

I am trying to learn to use asyncio in Python to optimize scripts.
My example returns a coroutine was never awaited warning, can you help to understand and find how to solve it?

import time 
import datetime
import random
import asyncio

import aiohttp
import requests

def requete_bloquante(num):
    print(f'Get {num}')
    uid = requests.get("https://httpbin.org/uuid").json()['uuid']
    print(f"Res {num}: {uid}")

def faire_toutes_les_requetes():
    for x in range(10):
        requete_bloquante(x)

print("Bloquant : ")
start = datetime.datetime.now()
faire_toutes_les_requetes()
exec_time = (datetime.datetime.now() - start).seconds
print(f"Pour faire 10 requêtes, ça prend {exec_time}s\n")

async def requete_sans_bloquer(num, session):
    print(f'Get {num}')
    async with session.get("https://httpbin.org/uuid") as response:
        uid = (await response.json()['uuid'])
    print(f"Res {num}: {uid}")

async def faire_toutes_les_requetes_sans_bloquer():
    loop = asyncio.get_event_loop()
    with aiohttp.ClientSession() as session:
        futures = [requete_sans_bloquer(x, session) for x in range(10)]
        loop.run_until_complete(asyncio.gather(*futures))
    loop.close()
    print("Fin de la boucle !")

print("Non bloquant : ")
start = datetime.datetime.now()
faire_toutes_les_requetes_sans_bloquer()
exec_time = (datetime.datetime.now() - start).seconds
print(f"Pour faire 10 requêtes, ça prend {exec_time}s\n")

The first classic part of the code runs correctly, but the second half only produces:

synchronicite.py:43: RuntimeWarning: coroutine 'faire_toutes_les_requetes_sans_bloquer' was never awaited
aiohttppythonpython-asyncio
  • 1 1 Answer
  • 11 Views
  • 0 Followers
  • 0
Answer
Share
  • Facebook

    1 Answer

    • Voted
    1. Rohit Patel

      Rohit Patel

      • 0 Questions
      • 98 Answers
      • 0 Best Answers
      • 0 Points
      View Profile
      Best Answer
      Rohit Patel
      2020-12-11T20:35:26+00:00Added an answer on December 11, 2020 at 8:35 pm

      You made faire_toutes_les_requetes_sans_bloquer an awaitable function, a coroutine, by usingasync def.

      When you call an awaitable function, you create a new coroutine object. The code inside the function won’t run until you then await on the function or run it as a task:

      >>> async def foo():
      ...     print("Running the foo coroutine")
      ...
      >>> foo()
      <coroutine object foo at 0x10b186348>
      >>> import asyncio
      >>> asyncio.run(foo())
      Running the foo coroutine
      

      You want to keep that function synchronous, because you don’t start the loop until inside that function:

      def faire_toutes_les_requetes_sans_bloquer():
          loop = asyncio.get_event_loop()
          # ...
          loop.close()
          print("Fin de la boucle !")
      

      However, you are also trying to use a aiophttp.ClientSession() object, and that’s an asynchronous context manager, you are expected to use it with async with, not just with, and so has to be run in aside an awaitable task. If you use with instead of async with a TypeError("Use async with instead") exception will be raised.

      That all means you need to move the loop.run_until_complete() call out of your faire_toutes_les_requetes_sans_bloquer() function, so you can keep that as the main task to be run; you can call and await on asycio.gather() directly then:

      async def faire_toutes_les_requetes_sans_bloquer():
          async with aiohttp.ClientSession() as session:
              futures = [requete_sans_bloquer(x, session) for x in range(10)]
              await asyncio.gather(*futures)
          print("Fin de la boucle !")
      
      print("Non bloquant : ")
      start = datetime.datetime.now()
      loop.run(faire_toutes_les_requetes_sans_bloquer())
      exec_time = (datetime.datetime.now() - start).seconds
      print(f"Pour faire 10 requêtes, ça prend {exec_time}s\n")
      

      I used the new asyncio.run() function (Python 3.7 and up) to run the single main task. This creates a dedicated loop for that top-level coroutine and runs it until complete.

      Next, you need to move the closing ) parenthesis on the await resp.json() expression:

      uid = (await response.json())['uuid']
      

      You want to access the 'uuid' key on the result of the await, not the coroutine that response.json() produces.

      With those changes your code works, but the asyncio version finishes in sub-second time; you may want to print microseconds:

      exec_time = (datetime.datetime.now() - start).total_seconds()
      print(f"Pour faire 10 requêtes, ça prend {exec_time:.3f}s\n")
      

      On my machine, the synchronous requests code in about 4-5 seconds, and the asycio code completes in under .5 seconds.

      • 1
      • Share
        Share
        • Share on Facebook
        • Share on Twitter
        • Share on LinkedIn
        • Share on WhatsApp

    You must login to add an answer.

    Forgot Password?

    Sidebar

    Ask A Question
    • Popular
    • Kenil Vasani

      SyntaxError: invalid syntax to repo init in the AOSP code

      • 5 Answers
    • Kenil Vasani

      xlrd.biffh.XLRDError: Excel xlsx file; not supported

      • 3 Answers
    • Kenil Vasani

      Homebrew fails on MacOS Big Sur

      • 3 Answers
    • Kenil Vasani

      runtimeError: package fails to pass a sanity check for numpy ...

      • 3 Answers
    • Kenil Vasani

      Python, Error while installing matplotlib

      • 2 Answers

    Explore

    • Most Answered
    • Most Visited
    • Most Voted
    • Random

    © 2020-2021 ErrorCorner. All Rights Reserved
    by ErrorCorner.com