Utiliser les outils de Twisted de base pour faire les requêtes est assez chiant, et quand on est habitué à requests, c’est le retour au moyen age.
La lib treq tente de corriger ça mais n’utilise pas l’API de requests et ne propose pas certaine de ses fonctionnalités.
Du coup, après l’article d’hier, j’ai regardé le code source de requests-futures pour voir si je pouvais pas faire la même chose pour Twisted.
Et on peut. J’ai fais un petit (bon, ok minuscule) wrapper qui permet de faire ça :
from requests_twisted import TwistedRequestsSession session = TwistedRequestsSession() defer = session.get('http://github.com/sametmax/') def print_status(response): print(response.url, response.status_code) defer.addCallback(print_status) |
Ça utilise l’objet Session de requests et donc on peut faire session.get|post|touslestrucsderequests
et toute l’API est disponible.
Donc si vous en avez besoin :
pip install requests-twisted |
Le truc fait 3 lignes et 2 tests unittaires, en fait c’est juste un deferToThreads
derrière. C’est certain que c’est moins performant que l’approche de treq qui utilise directement l’Agent non bloquant de Twisted, mais pour la plupart des cas c’est juste plus pratique, plus familier, et surtout, plus facile à maintenir :)
Pourquoi ne pas utiliser directement aiohttp? API jolie + AsyncIO = gloire et bonheur sur ton chemin ;-)
?
C’est comme si je te disais “comment mettre des pneus neiges plus facilement sur votre 4×4″ et que tu me répondais “pourquoi tu n’utilises pas une clio ?”. Ben, parce que là, j’utilise un 4×4, et j’ai besoin de pneus neige ?
Désolé, mais je ne suis pas d’accord,: ce n’est pas fonctionnellement équivalent:
En gros, tu nous proposes un hack qui est franchement quand même assez sale/dangereux d’un point de vue asynchrone:
Normalement on n’utilise le déportage dans un thread qu’en dernier recours quand on ne peut pas faire autrement, car ça a un impact sur les performances de ta boucle évenementielle et que tu peux éventuellement ne pas être threadsafe.
Or là, tu mets cette technique en avant, notamment en la packageant dans une lib.
D’où ma remarque sur aiohttp qui est à la fois réellement asynchrone et une API à la requests.
Après, j’entends bien que tu as déjà beaucoup de code en Twisted, j’en ai eu aussi, et j’ai dû faire parfois des trucs crades dedans car pas le temps et/ou pas le choix.
Ben si, tu proposes d’utiliser un autre outils en partant du principe que l’on utilise Twisted que pour faire des requêtes. Alors que l’outil est là pour dire “si vous utilisez twisted et devez faire de requêtes”. Utiliser twisted est le postulat de départ, sinon quel interêt ?
asyncio fait pas mal de chose maintenant (http://asyncio.org), c’est pas du tout un jouet.
Mais encore une fois, quel rapport bon sang ? L’article ne dit aucunement “si vous devez faire des requêtes asynchrones, utilisez ça”. L’article dit, si vous devez faire des requêtes HTTP avec Twisted, voici un peu de sucre syntaxique. Twisted est un prérequis pour l’intérêt de cet article. Cessez de vouloir lancer un troll sur les meilleures solutions pour faire de l’asyncrone en Python, ce n’est pas le sujet.
pip install txrequests
:)
pip install txrequests
from txrequests import Session
@defer.inlineCallbacks
def main():
use with statement to cleanup session’s threadpool, and connectionpool after use
you can also use session.close() if want to use session for long term use
with Session() as session:
first request is started in background
d1 = session.get(‘http://httpbin.org/get’)
second requests is started immediately
d2 = session.get(‘http://httpbin.org/get?foo=bar’)
wait for the first request to complete, if it hasn’t already
response_one = yield d1
print(‘response one status: {0}’.format(response_one.status_code))
print(response_one.content)
wait for the second request to complete, if it hasn’t already
response_two = yield d2
print(‘response two status: {0}’.format(response_two.status_code))
print(response_two.content)
https://pypi.python.org/pypi/txrequests