web-dev-qa-db-ja.com

Pythonのリクエストライブラリのセッションオブジェクトはスレッドセーフですか?

Pythonの人気のある Requests ライブラリは、そのホームページではスレッドセーフであると言われていますが、それ以上の詳細は提供されていません。 requests.session()を呼び出すと、このオブジェクトを安全に複数のスレッドに渡すことができますか?

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

複数のスレッドで同じ接続プールを使用してリクエストを作成しますか?

もしそうなら、これは推奨されるアプローチですか、それとも各スレッドに独自の接続プールを与える必要がありますか? (個々の接続プールすべての合計サイズを合計すると、上記のような1つの大きな接続プールのサイズになると仮定します。)各アプローチの長所と短所は何ですか。

43
DJG

requests.session のソースを確認した後、使用しているCookieJarの実装によっては、セッションオブジェクトがスレッドセーフである可能性があると言います。

Session.prepare_requestself.cookiesから読み取り、Session.sendextract_cookies_to_jar(self.cookies, ...)を呼び出し、jar.extract_cookies(...)を呼び出します(この場合、jarself.cookiesです)。

Python 2.7のcookielib のソースは、jarの更新中にロック(threading.RLock)を取得するため、スレッドセーフであるように見えます。一方、 cookielibのドキュメント はスレッドセーフについて何も述べていないため、この機能に依存すべきではないでしょうか。

更新

スレッドがheadersproxiesstreamなどのセッションオブジェクトの属性を変更している場合、またはmountメソッドを呼び出すか、セッションを使用している場合withステートメントなどでは、スレッドセーフではありません。

22
millerdev

https://github.com/kennethreitz/requests/issues/1871 は、セッションがスレッドセーフではなく、少なくとも1人のメンテナがスレッドごとに1つのセッションを推奨することを意味します。

ドキュメントを明確にするために https://github.com/kennethreitz/requests/issues/2766 を開きました。

22
Greg Ward