Как обрабатывать тайм-ауты с помощью httplib (python 2.6)?


Я использую httplib для доступа к api через https и должен построить обработку исключений в случае, если api не работает.

Вот пример соединения:

connection = httplib.HTTPSConnection('non-existent-api.com', timeout=1)
connection.request('POST', '/request.api', xml, headers={'Content-Type': 'text/xml'})
response = connection.getresponse()

Это должно быть таймаутом, поэтому я ожидал, что будет вызвано исключение, и response.read() просто возвращает пустую строку.

Как я могу узнать, был ли тайм-аут? Еще лучше, как лучше всего справиться с проблемой, когда сторонний api не работает?

3 5

3 ответа:

Urllib и httplib не предоставляют таймаут. Вы должны включить сокет и установить там тайм-аут:

import socket
socket.settimeout(10) # or whatever timeout you want

Еще лучше, какой лучший способ изящно справиться с проблемой сбоя стороннего api?

What's mean API is down, API return http 404, 500 ...

Или вы имеете в виду, когда API не может быть доступен ?

Во-первых, я не думаю, что вы можете знать, если веб-сервис в целом не работает, прежде чем пытаться получить к нему доступ, поэтому я буду рекомендовать для первого вы можете сделать так:

import httplib

conn = httplib.HTTPConnection('www.google.com')  # I used here HTTP not HTTPS for simplify
conn.request('HEAD', '/')  # Just send a HTTP HEAD request 
res = conn.getresponse()

if res.status == 200:
   print "ok"
else:
   print "problem : the query returned %s because %s" % (res.status, res.reason)  

И для проверки, если API не доступен, я думаю, что вы будете лучше сделать попытку поймать:

import httplib
import socket

try:
   # I don't think you need the timeout unless you want to also calculate the response time ...
   conn = httplib.HTTPSConnection('www.google.com') 
   conn.connect()
except (httplib.HTTPException, socket.error) as ex:
   print "Error: %s" % ex

Вы можете смешать два способа, если хотите что-то более общее, надеюсь, это поможет

Это то, что я нашел, чтобы работать правильно с httplib2. Разместив его, как это все еще может кому-то помочь:

    import httplib2, socket

    def check_url(url):
        h = httplib2.Http(timeout=0.1) #100 ms timeout
        try:
            resp = h.request(url, 'HEAD')
        except (httplib2.HttpLib2Error, socket.error) as ex:
            print "Request timed out for ", url
            return False
        return int(resp[0]['status']) < 400