【问题标题】:Do something on connection error apart from retry with python requests除了使用 python 请求重试之外,对连接错误做一些事情
【发布时间】:2018-01-02 13:47:45
【问题描述】:

我正在使用 Python 请求来发出发布请求。
我正在尝试做这样的事情,如下面的帖子所示: Retry with requests

当连接错误或收到来自status_forcelist的响应状态码时,它应该重试(工作正常)。我想做的是在第一次尝试之后(重试之前),我想做一些其他的事情。如果我可以捕获异常并处理它来做其他事情,这可能是可能的。但是,如果连接错误或响应代码在 status_forcelist 中,请求似乎不会引发任何异常,除非重试计数达到配置的最大值。我怎样才能做到这一点?

这是代码示例:

def requests_retry_session(
    retries=3,
    backoff_factor=0.3,
    status_forcelist=(500, 502, 504),
    session=None,
):
    session = session or requests.Session()
    retry = Retry(
        total=retries,
        read=retries,
        connect=retries,
        backoff_factor=backoff_factor,
        status_forcelist=status_forcelist,
    )
    adapter = HTTPAdapter(max_retries=retry)
    session.mount('http://', adapter)
    session.mount('https://', adapter)
    return session

def do_something_more():
    ## do something to tell user API failed and it will retry
    print("I am doing something more...")

用法...

t0 = time.time()
try:
    response = requests_retry_session().get(
        'http://localhost:9999',
    )
except Exception as x:
    # Catch exception when connection error or 500 on first attempt and do something more

    do_somthing_more() 
    print('It failed :(', x.__class__.__name__)
else:
    print('It eventually worked', response.status_code)
finally:
    t1 = time.time()
    print('Took', t1 - t0, 'seconds')

我知道在最大允许尝试次数后会引发异常(在 retries=3 中定义)。我想要的只是来自请求或 urllib3 的一些信号,告诉我的主程序第一次尝试失败,现在它将开始重试。这样我的程序就可以基于它做更多的事情。如果不是通过异常,其他的。

【问题讨论】:

  • 您应该尝试单独编写几行代码,以表明您正在积极考虑解决问题,然后向其他人寻求帮助。即使提供了该站点,您的问题也可能不清楚,除非您通过在此处粘贴到目前为止所获得的内容来展示您真正想要的内容。
  • @Sqoshu 有道理。我已按照您的建议使用代码示例更新了我的问题,以使其更清晰。

标签: python python-3.x python-requests urllib3


【解决方案1】:

最强大的方法(但可能不是最好的,当然也不是最有效的)就是将retries 设置为 0 - 然后每次都会引发异常。然后我将使用手动计数器调用该函数三次,它将计算您尝试重新连接的次数。像这样的东西(我没有检查它是否有效,只是想向您展示我的思维方式):

counter = 0
t0 = time.time()
for i in range(3):
    try:
        response = requests_retry_session().get(
            'http://localhost:9999',
        )
        #This should already be set to retries=0
    except MaxRetryError:
            counter += 1
            do_something_more() 
            print('It is the {} time it failed'.format(counter))
    else:
         break #If there isn't MaxRetryError, it connected successfully, so we don't have to execute for anymore
t1 = time.time()
print('Took', t1 - t0, 'seconds')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-27
    • 2018-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-31
    相关资源
    最近更新 更多