Utilisez le module asyncio pour les requêtes asynchrones en Python. Écrivons du code qui atteint l'API de manière asynchrone à l'aide du package de requêtes.
API
J'aurais pu utiliser time.sleep ()
, mais cette fois je vais assumer un modèle pour obtenir l'API plutôt que de m'entraîner.
J'ai utilisé JSON Placeholder
comme serveur fictif.
Écrivez le code qui demande aux API (6 ci-dessous) d'obtenir la liste de manière synchrone et asynchrone, et renvoie le résultat de chaque résultat sous la forme d'une liste.
https://jsonplaceholder.typicode.com/posts https://jsonplaceholder.typicode.com/comments https://jsonplaceholder.typicode.com/albums https://jsonplaceholder.typicode.com/photos https://jsonplaceholder.typicode.com/todos https://jsonplaceholder.typicode.com/users
Commençons par faire une requête dans le processus synchrone. Si vous l'écrivez selon le code Python habituel, ce sera comme suit.
import time
import requests
BASE_URL = "https://jsonplaceholder.typicode.com/"
def calc_time(fn):
"""Décorateur qui mesure le temps d'exécution d'une fonction"""
def wrapper(*args, **kwargs):
start = time.time()
fn(*args, **kwargs)
end = time.time()
print(f"[{fn.__name__}] elapsed time: {end - start}")
return
return wrapper
def get_sync(path: str) -> dict:
print(f"/{path} request")
res = requests.get(BASE_URL + path)
print(f"/{path} request done")
return res.json()
@calc_time
def main_sync():
data_ls = []
paths = [
"posts",
"comments",
"albums",
"photos",
"todos",
"users",
]
for path in paths:
data_ls.append(get_sync(path))
return data_ls
if __name__ == "__main__":
main_sync()
Lors de l'exécution, vous obtiendrez une sortie similaire à ce qui suit:
Requête 1-> Requête 1 terminée Demande 2-> Demande 2 terminée Requête 3-> Requête 3 terminée ...
Vous pouvez voir qu'il est en cours d'exécution.
/posts request
/posts request done
/comments request
/comments request done
/albums request
/albums request done
/photos request
/photos request done
/todos request
/todos request done
/users request
/users request done
[main_sync] elapsed time: 1.157785415649414
Ensuite, faites une requête asynchrone.
Les tâches exécutées de manière asynchrone sont exécutées dans une boucle d'événements. Pour obtenir la boucle d'événements, utilisez ʻasyncio.get_event_loop () `.
loop.run_until_complete
, comme son nom l'indique, est une méthode qui exécute une boucle d'événements jusqu'à ce que chaque tâche ait été exécutée.
La valeur de retour de cette méthode est une liste contenant la valeur de retour de chaque tâche d'exécution asynchrone.
L'ordre d'exécution n'est pas garanti, mais les valeurs de retour sont renvoyées dans l'ordre passé à l'argument, il peut donc être utilisé même lorsque l'ordre est important.
Get_async
déclaré avec ʻasync def est appelé une fonction collout. L'expression ʻawait
à l'intérieur d'une fonction coroutine interrompt l'exécution de la fonction coroutine jusqu'à ce que la valeur de retour soit renvoyée.
import asyncio
#Fonction corroutine
async def get_async(path: str) -> dict:
print(f"/{path} async request")
url = BASE_URL + path
loop = asyncio.get_event_loop()
#Exécuter en boucle d'événements
res = await loop.run_in_executor(None, requests.get, url)
print(f"/{path} async request done")
return res.json()
@calc_time
def main_async():
#Obtenir une boucle d'événement
loop = asyncio.get_event_loop()
#Tâche d'exécution asynchrone dans un objet Future
tasks = asyncio.gather(
get_async("posts"),
get_async("comments"),
get_async("albums"),
get_async("photos"),
get_async("todos"),
get_async("users"),
)
#Exécution asynchrone, jusqu'à ce que chacune soit terminée
results = loop.run_until_complete(tasks)
return results
if __name__ == "__main__":
main_async()
La sortie ressemble à ceci:
Demande 1 Demande 2 Demande 3 ... Demande 1 terminée Demande 2 terminée Demande 3 terminée ...
Vous pouvez voir qu'il est traité. Vous pouvez également constater que le temps d'exécution a été considérablement réduit.
/posts async request
/comments async request
/albums async request
/photos async request
/todos async request
/users async request
/users async request done
/todos async request done
/posts async request done
/albums async request done
/comments async request done
/photos async request done
[main_async] elapsed time: 0.17921733856201172
Recommended Posts