我们在整个项目中都使用了请求库。最近我们在我们的一个目的地遇到了一个错误,它在交易中冻结了,并且决定只打开连接。
当然,我们的申请也是如此。
是否有环境变量或其他一些设置超时的方法?即使它很重要(比方说,30秒),也应该足以阻止整个作品因为一项服务而停止。如果可能的话,它应该是全球性的,这样我就不必每次都能找到它,以免人们在将来忘记添加它。
答案 0 :(得分:8)
不幸的是,查看代码时,不可能设置全局默认值。我对此感到有些惊讶,因为我希望这是一个非常常见的用例。如果您发出功能请求,请告知我们(例如,对此帖子的评论)。
原因是get(...)
,post(...)
等方法都只是Session.request(...)
方法的简单包装(requests.get(...)
创建新的一次性会话,只是对于单个请求)。该方法以timeout
为参数,如果没有超时参数,则不检查Session
内部的值,因此您必须手动将其放在那里,如2ps中提出的那样{ {3}}
来源:
requests.get(...)
- 类似实用程序requests/__init__.py
- 上面导入的API模块;使用一次性会议requests.api
- Session
实施
requests.sessions
启动Session
class request(...)
方法timeout
参数get(...)
方法答案 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),
)