Twisted et requests


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 :)

8 thoughts on “Twisted et requests

  • Ludovic Gasc

    Pourquoi ne pas utiliser directement aiohttp? API jolie + AsyncIO = gloire et bonheur sur ton chemin ;-)

  • Sam Post author

    ?

    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 ?

  • Ludovic Gasc

    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.

  • Sam Post author

    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 ?

  • Sam Post author

    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.

  • Pierre Tardy

    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

Comments are closed.

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.