Кажется, что каждый необязательный параметр, который идет в send, также может быть установлен в сеансе (например, verify, stream и т. Д.). Кроме тайм-аута.
Можно ли изменить поведение так, чтобы тайм-аут объединялся с сеансом, как и все другие аргументы?
@ctheiss Привет, спасибо, что подняли этот вопрос!
Это то, что поднималось раньше, совсем недавно в # 1987, но также в # 1130 и # 1563 (весь этот год). Кеннет обычно не проявляет интереса к внесению этого изменения, ожидая, что это будет сделано с использованием транспортных адаптеров. Если вы хотите получить рекомендации относительно того, как это сделать, я рад помочь, но не думаю, что мы добавим timeout
в Session
.
Извините, мы ничем не можем помочь!
Спасибо за сверхбыстрый ответ. Мне нужно лучше разбираться в проблемах, так как те, которые вы упомянули, являются точными дубликатами!
Есть ли идея реализовать BaseAdapter
(или подкласс HTTPAdapter
), а затем связать подкласс с сеансом с помощью mount
? Это кажется странно трудоемким просто для реализации «тайм-аута по умолчанию» (учитывая, насколько удивительно просто все остальное находится в запросах).
Идея состоит в том, чтобы создать подкласс HTTPAdapter
. На самом деле это не очень трудоемко, но основная причина, по которой мы это делаем, заключается в том, что он сохраняет концептуальные различия в библиотеке. Объекты Session
должны строго управлять тем, что касается сеанса, а именно, как работает HTTP: файлы cookie, заголовки и т. Д. Транспортные адаптеры управляют вещами, касающимися работы сетевых соединений: сокетов, таймаутов и т. Д.
Чтобы уточнить, вы рекомендуете, чтобы люди это делали?
class MyHTTPAdapter(requests.adapters.HTTPAdapter):
def __init__(self, timeout=None, *args, **kwargs):
self.timeout = timeout
super(MyHTTPAdapter, self).__init__(*args, **kwargs)
def send(self, *args, **kwargs):
kwargs['timeout'] = self.timeout
return super(MyHTTPAdapter, self).send(*args, **kwargs)
s = requests.Session()
s.mount("http://", MyHTTPAdapter(timeout=10))
@staticshock это вариант. да
Но, более конкретно, это _рекомендация_?
Особых рекомендаций нет, потому что потребности пользователей будут разными, и для этих пользователей будет множество способов решить эту проблему.
@staticshock @ sigmavirus24
Это решение кажется слишком сложным. Мне кажется, что следующее работает.
s = requests.Session()
s.get_orig, s.get = s.get, functools.partial(s.get, timeout=3)
# this should now timeout
s.get('https://httpbin.org/delay/6')
# and this should succeed
s.get_orig('https://httpbin.org/delay/6')
@staticshock @ sigmavirus24
Это решение кажется слишком сложным. Мне кажется, что следующее работает.
s = requests.Session() s.get_orig, s.get = s.get, functools.partial(s.get, timeout=3) # this should now timeout s.get('https://httpbin.org/delay/6') # and this should succeed s.get_orig('https://httpbin.org/delay/6')
Обратите внимание, что вам также необходимо применить это к другим глаголам, например, post
, put
и т. Д., Если вы их используете. Для полноты картины я использую:
session = requests.Session()
for method in ('get', 'options', 'head', 'post', 'put', 'patch', 'delete'):
setattr(session, method, functools.partial(getattr(session, method), timeout=5))
# All methods of session should now timeout after 5 seconds
Почему бы просто не установить прокладку для метода request
?
s = requests.Session()
s.request = functools.partial(s.request, timeout=3)
# this should now timeout
s.get('https://httpbin.org/delay/6')
Если вам это нужно глобально на уровне модуля и вы не используете сеансы, вы потенциально можете сделать:
requests.api.request = functools.partial(requests.api.request, timeout=3)
Я не уверен, как это работает с использованием его в нескольких модулях, я полагаю, вам понадобится прокладка в каждом файле, где вы используете запросы.
Самый полезный комментарий
Почему бы просто не установить прокладку для метода
request
?