在Python请求中重试

时间:2016-04-26 20:45:13

标签: python python-requests

我有以下需要重试:

我的Python脚本使用REQUESTS模块来调用API&解析JSON响应。

最近,API会返回不完整的数据,如下所示

数据不完整:

{
offerInfo: {
siteID: "001",
language: "en_US",
currency: "USD"
},
userInfo: {
persona: {
personaType: "OTHERS"
},
userId: "111"
},
offers: { }
}

完整数据:

{
offerInfo: {
siteID: "001",
language: "en_US",
currency: "USD"
},
userInfo: {
persona: {
personaType: "OTHERS"
},
userId: "111"
},
offers: { 
Flight: [
{
offerDateRange: {
travelStartDate: [
2016,
5,
7
],
travelEndDate: [
2016,
5,
11
]
}}}

完整的回复应该包含['offers'] ['Flight']键,否则我的代码应该在它放弃之前尝试调用API N次。转到下一个API URL。

我正在尝试使用以下代码进行会话,但不确定如何在其中添加检查['offers'] ['Flight']

注意:从API返回不完整的数据时没有HTTP错误,所以我必须依赖键['offers'] ['Flight']

session = requests.Session()
session.mount("http://", requests.adapters.HTTPAdapter(max_retries=2))
session.mount("https://", requests.adapters.HTTPAdapter(max_retries=2))
try:
    response = session.get(url=line,timeout=(connect_timeout,read_timeout),verify=False)

2 个答案:

答案 0 :(得分:1)

while循环加上评论中建议的计数是简单的答案,可能还不错。

如果您想要使用满足此类功能的模块,backoff是一个用于装饰函数的库,可通过可配置的退避行为进行重试。特别是,on_predicate装饰器允许您根据指定函数的返回值定义重试条件。

import backoff

def has_flight_offer(dct):
    return 'Flight' in dct.get('offers')

@backoff.on_predicate(backoff.constant, has_flight_offer, max_tries=3, interval=1)
def get_offers(session, url))
    response = session.get(url, verify=False)
    return response.json()

它还可以处理异常的重试,并且它可以很好地处理请求,因此您可以使用它来处理请求异常,同时您也可以使用类似的装饰。

@backoff.on_predicate(backoff.constant, has_flight_offer, max_tries=3, interval=1)
@backoff.on_exception(backoff.expo, requests.exceptions.RequestException, max_tries=3)
def get_offers(session, url))
    response = session.get(url, verify=False)
    return response.json()

答案 1 :(得分:0)

您可以使用坚韧。

文档:https://tenacity.readthedocs.io/en/latest/

它可以在之前或之后登录

import logging

logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)

logger = logging.getLogger(__name__)

@retry(stop=stop_after_attempt(3), before=before_log(logger, logging.DEBUG))
def raise_my_exception():
    raise MyException("Fail")