
ich fange gerade an mich mit "async/asyncio" zu beschäftigen, es scheint leider doch deutlich schwerer zu erlernen, als ich gedacht habe (in test-codes gibts ständig fehlermeldungen wie "nicht awaited" oder "das muss in async funktion rein", ohne dass ich verstehe warum das so sein muss)
Jedenfalls ist mein Hauptanliegen, in einem synchron laufendem code, async zu verwenden, um gleichzeitig x REST API calls zu machen.
Aktuell mache ich das simpel mit threads. Nur leider kommt es ab und zu auch vor, dass ich 1000+ API calls möglichst gleichzeitig machen muss. Und wenn ich das mit Threads versuche, gibts logischerweise den Fehler, dass keine neuen threads gestartet werden können, weil schon zuviele aktiv sind. Nun könnte ich stattdessen einfach immer nur 500 calls aufeinmal machen und das nacheinander... aber ich glaube async wäre hier die bessere Wahl, oder?
Nur wie verändere ich folgenden beispiel code so, dass die calls mit async funktionieren? (Ich habe aktuell den Eindruck, dass async nur geht, wenn der vollständige code auf async basiert, doch ich will den hauptcode eigentlich weiterhin synchron haben, da der ohne die REST Ergebnisse sowieso nicht weiterlaufen kann):
Code: Alles auswählen
import concurrent.futures
import time
import requests
class Test:
def __init__(self):
self.url = "https://api.github.com/events" # example url
self.session = requests.session()
self.Pool = concurrent.futures.ThreadPoolExecutor(500)
def make_call(self,i): # requests/aiohttp code to do the REST calls
return self.session.get(url=self.url,params={"param":i})
def run(self):
while True:
# make stuff
results = []
futures = []
for i in range(1000): # doing 1000 REST API calls as fast as possible
futures.append( self.Pool.submit( self.make_call, i) )
for future in futures:
results.append(future.result())
# do stuff with results
time.sleep(2) # start over again in some seconds.
Test().run()
Außerdem kam ich mit aiohttp noch nicht ganz klar, denn jedes Beispiel was ich dazu finde, lässt sich glaube ich nicht auf meinen code anwenden. Denn da wird entweder mit context manager gearbeitet um eine session zu öffnen/schließen oder halt am Ende des programms "await session.close()" aufgerufen (welches nur innerhalb einer async funktion geht). Aber ich möchte so eine clientsession ja nur einmal zu start des skripts öffnen und dann soll diese offen bleiben, bis ich das ganze system wieder beende. Die session soll also nicht jeden "while True" Durchlauf neu geöffnet und geschlossen werden.