Je travaille avec le module de requêtes de python pour la communication HTTP et je me demande comment réutiliser les connexions TCP déjà établies)? Le module de requêtes est sans état et si j'appelle à plusieurs reprises get pour la même URL, ne ça crée pas une nouvelle connexion à chaque fois?
Merci!!
Le module des demandes est sans état et si j'appelle à plusieurs reprises get pour la même URL, ne créerait-il pas une nouvelle connexion à chaque fois?
Le module requests
n'est pas sans état; il vous permet simplement d'ignorer l'état et d'utiliser efficacement un état singleton global si vous le souhaitez. *
Et il (ou, plutôt, l'une des bibliothèques sous-jacentes, urllib3
) maintient un pool de connexions codé par une paire (nom d'hôte, port), donc il réutilise généralement comme par magie une connexion s'il le peut.
Comme la documentation dit:
Excellente nouvelle - grâce à urllib3, keep-alive est 100% automatique en une session! Toutes les demandes que vous faites dans une session réutilisent automatiquement la connexion appropriée!
Notez que les connexions ne sont renvoyées au pool pour réutilisation qu'une fois que toutes les données du corps ont été lues; assurez-vous de définir
stream
surFalse
ou de lire la propriétécontent
de l'objetResponse
.
Alors, que signifie "si cela peut"? Comme le suggèrent les documents ci-dessus, si vous gardez en vie les objets de réponse en streaming, leurs connexions ne peuvent évidemment pas être réutilisées.
De plus, le pool de connexions est vraiment un cache fini, pas infini, donc si vous envoyez du spam sur une tonne de connexions et que deux d'entre elles sont sur le même serveur, vous ne serez pas toujours réutiliser la connexion, juste souvent . Mais généralement, c'est ce que vous voulez réellement.
* L'état particulier pertinent ici est le adaptateur de transport . Chaque session reçoit un adaptateur de transport. Vous pouvez spécifier l'adaptateur manuellement, ou vous pouvez spécifier une valeur par défaut globale, ou vous pouvez simplement utiliser la valeur par défaut globale par défaut, qui se résume simplement à un urllib3.PoolManager
pour gérer ses connexions HTTP. Pour plus d'informations, lisez la documentation.
Fonctions globales comme requests.get
ou requests.post
créer le requests.Session
instance à chaque appel. Les connexions établies avec ces fonctions ne peuvent pas être réutilisées, car vous ne pouvez pas accéder à la session créée automatiquement et utiliser son pool de connexions pour les requêtes suivantes. C'est bien d'utiliser ces fonctions si vous n'avez qu'à faire quelques demandes. Sinon, vous voudrez gérer les sessions vous-même.
Voici un affichage rapide du comportement de requests
lorsque vous utilisez la fonction et la session globale get
.
Préparation, pas vraiment pertinente à la question:
>>> import logging, requests, timeit
>>> logging.basicConfig(level=logging.DEBUG, format="%(message)s")
Vous voyez, une nouvelle connexion est établie chaque fois que vous appelez get
:
>>> _ = requests.get("https://www.wikipedia.org")
Starting new HTTPS connection (1): www.wikipedia.org
>>> _ = requests.get("https://www.wikipedia.org")
Starting new HTTPS connection (1): www.wikipedia.org
Mais si vous utilisez la même session pour les appels suivants, la connexion est réutilisée:
>>> session = requests.Session()
>>> _ = session.get("https://www.wikipedia.org")
Starting new HTTPS connection (1): www.wikipedia.org
>>> _ = session.get("https://www.wikipedia.org")
>>> _ = session.get("https://www.wikipedia.org")
>>> _ = session.get("https://www.wikipedia.org")
Performance:
>>> timeit.timeit('_ = requests.get("https://www.wikipedia.org")', 'import requests', number=100)
Starting new HTTPS connection (1): www.wikipedia.org
Starting new HTTPS connection (1): www.wikipedia.org
Starting new HTTPS connection (1): www.wikipedia.org
...
Starting new HTTPS connection (1): www.wikipedia.org
Starting new HTTPS connection (1): www.wikipedia.org
Starting new HTTPS connection (1): www.wikipedia.org
52.74904417991638
>>> timeit.timeit('_ = session.get("https://www.wikipedia.org")', 'import requests; session = requests.Session()', number=100)
Starting new HTTPS connection (1): www.wikipedia.org
15.770191192626953
Fonctionne beaucoup plus rapidement lorsque vous réutilisez la session (et donc le pool de connexions de la session).