Является ли объект сеанса из библиотеки запросов Python потокобезопасным?

Популярная библиотека Python Requests на своей домашней странице считается поточно-ориентированной, но нет даны дальнейшие подробности. Если я вызываю requests.session(), могу ли я безопасно передать этот объект нескольким потокам, например:

session = requests.session()
for i in xrange(thread_count):
    threading.Thread(
        target=target,
        args=(session,),
        kwargs={}
    )

и делать запросы, используя один и тот же пул соединений в нескольких потоках?

Если да, то это рекомендуемый подход или каждому потоку должен быть предоставлен собственный пул соединений? (Предполагая, что общий размер всех отдельных пулов соединений в сумме равен размеру одного большого пула соединений, подобного приведенному выше.) Каковы плюсы и минусы каждого подхода?


person DJG    schedule 12.08.2013    source источник
comment
Вы выяснили, что лучше? В настоящее время я сталкиваюсь почти с тем же вопросом. Я думал о новом сеансе для каждого потока, чтобы не блокировать все запросы в одном пуле соединений.   -  person Marcel Wilson    schedule 06.11.2013
comment
@ Марсель Уилсон: Не совсем так. Хотя в одном из моих проектов, где я использовал объект сеанса для многократного запроса одного и того же URL-адреса, я отправил один и тот же объект сеанса всем потокам. Приложение, похоже, работает, но я все еще не уверен, какой подход лучше. Однако обратите внимание, что моя проблема заключалась не в том, чтобы создавать узкие места для пулов соединений, а в том, чтобы открывать слишком много соединений и отправлять слишком много запросов за раз.   -  person DJG    schedule 07.11.2013
comment
Запросы строятся поверх urllib3. Потоковая безопасность запросов во многом обусловлена ​​потокобезопасностью urllib3, в документации для которой более подробно обсуждается потокобезопасность.   -  person selllikesybok    schedule 20.11.2013
comment
@ dg123 В итоге я создал сеанс в цикле for. Каждый поток получает собственный пул соединений.   -  person Marcel Wilson    schedule 13.12.2013


Ответы (2)


Изучив источник requests.session, я скажу, что объект сеанса может быть потокобезопасный, в зависимости от используемой реализации CookieJar.

Session.prepare_request читает из self.cookies, а Session.send вызывает extract_cookies_to_jar(self.cookies, ...), и это вызывает jar.extract_cookies(...) (jar в данном случае self.cookies).

Источник для Python 2.7 cookielib получает блокировку (threading.RLock), пока он обновляет jar-файл, чтобы он выглядел поточно-ориентированным. С другой стороны, документация для cookielib ничего не говорит о безопасности потоков, поэтому, возможно, эта функция не должна зависеть от?

ОБНОВИТЬ

Если ваши потоки изменяют какие-либо атрибуты объекта сеанса, такие как headers, proxies, stream и т. Д., Или вызывают метод mount, или используют сеанс с оператором with и т. Д., Тогда это не является потокобезопасным.

person millerdev    schedule 08.12.2013
comment
Тем не менее, я полагаю, если вы сделаете my_session.get(url, headers={"something": "something"}) это не должно быть проблемой. - person PascalVKooten; 12.04.2020

https://github.com/psf/requests/issues/1871 подразумевает, что сеанс не является потокобезопасным, и хотя бы один сопровождающий рекомендует один сеанс для каждого потока.

Я только что открыл https://github.com/psf/requests/issues/2766 для уточнения документации.

person Greg Ward    schedule 10.09.2015
comment
Похоже, это зависит от urllib3 потоковой безопасности, что, я не думаю, основано на github .com / urllib3 / urllib3 / issues / 1252 - person Charles L.; 05.09.2019