Модуль запросов Python прост и элегантен, но меня беспокоит одна вещь. Возможно получить request.exception.ConnectionError с сообщением как:
Max retries exceeded with url: ...
Это означает, что запросы могут пытаться получить доступ к данным несколько раз. Но нигде в документации нет ни одного упоминания об этой возможности. Глядя на исходный код, я не нашел места, где я мог бы изменить значение по умолчанию (предположительно 0).
Так можно ли как-то установить максимальное количество повторов для запросов?
python
python-requests
Кирилл Зайцев
источник
источник
requests.get(url, max_retries=num_max_retries, dely_between_retries=3))
just.get
иjust.post
на github.com/kootenpv/justОтветы:
Это основная
urllib3
библиотека, которая выполняет повторную попытку. Чтобы установить другое максимальное число повторов, используйте альтернативные транспортные адаптеры :max_retries
Аргумент принимает целое число илиRetry()
объект ; последний дает вам детальный контроль над тем, какие виды сбоев повторяются (целочисленное значение превращается вRetry()
экземпляр, который обрабатывает только сбои соединения; ошибки после установления соединения по умолчанию не обрабатываются, так как это может привести к побочным эффектам) ,Старый ответ, предшествующий выпуску запросов 1.2.1 :
requests
Библиотека не реально сделать это настраивается, а также не намерено (см этого запроса тянуть ). В настоящее время (запросы 1.1) счетчик попыток установлен на 0. Если вы действительно хотите установить его на более высокое значение, вам придется установить это глобально:Эта константа не задокументирована; используйте его на свой страх и риск, так как будущие выпуски могут изменить способ обработки.
Обновление : и это сделало изменения; в версии 1.2.1 была добавлена опция для установки
max_retries
параметра вHTTPAdapter()
классе , так что теперь вам нужно использовать альтернативные транспортные адаптеры, см. выше. Подход monkey-patch больше не работает, если только вы не исправляетеHTTPAdapter.__init__()
значения по умолчанию (очень не рекомендуется).источник
session.mount('http://', HTTPAdapter(max_retries=10))
это будет работать для всех подключений http. То же самое с https будет работать для всех соединений https.http://
иhttps://
используйте минимальные префиксы, см. документацию, на которую ссылается ответ.HTTPAdapter(max_retries=5)
будет работать только для определенного сценария. Из запросов doc ,Note, this applies only to failed DNS lookups, socket connections and connection timeouts, never to requests where data has made it to the server. By default, Requests does not retry failed connections.
чтобы принудительно повторить попытку для любых кодов состояния, см. Ответ @ datashaman ниже.Retry()
изменение сценариев сбоя.Это не только изменит max_retries, но также включит стратегию отката, которая переводит запросы ко всем адресам http: // на некоторое время перед повторной попыткой (в общей сложности 5 раз):
Согласно документации для
Retry
: если backoff_factor равен 0,1 , то sleep () будет бездействовать в течение [0,1 с, 0,2 с, 0,4 с, ...] между повторными попытками. Также будет произведена повторная попытка, если возвращен код состояния 500 , 502 , 503 или 504 .Различные другие опции
Retry
для более детального контроля:MaxRetryError
или вернуть ответ с кодом ответа в диапазоне 3хх .NB : повышение_он_стата является относительно новым и еще не превратило его в выпуск urllib3 или запросов.Raise_on_status аргумент ключевого словакажется, сделали это в стандартную библиотеку наиболее питон версии 3.6.Чтобы повторять запросы на определенные коды состояния HTTP, используйте status_forcelist . Например, status_forcelist = [503] будет повторять попытку с кодом состояния 503 (услуга недоступна).
По умолчанию повтор запускается только для следующих условий:
TimeoutError
HTTPException
поднял (из http.client в Python 3 еще httplib ). Похоже, это низкоуровневые исключения HTTP, например, неправильно сформированный URL или протокол.SocketError
ProtocolError
Обратите внимание, что все это исключения, которые препятствуют получению регулярного ответа HTTP. Если генерируется какой-либо регулярный ответ, повтор не выполняется. Без использования status_forcelist даже ответ со статусом 500 не будет повторен.
Чтобы заставить его вести себя более интуитивно понятным для работы с удаленным API или веб-сервером, я бы использовал приведенный выше фрагмент кода, который вызывает повторные попытки для статусов 500 , 502 , 503 и 504 , которые все нередки на сеть и (возможно) восстанавливаемый, учитывая достаточно большой период отсрочки.
Отредактировано : импортировать
Retry
класс напрямую из urllib3 .источник
Будьте осторожны, ответ Martijn Pieters не подходит для версии 1.2.1+. Вы не можете установить его глобально без исправления библиотеки.
Вы можете сделать это вместо этого:
источник
Немного поразмыслив с некоторыми ответами, я нашел библиотеку под названием backoff, которая лучше подойдет для моей ситуации. Основной пример:
Я бы по-прежнему рекомендовал дать толчок нативной функциональности библиотеки, но если у вас возникнут какие-либо проблемы или вам понадобится более широкий контроль, то откат - вариант.
источник
requests
, так что это прекрасно работает!Более чистый способ получить более высокий контроль может состоять в том, чтобы упаковать содержимое повторов в функцию и сделать эту функцию повторяемой с помощью декоратора и внести исключения в белый список.
Я создал то же самое здесь: http://www.praddy.in/retry-decorator-whitelisted-exceptions/
Воспроизведение кода по этой ссылке:
источник