establecer el tiempo de espera para el método de lectura de respuesta http en Python

Estoy creando un administrador de descargas en Python por diversión, y algunas veces la conexión con el servidor todavía está activa pero el servidor no me envía datos, así que el método de lectura (de HTTPResponse) me bloquea para siempre. Esto sucede, por ejemplo, cuando descargo desde un servidor, ubicado fuera de mi país, que limita el ancho de banda a otros países.

¿Cómo puedo configurar un tiempo de espera para el método de lectura (2 minutos, por ejemplo)?

Gracias, Nir.

Tienes que configurarlo durante la inicialización de HTTPConnection .

Nota: en caso de que esté utilizando una versión anterior de Python, puede instalar httplib2 ; para muchos, se considera una alternativa superior a httplib, y admite el tiempo de espera .
Sin embargo, nunca lo he usado, y solo informo lo que dicen los documentos y los blogs.

Si está atascado en alguna versión de Python < 2.6 , un enfoque (imperfecto pero utilizable) es hacerlo

 import socket socket.setdefaulttimeout(10.0) # or whatever 

antes de comenzar a utilizar httplib . Los documentos están aquí y establecen claramente que setdefaulttimeout está disponible desde Python 2.3: cada socket realizado desde el momento en que realizas esta llamada, hasta el momento en que vuelves a llamar a la misma función, utilizará ese tiempo de espera de 10 segundos. Puede usar getdefaulttimeout antes de configurar un nuevo tiempo de espera, si desea guardar el tiempo de espera anterior (incluido ninguno) para poder restaurarlo más tarde (con otro setdefaulttimeout ).

Estas funciones y expresiones idiomáticas son bastante útiles siempre que necesite usar una biblioteca de nivel superior más antigua que utiliza socket Python socket pero no le proporciona una buena manera de establecer tiempos de espera (por supuesto, es mejor usar bibliotecas de nivel superior actualizadas, por ejemplo, httplib versión httplib que viene con 2.6 o httplib2 terceros en este caso, pero eso no siempre es factible, y jugar con la configuración predeterminada de tiempo de espera puede ser una buena solución.

Establecer el tiempo de espera predeterminado puede abortar una descarga antes si es grande, en lugar de abortar solo si deja de recibir datos para el valor de tiempo de espera. HTTPlib2 es probablemente el camino a seguir.

5 años después, pero espero que esto ayude a alguien más …

Estaba destrozando mi cerebro tratando de resolver esto. Mi problema fue que un servidor devolvía contenido corrupto y, por lo tanto, devolvía menos datos de los que creía.

Se me ocurrió una solución desagradable que parece estar funcionando correctamente. Aquí va:

 # NOTE I directly disabling blocking is not necessary but it represents # an important piece to the problem so I am leaving it here. # http_response.fp._sock.socket.setblocking(0) http_response.fp._sock.settimeout(read_timeout) http_response.read(chunk_size) 

NOTA Esta solución también funciona para las solicitudes de python CUALQUIER biblioteca que implementa los sockets de python normales (¿cuáles deberían ser todos?). Solo tienes que ir unos niveles más profundos:

 resp.raw._fp.fp._sock.socket.setblocking() resp.raw._fp.fp._sock.settimeout(read_timeout) resp.raw.read(chunk_size) 

En el momento de escribir este artículo, no he intentado lo siguiente, pero en teoría debería funcionar:

 resp = requests.get(some_url, stream=True) resp.raw._fp.fp._sock.socket.setblocking() resp.raw._fp.fp._sock.settimeout(read_timeout) for chunk in resp.iter_content(chunk_size): # do stuff 

Explicación

Me encontré con este enfoque al leer esta pregunta SO para establecer un tiempo de espera en socket.recv

Al final del día, cualquier solicitud http tiene un socket. Para el httplib, ese socket se encuentra en resp.raw._fp.fp._sock.socket . El resp.raw._fp.fp._sock es un socket._fileobj (que honestamente no socket._fileobj mucho) y me imagino que el método settimeout establece internamente en el atributo socket .