有没有办法全局覆盖请求'超时设置?

时间:2016-12-23 04:20:34

标签: python python-requests

我们在整个项目中都使用了请求库。最近我们在我们的一个目的地遇到了一个错误,它在交易中冻结了,并且决定只打开连接。

当然,我们的申请也是如此。

是否有环境变量或其他一些设置超时的方法?即使它很重要(比方说,30秒),也应该足以阻止整个作品因为一项服务而停止。如果可能的话,它应该是全球性的,这样我就不必每次都能找到它,以免人们在将来忘记添加它。

6 个答案:

答案 0 :(得分:8)

不幸的是,查看代码时,不可能设置全局默认值。我对此感到有些惊讶,因为我希望这是一个非常常见的用例。如果您发出功能请求,请告知我们(例如,对此帖子的评论)。

原因是get(...)post(...)等方法都只是Session.request(...)方法的简单包装(requests.get(...)创建新的一次性会话,只是对于单个请求)。该方法以timeout为参数,如果没有超时参数,则不检查Session内部的值,因此您必须手动将其放在那里,如2ps中提出的那样{ {3}}

来源:

答案 1 :(得分:5)

实现这一目标的两种方法。它涉及一些脏猴子修补。在python 3.6上测试。

将此放在像main.py, init .py或urls.py这样的文件中,并确保调用它。

选项1:修补请求方法

import requests

def request_patch(slf, *args, **kwargs):
    print("Fix called")
    timeout = kwargs.pop('timeout', 2)
    return slf.request_orig(*args, **kwargs, timeout=timeout)

setattr(requests.sessions.Session, 'request_orig', requests.sessions.Session.request)
requests.sessions.Session.request = request_patch

选项2:修补Session类

import requests

class SessionTimeoutFix(requests.Session):

    def request(self, *args, **kwargs):
        print("Fix called")
        timeout = kwargs.pop('timeout', 2)
        return super().request(*args, **kwargs, timeout=timeout)

requests.sessions.Session = SessionTimeoutFix

答案 2 :(得分:3)

相反,您可以继承request.Session类并重写request函数,就像这样。

HTTP_TIMEOUT = 30

class TimeoutRequestsSession(requests.Session):
    def request(self, *args, **kwargs):
        if kwargs.get('timeout') is None:
            kwargs['timeout'] = HTTP_TIMEOUT
        return super(TimeoutRequestsSession, self).request(*args, **kwargs)

session = TimeoutRequestsSession()
session.get('https://www.google.com') # connection timeout is default 30s

答案 3 :(得分:1)

您当然可以使用timeout参数进行每次通话:

requests.get('http://www.google.com', timeout=10)

timeout参数指定秒数或元组(连接超时,读取时间)。您可以阅读更多相关信息here

如果你想使这个全局化,最简单的方法是将所有调用重构为包装类,并确保每个人都使用包装类来调用这个API端点。我快速检查了请求代码,并没有看到使用全局覆盖超时,因为默认行为是等待数据。

答案 4 :(得分:1)

最简单的方法是"shim" the session's request function

import requests
import functools

s = requests.Session()
s.request = functools.partial(s.request, timeout=3)

# now all get, post, head etc requests should timeout after 3 seconds
# following will fail
s.get('https://httpbin.org/delay/6')

# we can still pass higher timeout when needed
# following will succeed
s.get('https://httpbin.org/delay/6', timeout=7)

答案 5 :(得分:0)

为什么不呢?

    for method in ("get", "options", "head", "post", "put", "patch", "delete"):
        setattr(
            session,
            method,
            functools.partial(getattr(session, method), timeout=timeout),
        )