[Python] Asynchrone Anfrage mit async / await

Verwenden Sie das Asyncio-Modul für asynchrone Anforderungen in Python. Schreiben wir Code, der die API asynchron mit dem Anforderungspaket trifft.

Umgebung

API

Ich hätte time.sleep () verwenden können, aber dieses Mal werde ich ein Muster annehmen, um die API zu erhalten, anstatt zu üben. Ich habe "JSON Placeholder" als Mock-Server verwendet.

JSONPlaceholder

Schreiben Sie den Code, der die APIs (6 unten) auffordert, die Liste synchron und asynchron abzurufen, und geben Sie das Ergebnis jedes Ergebnisses in einer Liste zurück.

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

Synchronisierungsanforderung

Lassen Sie uns zunächst eine Anfrage im synchronen Prozess stellen. Wenn Sie es gemäß dem üblichen Python-Code schreiben, sieht es wie folgt aus.

import time
import requests

BASE_URL = "https://jsonplaceholder.typicode.com/"


def calc_time(fn):
    """Dekorateur, der die Ausführungszeit einer Funktion misst"""
    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()

Beim Ausführen erhalten Sie eine Ausgabe ähnlich der folgenden:

Anfrage 1-> Anfrage 1 abgeschlossen Anfrage 2-> Anfrage 2 abgeschlossen Anfrage 3-> Anfrage 3 abgeschlossen ...

Sie können sehen, dass es ausgeführt wird.

/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

Asynchrone Anforderung

Stellen Sie dann eine asynchrone Anforderung.

Asynchron ausgeführte Aufgaben werden innerhalb einer Ereignisschleife ausgeführt. Verwenden Sie zum Abrufen der Ereignisschleife "asyncio.get_event_loop ()".

loop.run_until_complete ist, wie der Name schon sagt, eine Methode, die eine Ereignisschleife ausführt, bis jede Aufgabe ausgeführt wurde. Der Rückgabewert dieser Methode ist eine Liste, die den Rückgabewert jeder asynchronen Ausführungsaufgabe enthält. Die Ausführungsreihenfolge ist nicht garantiert, aber die Rückgabewerte werden in der an das Argument übergebenen Reihenfolge zurückgegeben, sodass sie auch dann verwendet werden können, wenn die Reihenfolge wichtig ist.

Das mit async def deklarierte get_async wird als Collout-Funktion bezeichnet. Der Ausdruck "Warten" innerhalb einer Coroutine-Funktion wird angehalten, bis der Rückgabewert der Ausführung der Coroutine-Funktion erreicht ist.

import asyncio

#Korroutinenfunktion
async def get_async(path: str) -> dict:
    print(f"/{path} async request")
    url = BASE_URL + path
    loop = asyncio.get_event_loop()
    #In Ereignisschleife ausführen
    res = await loop.run_in_executor(None, requests.get, url)
    print(f"/{path} async request done")
    return res.json()


@calc_time
def main_async():
    #Ereignisschleife abrufen
    loop = asyncio.get_event_loop()
    #Asynchrone Ausführungsaufgabe in einem zukünftigen Objekt
    tasks = asyncio.gather(
        get_async("posts"),
        get_async("comments"),
        get_async("albums"),
        get_async("photos"),
        get_async("todos"),
        get_async("users"),
    )
    #Asynchrone Ausführung, bis jede beendet ist
    results = loop.run_until_complete(tasks)
    return results


if __name__ == "__main__":
    main_async()

Die Ausgabe sieht folgendermaßen aus:

Anfrage 1 Anfrage 2 Anfrage 3 ... Anfrage 1 erledigt Anfrage 2 erledigt Anfrage 3 erledigt ...

Sie können sehen, dass es verarbeitet wird. Sie können auch sehen, dass die Ausführungszeit erheblich reduziert wurde.

/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] Asynchrone Anfrage mit async / await
Python async / warte auf Kuriosität
Konvertieren Sie die asynchrone API im Callback-Stil in async / await in Python
Asynchrone Verarbeitung von Python ~ Asynchron vollständig verstehen und warten ~
Python: So verwenden Sie Async mit
Verstecke Websockets asynchron / warte in Python3
Async / warte mit Kivy und tkinter
FizzBuzz in Python3
Scraping mit Python
Statistik mit Python
Scraping mit Python
Python mit Go
Twilio mit Python
In Python integrieren
Spielen Sie Python async
Spielen Sie mit 2016-Python
AES256 mit Python
Getestet mit Python
Python beginnt mit ()
mit Syntax (Python)
Bingo mit Python
Zundokokiyoshi mit Python
Excel mit Python
Mikrocomputer mit Python
Mit Python besetzen
Serielle Kommunikation mit Python
Zip, entpacken mit Python
Django 1.11 wurde mit Python3.6 gestartet
Primzahlbeurteilung mit Python
Socket-Kommunikation mit Python
Datenanalyse mit Python 2
Versuchen Sie es mit Python.
Asynchrone Programmierung mit libev # 2
Python lernen mit ChemTHEATER 03
Sequentielle Suche mit Python
"Objektorientiert" mit Python gelernt
Führen Sie Python mit VBA aus
Umgang mit Yaml mit Python
Löse AtCoder 167 mit Python
Serielle Kommunikation mit Python
[Python] Verwenden Sie JSON mit Python
Python lernen mit ChemTHEATER 05-1
HTTP-Anfrage in Python
Führen Sie prepDE.py mit python3 aus
1.1 Erste Schritte mit Python
Tweets mit Python sammeln
Binarisierung mit OpenCV / Python
Kernel-Methode mit Python
Nicht blockierend mit Python + uWSGI
Tweets mit Python posten
Fahren Sie WebDriver mit Python
Verwenden Sie Mecab mit Python 3
[Python] Mit CGIHTTPServer umleiten
Sprachanalyse mit Python
Denken Sie an Yaml mit Python
Kinesis mit Python betreiben
Erste Schritte mit Python
Verwenden Sie DynamoDB mit Python
Zundko Getter mit Python
Primzahlbeurteilung mit Python
Führen Sie Blender mit Python aus