Python requests/urllib3 仅当脚本在办公室的 cronjob 上运行时才会出现 NewConnectionError
Python requests/urllib3 NewConnectionError only when script runs on a cronjob from the office
奇怪的问题我想不通。
我有一个使用 Python 的请求库的脚本,并且 运行 在 cronjob 上。当我在家通过 VPN 时,它工作正常。
如果我在办公室,cronjob returns 连接错误,更具体地说是 NewConnectionError[错误 60:连接超时](由 urllib3 引发)。奇怪的是,如果我从命令行手动 运行 脚本,它没有问题。
我对 requests/urllib3/cron 的工作原理只有高层次的理解。我猜连接是以某种方式缓存的,但我不确定。有谁知道这可能是什么原因造成的?
脚本本身是一个同步实用程序,可创建与 bitbucket 的 api 的连接。我创建了一个 api-wrapper 来实现这一点,它本质上只是一个用来构建查询的对象。这是包装器的一个片段:
def __init__(self, username, password):
s = requests.Session()
s.auth = (username, password)
self._bitbucket_session = s
def _get_context(self, url, paging):
try:
r = self._bitbucket_session.get(url)
if r.status_code == 403:
raise self.BitbucketAPIError('BitbucketAPIError: {}'.format(r.reason))
if 'error' in r.json():
raise self.BitbucketAPIError('BitbucketAPIError: {}'.format(r.json()['error']['message']))
except HTTPError as e:
print("HTTP Error: {}".format(e))
except ConnectTimeout as e:
print("The request timed out while trying to connect to the remote server: {}".format(e))
except ConnectionError as e:
print("Connection Error: {}".format(e))
except Timeout as e:
print("Connection Timed out: {}".format(e))
except RequestException as e:
print("Unhandled exception: {}".format(e))
这里是同步客户端的简化版本 "croned":
bapi = BitbucketApi(username, password)
# blah blah blah
update_members()
update_repository()
bapi.close()
这里是关闭方法:
def close(self):
self._bitbucket_session.close()
可能涉及代理。
从你家运行脚本时没有代理,或者代理配置正确,所以没有问题。
当 运行 从您办公室的命令行中正确配置 shell 环境以通过环境变量设置 HTTP/S 代理时:
export http_proxy="http://proxy.com:3128"
export https_proxy="https://proxy.com:3128"
(大写变量也有效,即HTTP_PROXY、HTTPS_PROXY)
但是,当脚本来自 cron
运行 时,环境没有设置代理变量,连接请求超时。您为脚本创建一个包装器,然后从 cron 执行包装器脚本。例如
#!/bin/sh
export HTTP_PROXY="http://proxy:1234"
export HTTPS_PROXY="https://proxy:1234"
python your_script.py
奇怪的问题我想不通。
我有一个使用 Python 的请求库的脚本,并且 运行 在 cronjob 上。当我在家通过 VPN 时,它工作正常。
如果我在办公室,cronjob returns 连接错误,更具体地说是 NewConnectionError[错误 60:连接超时](由 urllib3 引发)。奇怪的是,如果我从命令行手动 运行 脚本,它没有问题。
我对 requests/urllib3/cron 的工作原理只有高层次的理解。我猜连接是以某种方式缓存的,但我不确定。有谁知道这可能是什么原因造成的?
脚本本身是一个同步实用程序,可创建与 bitbucket 的 api 的连接。我创建了一个 api-wrapper 来实现这一点,它本质上只是一个用来构建查询的对象。这是包装器的一个片段:
def __init__(self, username, password):
s = requests.Session()
s.auth = (username, password)
self._bitbucket_session = s
def _get_context(self, url, paging):
try:
r = self._bitbucket_session.get(url)
if r.status_code == 403:
raise self.BitbucketAPIError('BitbucketAPIError: {}'.format(r.reason))
if 'error' in r.json():
raise self.BitbucketAPIError('BitbucketAPIError: {}'.format(r.json()['error']['message']))
except HTTPError as e:
print("HTTP Error: {}".format(e))
except ConnectTimeout as e:
print("The request timed out while trying to connect to the remote server: {}".format(e))
except ConnectionError as e:
print("Connection Error: {}".format(e))
except Timeout as e:
print("Connection Timed out: {}".format(e))
except RequestException as e:
print("Unhandled exception: {}".format(e))
这里是同步客户端的简化版本 "croned":
bapi = BitbucketApi(username, password)
# blah blah blah
update_members()
update_repository()
bapi.close()
这里是关闭方法:
def close(self):
self._bitbucket_session.close()
可能涉及代理。
从你家运行脚本时没有代理,或者代理配置正确,所以没有问题。
当 运行 从您办公室的命令行中正确配置 shell 环境以通过环境变量设置 HTTP/S 代理时:
export http_proxy="http://proxy.com:3128"
export https_proxy="https://proxy.com:3128"
(大写变量也有效,即HTTP_PROXY、HTTPS_PROXY)
但是,当脚本来自 cron
运行 时,环境没有设置代理变量,连接请求超时。您为脚本创建一个包装器,然后从 cron 执行包装器脚本。例如
#!/bin/sh
export HTTP_PROXY="http://proxy:1234"
export HTTPS_PROXY="https://proxy:1234"
python your_script.py