[Python] Requête asynchrone avec async / await

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.

environnement

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.

JSONPlaceholder

É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

Demande de synchronisation

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

Requête asynchrone

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

[Python] Requête asynchrone avec async / await
python async / attend curio
Convertir l'API asynchrone de style callback en async / await en Python
Traitement asynchrone de Python ~ Comprenez parfaitement async et attendez ~
Python: comment utiliser async avec
Masquer les websockets async / attendent dans Python3
Async / await avec Kivy et tkinter
FizzBuzz en Python3
Grattage avec Python
Statistiques avec python
Grattage avec Python
Python avec Go
Twilio avec Python
Intégrer avec Python
Jouer Python async
Jouez avec 2016-Python
AES256 avec python
Testé avec Python
python commence par ()
avec syntaxe (Python)
Bingo avec python
Zundokokiyoshi avec python
Excel avec Python
Micro-ordinateur avec Python
Cast avec python
Communication série avec Python
Zip, décompressez avec python
Django 1.11 a démarré avec Python3.6
Jugement des nombres premiers avec Python
Communication de socket avec Python
Analyse de données avec python 2
Essayez de gratter avec Python.
Programmation asynchrone avec libev # 2
Apprendre Python avec ChemTHEATER 03
Recherche séquentielle avec Python
"Orienté objet" appris avec python
Exécutez Python avec VBA
Manipuler yaml avec python
Résolvez AtCoder 167 avec python
Communication série avec python
[Python] Utiliser JSON avec Python
Apprendre Python avec ChemTHEATER 05-1
Requête HTTP en Python
Exécutez prepDE.py avec python3
1.1 Premiers pas avec Python
Collecter des tweets avec Python
Binarisation avec OpenCV / Python
Méthode Kernel avec Python
Non bloquant avec Python + uWSGI
Publier des tweets avec python
Conduisez WebDriver avec python
Utiliser mecab avec Python 3
[Python] Redirection avec CGIHTTPServer
Analyse vocale par python
Pensez à yaml avec python
Utiliser Kinesis avec Python
Premiers pas avec Python
Utiliser DynamoDB avec Python
Getter Zundko avec python
Jugement des nombres premiers avec python
Exécutez Blender avec python