2016-08-17 34 views
1

我想強制所有請求重試一些5xx HTTP狀態代碼。我會做什麼是:Python請求 - 如何爲創建的會話設置默認重試對象?

retry = requests.packages.urllib3.util.retry.Retry(
     total=20, 
     backoff_factor=0.1, 
     status_forcelist=[500, 502, 503, 504], 
     method_whitelist=frozenset(['GET', 'POST'])) 
for adapter in session.adapters.values(): 
    adapter.max_retries = retry 

但我需要做的是現有的代碼與不同的模塊/包中有很多不同的會話。其中一些使用s = Session(); s.get(),其他使用requests.get()。所以,我想迫使他們都使用這個實例。

是否可以在requests程序包級別(通過初始化,設置,簡單的猴子修補程序requests包)執行?

import requests 

# Initialize/setup/patch requests package. 
??? 

# Following should retry on server errors: 
requests.Session().get('http://httpstat.us/500') 
requests.post('http://httpstat.us/500', data={}) 

我試圖設置requests.adapters.DEFAULT_RETRIESretry對象。但是,這是不是它是如何工作...

回答

1
import requests 
import logging 


logging.basicConfig(level='DEBUG') 


def forceretry(max_retries): 
    """ Decorator for `requests.adapters.HTTPAdapter.__init__`. """ 
    def decorate(func): 
     def wrapper(self, *args, **kwargs): 
      func(self, *args, **kwargs) 
      self.max_retries = max_retries 
     return wrapper 
    return decorate 


max_retries = requests.packages.urllib3.util.retry.Retry(
     total=20, 
     backoff_factor=0.1, 
     status_forcelist=[500, 502, 503, 504], 
     method_whitelist=frozenset(['GET', 'POST'])) 

func = requests.adapters.HTTPAdapter.__init__ 
requests.adapters.HTTPAdapter.__init__ = forceretry(max_retries)(func) 

requests.post('http://httpstat.us/500', data={}) 

它迫使Retry對象爲每個會話(不設置默認的)。但它爲我工作。

0

我會用exponential backoff算法。

這是一個很好的包,爲您提供裝飾:backoff。可以與requests一起使用。從包文檔

代碼示例:

@backoff.on_exception(backoff.expo, 
         requests.exceptions.RequestException, 
         max_tries=8) 
def get_url(url): 
    return requests.get(url)