72 votes

Python - Demande de fermeture de la connexion http

Je me demandais, comment fermer une connexion avec Requests (python-requests.org) ?

Con httplib c'est HTTPConnection.close() mais comment faire de même avec les demandes ?

Code :

r = requests.post("https://stream.twitter.com/1/statuses/filter.json", data={'track':toTrack}, auth=('username', 'passwd'))
for line in r.iter_lines():
    if line:
        self.mongo['db'].tweets.insert(json.loads(line))

0 votes

Je ne pense pas que Requests établisse une connexion persistante... il n'y a pas de connexion à fermer.

0 votes

@michael, vous obtenez un pool de connexion persistant gratuitement, sauf si vous spécifiez le contraire. docs.python-requests.org/fr/latest/user/advanced/#keep-alive

0 votes

@istruble Alors urllib3 s'occupe du nettoyage du pool de connexion ?

78voto

Oleg Gryb Points 1525

Je pense qu'une manière plus fiable de fermer une connexion est de dire explicitement au serveur de la fermer d'une manière conforme à la spécification HTTP :

HTTP/1.1 définit l'option de connexion "close" pour que l'expéditeur indique que la connexion sera fermée une fois le message terminé. de signaler que la connexion sera fermée à la fin de la réponse. réponse. Par exemple,

   Connection: close

dans les champs d'en-tête de la demande ou de la réponse indique que la connexion NE DEVRAIT PAS être considérée comme `persistante' (section 8.1) une fois que la demande/réponse en cours est terminée.

El Connection: close est ajouté à la demande réelle :

r = requests.post(url=url, data=body, headers={'Connection':'close'})

0 votes

Qu'est-ce que le "corps" dans ce cas ? Un simple { } ?

1 votes

@Brad Cela dépend du type de contenu, par exemple, si vous voulez envoyer une application/json, vous pouvez utiliser data=json.dumps(payload), si vous voulez juste envoyer une charge utile commune codée par formulaire, vous pouvez utiliser data={"k1" : "v1", ...}. Voir plus de détails ici : docs.python-requests.org/en/latest/user/quickstart/

1 votes

C'est utilisé aquí mais pour une raison quelconque, il semble que la connexion ne soit pas vraiment fermée - je remarque que mon système d'exploitation est à court de ports - ce qui ne devrait pas se produire si la connexion est fermée correctement :/.

72voto

stwhite Points 447

Je suis venu à cette question en cherchant à résoudre le "too many open files" error mais j'utilise requests.session() dans mon code. Quelques recherches plus tard, j'ai trouvé une réponse sur le site de l Documentation sur les requêtes Python qui suggère d'utiliser le with afin que la session soit fermée même si des exceptions ne sont pas gérées :

with requests.Session() as s:
    s.get('http://google.com')

Si vous n'utilisez pas Session, vous pouvez en fait faire la même chose : https://2.python-requests.org/en/master/user/advanced/#session-objects

with requests.get('http://httpbin.org/get', stream=True) as r:
    # Do something

5 votes

Suis-je censé rétrograder les autres commentaires afin d'aider celui-là à monter ?

1 votes

@dmigo : Non. Ne décotez que si une réponse est fausse d'une manière ou d'une autre, ou si elle n'est pas utile à la question posée.

0 votes

Disons que je crée une session en utilisant "with" dans une fonction et que je renvoie la session. J'utilise la session dans tous mes tests. Comment saurais-je si la session est terminée ?

33voto

Felix Fung Points 781

Comme indiqué aquí En effet, il n'existe pas vraiment de connexion HTTP et ce que httplib appelle la connexion HTTPConnection est en fait la connexion TCP sous-jacente qui ne sait pas grand-chose de vos requêtes. Requests fait abstraction de cela et vous ne le verrez jamais.

La dernière version de Requests maintient en fait la connexion TCP en vie après votre demande. Si vous souhaitez que vos connexions TCP soient fermées, vous pouvez simplement configurer les requêtes pour qu'elles n'utilisent pas la fonction keep-alive .

s = requests.session()
s.config['keep_alive'] = False

15 votes

Ou bien s = requests.session(config={'keep_alive': False})

6 votes

L'OP demandait comment fermer une réponse de streaming. Je ne vois pas en quoi le fait d'activer le mode "keep-alive" sur la session peut être utile. Il y a plusieurs tickets récents dans requests et urllib3 autour de cette question : github.com/shazow/urllib3/pull/132 , github.com/kennethreitz/requests/issues/1073 , github.com/kennethreitz/requests/issues/1041

0 votes

28voto

hatcher Points 131

Veuillez utiliser response.close() à fermer pour éviter l'erreur "trop de fichiers ouverts".

par exemple :

r = requests.post("https://stream.twitter.com/1/statuses/filter.json", data={'track':toTrack}, auth=('username', 'passwd'))
....
r.close()

0 votes

Je cherchais des réponses pour exactement ce problème !

0 votes

Quel est le nombre maximum de connexions qu'une session peut gérer avant de donner l'erreur "trop de fichiers ouverts" ?

12voto

Wilfred Hughes Points 3507

Sur Requests 1.X, la connexion est disponible sur l'objet de réponse :

r = requests.post("https://stream.twitter.com/1/statuses/filter.json",
                  data={'track': toTrack}, auth=('username', 'passwd'))

r.connection.close()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X