2017-10-02 9 views
0

J'essaie d'effectuer des requêtes HTTP asynchrones en utilisant la bibliothèque de requêtes en Python. J'ai trouvé que la dernière version de la bibliothèque ne supporte pas directement les requets asynchrones. Pour y parvenir, ils fournissent la bibliothèque requests-threads qui utilise Twisted pour gérer l'asynchronicité. J'ai essayé de modifier les exemples fournis pour utiliser les callbacks au lieu de wait/yield, mais les callbacks ne sont pas appelés.Le rappel différé n'est pas appelé à l'aide de requêtes-threads Python

Mon exemple de code est:

session = AsyncSession(n=10) 

def processResponse(response): 
    print(response) 

def main(): 
    a = session.get('https://reqres.in/api/users') 
    a.addCallbacks(processResponse, processResponse) 
    time.sleep(5) 

La bibliothèque demande-fils: https://github.com/requests/requests-threads

Répondre

2

Je soupçonne que les callbacks ne sont pas appelés parce que vous n'êtes pas en cours d'exécution de eventloop de Twisted (connu sous le nom reactor). Retirez votre fonction de veille et remplacez-la par reactor.run().

from twisted.internet import reactor 
# ... 
def main(): 
    a = session.get('https://reqres.in/api/users') 
    a.addCallbacks(processResponse, processResponse) 
    #time.sleep(5) # never use blocking functions like this w/ Twisted 
    reactor.run() 

Le hic est le réacteur de Twisted ne peut pas être redémarré, donc une fois que vous arrêtez la boucle d'événements (ie. reactor.stop()), une exception sera levée lorsque reactor.run() est exécuté à nouveau. En d'autres termes, votre script/application ne fonctionnera qu'une fois. Pour contourner ce problème, je vous suggère d'utiliser crochet. Voici un exemple rapide en utilisant un exemple similaire de requests-thread:

import crochet 
crochet.setup() 
print('setup') 

from twisted.internet.defer import inlineCallbacks 
from requests_threads import AsyncSession 

session = AsyncSession(n=100) 

@crochet.run_in_reactor 
@inlineCallbacks 
def main(reactor): 
    responses = [] 
    for i in range(10): 
     responses.append(session.get('http://httpbin.org/get')) 

    for response in responses: 
     r = yield response 
     print(r) 

if __name__ == '__main__': 
    event = main(None) 
    event.wait() 

Et tout comme un FYI requests-thread n'est pas pour les systèmes de production et est soumise à des changements importants (en octobre 2017). L'objectif final de ce projet est de concevoir un modèle de conception attendu pour requests à l'avenir. Si vous avez besoin de demandes simultanées en production, envisagez grequests ou treq.

0

Je pense que la seule erreur ici est que vous avez oublié d'exécuter le reactor/event loop.

Le code suivant fonctionne pour moi:

from twisted.internet import reactor 
from requests_threads import AsyncSession 

session = AsyncSession(n=10) 


def processResponse(response): 
    print(response) 


a = session.get('https://reqres.in/api/users') 
a.addCallbacks(processResponse, processResponse) 
reactor.run()