J'essaie d'apprendre à utiliser asyncio dans Python pour optimiser les scripts. Mon exemple renvoie un coroutine was never awaited
avertissement, pouvez-vous aider à comprendre et à trouver comment le résoudre?
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")
La première partie classique du code fonctionne correctement, mais la seconde moitié ne produit que:
synchronicite.py:43: RuntimeWarning: coroutine 'faire_toutes_les_requetes_sans_bloquer' was never awaited
N'utilisez pas l'appel loop.run_until_complete
Dans la fonction async
. Le but de cette méthode est d'exécuter une fonction asynchrone dans le contexte de synchronisation. Quoi qu'il en soit, voici comment modifier le code:
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 !")
loop = asyncio.get_event_loop()
loop.run_until_complete(faire_toutes_les_requetes_sans_bloquer())
Notez que seul l'appel faire_toutes_les_requetes_sans_bloquer()
crée un futur qui doit être attendu via un explicite await
(pour cela vous devez être dans le contexte async
) ou passé à une boucle d'événement . Lorsqu'il est laissé seul Python s'en plaint. Dans votre code d'origine, vous ne faites rien de tout cela.