我们在整个项目中都使用了请求库。最近我们在我们的一个目的地遇到了一个错误,它在交易中冻结,并决定只是保持连接打开。
当然,我们的申请也是如此。
是否有环境变量或其他一些设置超时的方法?即使它很重要(例如,30秒),也应该足以阻止整个工作因为一项服务而停止。如果可能的话,它应该是全球性的,这样我就不必每次都能找到它,所以人们不会忘记将来添加它。
不幸的是,查看代码时,不可能设置全局默认值。我对此感到有些惊讶,因为我希望这是一个非常常见的用例。如果您发出功能请求,请告知我们(例如,对此帖子的评论)。
原因是像get(...)
,post(...)
等方法都只是Session.request(...)
方法的薄包装(requests.get(...)
创建新的一次性会话,仅针对单个请求)。该方法将timeout
作为参数,并且如果没有超时参数,则不检查Session
内部的值,因此您必须手动将其放在那里,如2ps中提出的his answer。
资料来源:
requests/__init__.py
- 导入包装范围的API,以提供类似requests.get(...)
的实用程序requests.api
- 上面导入的API模块;使用一次性会话requests.sessions
- Session
实施
line 283开始Session
类
line 411开始request(...)
方法
line 484实际上使用timeout
参数
line 492开始get(...)
方法实现这一目标的两种方法。它涉及一些脏猴子修补。在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
相反,你可以继承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
你当然可以使用timeout
参数进行每次调用:
requests.get('http://www.google.com', timeout=10)
timeout
参数指定秒数或元组(连接超时,读取时间)。你可以阅读更多关于它here。
如果要使这种全局化,最简单的方法是将所有调用重构为包装类,并确保每个人都使用包装类来调用此API端点。我快速检查了请求代码,并没有看到使用全局覆盖超时,因为默认行为是等待数据。
为什么不?:
for method in ("get", "options", "head", "post", "put", "patch", "delete"):
setattr(
session,
method,
functools.partial(getattr(session, method), timeout=timeout),
)