GitHubじゃ!Pythonじゃ!

GitHubからPython関係の優良リポジトリを探したかったのじゃー、でも英語は出来ないから日本語で読むのじゃー、英語社会世知辛いのじゃー

ross

requests-futures – 先物を使用する人間に対する非同期Python HTTP要求

投稿日:

先物を使用する人間に対する非同期Python HTTP要求

人間に対する非同期Python HTTPリクエスト

Pythonの小さなアドオン httpライブラリをリクエストします。 Python 3.2のconcurrent.futuresまたは以前のバージョンのpythonのバックポートを使用します。

追加のAPIと変更は最小限であり、驚きを避けるために努力しています。

次の同期コード:

from requests import Session

session = Session()
# first requests starts and blocks until finished
response_one = session.get('http://httpbin.org/get')
# second request starts once first is finished
response_two = session.get('http://httpbin.org/get?foo=bar')
# both requests are complete
print('response one status: {0}'.format(response_one.status_code))
print(response_one.content)
print('response two status: {0}'.format(response_two.status_code))
print(response_two.content)

未来を利用するために翻訳することができます。したがって、FuturesSessionを作成し、Responseの代わりに返されたFutureをキャッチすることによって非同期にすることができます。 レスポンスは、Futureメソッドを呼び出すことで取得できます。

from requests_futures.sessions import FuturesSession

session = FuturesSession()
# first request is started in background
future_one = session.get('http://httpbin.org/get')
# second requests is started immediately
future_two = session.get('http://httpbin.org/get?foo=bar')
# wait for the first request to complete, if it hasn't already
response_one = future_one.result()
print('response one status: {0}'.format(response_one.status_code))
print(response_one.content)
# wait for the second request to complete, if it hasn't already
response_two = future_two.result()
print('response two status: {0}'.format(response_two.status_code))
print(response_two.content)

デフォルトでは、ThreadPoolExecutorは2人のワーカーで作成されます。 その値を調整したり、複数のセッションにまたがってエグゼキュータを共有したい場合は、FuturesSessionコンストラクタに値を渡すことができます。

from concurrent.futures import ThreadPoolExecutor
from requests_futures.sessions import FuturesSession

session = FuturesSession(executor=ThreadPoolExecutor(max_workers=10))
# ...

労働者数を増やす場合のショートカットとして、max_workersをFuturesSessionコンストラクタに直接渡すことができます:

from requests_futures.sessions import FuturesSession
session = FuturesSession(max_workers=10)

FutureSessionは既存のセッションオブジェクトを使用します。

from requests import session
from requests_futures.sessions import FuturesSession
my_session = session()
future_session = FuturesSession(session=my_session)

それでおしまい。 要求のAPI。セッションは、レスポンスではなく未来​​を返す以外の変更なしに保持されます。 すべての先物の例外と同様にfuture.result()コールに移動(スロー)されるのでtry / exceptブロックをそこに移動する必要があります。

キューに入れられたリクエストをキャンセルする(別名で自分自身をクリーンアップする)

まだ解決されていない先物から追加の返答が必要ないことがわかっている場合は、それらのリクエストをキャンセルすることをお勧めします。 これを行うには、セッションをコンテキストマネージャーとして使用します。

from requests_futures.sessions import FuturesSession
with FuturesSession(max_workers=1) as session:
    future = session.get('https://httpbin.org/get')
    future2 = session.get('https://httpbin.org/delay/10')
    future3 = session.get('https://httpbin.org/delay/10')
    response = future.result()

この例では、2番目または3番目の要求はスキップされ、時間とリソースが節約されます。

バックグラウンドでの作業

さまざまなリクエスト関数background_callbackには、バックグラウンドスレッドでResponseオブジェクトを操作するための追加パラメータが1つあります。 これは、単純な例としてjson解析を行うために、フォアグラウンドから作業をシフトするのに便利です。

from pprint import pprint
from requests_futures.sessions import FuturesSession

session = FuturesSession()

def bg_cb(sess, resp):
    # parse the json storing the result on the response object
    resp.data = resp.json()

future = session.get('http://httpbin.org/get', background_callback=bg_cb)
# do some other stuff, send some more requests while this one works
response = future.result()
print('response status {0}'.format(response.status_code))
# data will have been attached to the response object in the background
pprint(response.data)

ProcessPoolExecutorの使用

ThreadPoolExecutorと同様に、ProcessPoolExecutorのインスタンスを使用することもできます。 名前が示すように、リクエストはスレッドではなく別々のプロセスで同時に実行されます。

from concurrent.futures import ProcessPoolExecutor
from requests_futures.sessions import FuturesSession

session = FuturesSession(executor=ProcessPoolExecutor(max_workers=10))
# ... use as before

ヒント

ProcessPoolExecutorを使用すると、要求ごとのメモリ使用量が非常に高く(応答が大)、メモリーをOSに戻すためにインタープリタをサイクリングする必要がある場合に便利です。

ProcessPoolExecutorを使用する基本的な要件は、Session.request、FutureSession、および(オプションの)background_callbackがすべてpickle可能であることです。

つまり、Python 3.5のみが完全にサポートされていますが、Python 3.4以降ではFutureSessionの初期化時に渡される既存のrequests.Sessionインスタンスが必要です。 Python 2.Xおよび<3.4は現在サポートされていません。

# Using python 3.4
from concurrent.futures import ProcessPoolExecutor
from requests import Session
from requests_futures.sessions import FuturesSession

session = FuturesSession(executor=ProcessPoolExecutor(max_workers=10),
                         session=Session())
# ... use as before

酸洗いに失敗した場合は、この文書を参照して例外が発生します。

# Using python 2.7
from concurrent.futures import ProcessPoolExecutor
from requests import Session
from requests_futures.sessions import FuturesSession

session = FuturesSession(executor=ProcessPoolExecutor(max_workers=10),
                         session=Session())
Traceback (most recent call last):
...
RuntimeError: Cannot pickle function. Refer to documentation: https://github.com/ross/requests-futures/#using-processpoolexecutor

重要

  • Python> = 3.4が必要
  • Pythonを使用する場合はセッションインスタンスが必要<3.5
  • FuturesSessionをサブクラス化する場合は、それをインポート可能(モジュール全体)にする必要があります。
  • background_callbackを使用している場合は、それもインポート可能でなければなりません(モジュール全体)

インストール

ピップインストールリクエスト – 先物







-ross

執筆者: