多次调用 requests_oauthlib 时出现 TypeError(错误实际上是在 urllib3 中引发的)
TypeError when calling requests_oauthlib multiple times (error actually raised within urllib3)
我正在编写脚本以从 Twitter API 中提取一些数据。它使用 OAuth 1.1 意味着我在 requests
之上使用 requests_oauthlib
帮助程序库来验证会话。
第一次调用 API 有效,但随后的调用给出 TypeError
如下:
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/packages/urllib3/connection.pyc in __init__(self, *args, **kw)
124
125 # Superclass also sets self.source_address in Python 2.7+.
--> 126 _HTTPConnection.__init__(self, *args, **kw)
127
128 def _new_conn(self):
TypeError: unbound method __init__() must be called with HTTPConnection instance as first argument (got VerifiedHTTPSConnection instance instead)
看起来会话中一直存在某些问题,因为它总是在重复使用时出现错误。我尝试了一个干净的 virtualenv,通过 pip 安装了最新版本,没有区别。
我正在使用上下文管理器方法,所以我认为会话会在每次调用后被销毁,从而防止这种情况发生:
with ro.OAuth1Session(**self._auth) as s:
response = s.get(url)
任何修复或指示以了解导致问题的原因将不胜感激。
编辑: 我尝试了一种不同的方法,使用 requests
文档 (http://docs.python-requests.org/en/master/user/authentication/) 中描述的另一种构建会话的方法但出现了同样的错误。
编辑: 全栈以防有用:
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/sessions.pyc 在 get(self, url, **kwargs)
485
486kwargs.setdefault('allow_redirects',正确)
--> 487 return self.request('GET', url, **kwargs)
488
489 def 选项(self, url, **kwargs):
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/sessions.pyc in request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
473 }
474 send_kwargs.update(settings)
--> 475 resp = self.send(prep, **send_kwargs)
476
477 return resp
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/sessions.pyc in send(self, request, **kwargs)
583
584 # Send the request
--> 585 r = adapter.send(request, **kwargs)
586
587 # Total elapsed time of the request (approximately)
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/adapters.pyc in send(self, request, stream, timeout, verify, cert, proxies)
401 decode_content=False,
402 retries=self.max_retries,
--> 403 timeout=timeout
404 )
405
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.pyc in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, **response_kw)
564 # Request a connection from the queue.
565 timeout_obj = self._get_timeout(timeout)
--> 566 conn = self._get_conn(timeout=pool_timeout)
567
568 conn.timeout = timeout_obj.connect_timeout
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.pyc in _get_conn(self, timeout)
254 conn = None
255
--> 256 return conn or self._new_conn()
257
258 def _put_conn(self, conn):
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.pyc in _new_conn(self)
800 conn = self.ConnectionCls(host=actual_host, port=actual_port,
801 timeout=self.timeout.connect_timeout,
--> 802 strict=self.strict, **self.conn_kw)
803
804 return self._prepare_conn(conn)
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/packages/urllib3/connection.pyc in __init__(self, host, port, key_file, cert_file, strict, timeout, **kw)
208
209 HTTPConnection.__init__(self, host, port, strict=strict,
--> 210 timeout=timeout, **kw)
211
212 self.key_file = key_file
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/packages/urllib3/connection.pyc in __init__(self, *args, **kw)
124
125 # Superclass also sets self.source_address in Python 2.7+.
--> 126 _HTTPConnection.__init__(self, *args, **kw)
127
128 def _new_conn(self):
TypeError: unbound method __init__() must be called with HTTPConnection instance as first argument (got VerifiedHTTPSConnection instance instead)
OAuth1Session 的格式为:
oauth = OAuth1Session(client_key,
client_secret=client_secret,
resource_owner_key=resource_owner_key,
resource_owner_secret=resource_owner_secret,
verifier=verifier)
** 与关键字参数一起使用,OAuth1Session 具有不同的签名
编辑:还添加了对 IPython / Jupyter 中重新加载容器库的引用。
经过大量阅读后,当您根据请求调用 get
但不访问响应主体时(这是我在构建/调试流量):
http://docs.python-requests.org/en/master/user/advanced/#keep-alive
"Note that connections are only released back to the pool for reuse once all body data has been read; be sure to either set stream to False or read the content property of the Response object."
所以答案是确保在发出请求后做的第一件事是通过调用 Response.content
、Response.json()
或类似方法刷新响应。
问题只在使用 requests_oauthlib
库时出现,因为它使用的会话不太常见。通过使用不影响会话对象本身的查询参数,我已经毫无问题地对 Facebook 和 LinkedIn API 进行了类似操作。
在 IPython / Jupyter 中重新加载帮助程序库时,它也最常出现。退出笔记本或命令行会话然后重新启动将解决问题。
我正在编写脚本以从 Twitter API 中提取一些数据。它使用 OAuth 1.1 意味着我在 requests
之上使用 requests_oauthlib
帮助程序库来验证会话。
第一次调用 API 有效,但随后的调用给出 TypeError
如下:
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/packages/urllib3/connection.pyc in __init__(self, *args, **kw)
124
125 # Superclass also sets self.source_address in Python 2.7+.
--> 126 _HTTPConnection.__init__(self, *args, **kw)
127
128 def _new_conn(self):
TypeError: unbound method __init__() must be called with HTTPConnection instance as first argument (got VerifiedHTTPSConnection instance instead)
看起来会话中一直存在某些问题,因为它总是在重复使用时出现错误。我尝试了一个干净的 virtualenv,通过 pip 安装了最新版本,没有区别。
我正在使用上下文管理器方法,所以我认为会话会在每次调用后被销毁,从而防止这种情况发生:
with ro.OAuth1Session(**self._auth) as s:
response = s.get(url)
任何修复或指示以了解导致问题的原因将不胜感激。
编辑: 我尝试了一种不同的方法,使用 requests
文档 (http://docs.python-requests.org/en/master/user/authentication/) 中描述的另一种构建会话的方法但出现了同样的错误。
编辑: 全栈以防有用:
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/sessions.pyc 在 get(self, url, **kwargs) 485 486kwargs.setdefault('allow_redirects',正确) --> 487 return self.request('GET', url, **kwargs) 488 489 def 选项(self, url, **kwargs):
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/sessions.pyc in request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
473 }
474 send_kwargs.update(settings)
--> 475 resp = self.send(prep, **send_kwargs)
476
477 return resp
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/sessions.pyc in send(self, request, **kwargs)
583
584 # Send the request
--> 585 r = adapter.send(request, **kwargs)
586
587 # Total elapsed time of the request (approximately)
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/adapters.pyc in send(self, request, stream, timeout, verify, cert, proxies)
401 decode_content=False,
402 retries=self.max_retries,
--> 403 timeout=timeout
404 )
405
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.pyc in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, **response_kw)
564 # Request a connection from the queue.
565 timeout_obj = self._get_timeout(timeout)
--> 566 conn = self._get_conn(timeout=pool_timeout)
567
568 conn.timeout = timeout_obj.connect_timeout
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.pyc in _get_conn(self, timeout)
254 conn = None
255
--> 256 return conn or self._new_conn()
257
258 def _put_conn(self, conn):
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.pyc in _new_conn(self)
800 conn = self.ConnectionCls(host=actual_host, port=actual_port,
801 timeout=self.timeout.connect_timeout,
--> 802 strict=self.strict, **self.conn_kw)
803
804 return self._prepare_conn(conn)
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/packages/urllib3/connection.pyc in __init__(self, host, port, key_file, cert_file, strict, timeout, **kw)
208
209 HTTPConnection.__init__(self, host, port, strict=strict,
--> 210 timeout=timeout, **kw)
211
212 self.key_file = key_file
/Users/phil/code/Virtualenv/req_test/lib/python2.7/site-packages/requests/packages/urllib3/connection.pyc in __init__(self, *args, **kw)
124
125 # Superclass also sets self.source_address in Python 2.7+.
--> 126 _HTTPConnection.__init__(self, *args, **kw)
127
128 def _new_conn(self):
TypeError: unbound method __init__() must be called with HTTPConnection instance as first argument (got VerifiedHTTPSConnection instance instead)
OAuth1Session 的格式为:
oauth = OAuth1Session(client_key,
client_secret=client_secret,
resource_owner_key=resource_owner_key,
resource_owner_secret=resource_owner_secret,
verifier=verifier)
** 与关键字参数一起使用,OAuth1Session 具有不同的签名
编辑:还添加了对 IPython / Jupyter 中重新加载容器库的引用。
经过大量阅读后,当您根据请求调用 get
但不访问响应主体时(这是我在构建/调试流量):
http://docs.python-requests.org/en/master/user/advanced/#keep-alive
"Note that connections are only released back to the pool for reuse once all body data has been read; be sure to either set stream to False or read the content property of the Response object."
所以答案是确保在发出请求后做的第一件事是通过调用 Response.content
、Response.json()
或类似方法刷新响应。
问题只在使用 requests_oauthlib
库时出现,因为它使用的会话不太常见。通过使用不影响会话对象本身的查询参数,我已经毫无问题地对 Facebook 和 LinkedIn API 进行了类似操作。
在 IPython / Jupyter 中重新加载帮助程序库时,它也最常出现。退出笔记本或命令行会话然后重新启动将解决问题。