В Python запросы/urllib3 NewConnectionError только когда скрипт работает по расписанию из офиса


Странная проблема, которую я не могу понять.

У меня есть скрипт, который использует библиотеку запросов Python и запускается на cronjob. Когда я нахожусь дома через VPN, это работает нормально.

Если я нахожусь в офисе, cronjob возвращает ошибку соединения, более конкретно NewConnectionError[ошибка 60: время ожидания соединения] (которая вызывается urllib3). Самое странное, что если я запускаю скрипт вручную из командной строки, у него нет проблем.

У меня есть только высокоуровневое понимание того, как запросы / urllib3 / cron работает. Я предполагаю, что соединение каким-то образом кэшируется, но я не уверен. Кто-нибудь знает, что может быть причиной этого?

Сам скрипт-это утилита синхронизации, которая создает соединение с api bitbucket. Для этого я создал api-оболочку, которая по сути является просто объектом для построения запросов. Вот фрагмент из обертки:
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()
1 3

1 ответ:

Вероятно, здесь замешан посредник.

Когда скрипт запускается из вашего дома, прокси нет, или прокси настроен правильно, так что нет никаких проблем.

При запуске из командной строки в вашем офисе среда оболочки правильно настроена для установки 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