で並列 http 要求タスクを実行したいのですが、それでは のイベント ループがブロックasyncio
されることがわかりました。aiohttpを見つけましたが、http プロキシを使用して http リクエストのサービスを提供できませんでした。python-requests
asyncio
を使用して非同期の http 要求を行う方法があるかどうかを知りたいですasyncio
。
で並列 http 要求タスクを実行したいのですが、それでは のイベント ループがブロックasyncio
されることがわかりました。aiohttpを見つけましたが、http プロキシを使用して http リクエストのサービスを提供できませんでした。python-requests
asyncio
を使用して非同期の http 要求を行う方法があるかどうかを知りたいですasyncio
。
asyncio でリクエスト (またはその他のブロッキング ライブラリ) を使用するには、 BaseEventLoop.run_in_executorを使用して別のスレッドで関数を実行し、そこから生成して結果を取得できます。例えば:
import asyncio
import requests
@asyncio.coroutine
def main():
loop = asyncio.get_event_loop()
future1 = loop.run_in_executor(None, requests.get, 'http://www.google.com')
future2 = loop.run_in_executor(None, requests.get, 'http://www.google.co.uk')
response1 = yield from future1
response2 = yield from future2
print(response1.text)
print(response2.text)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
これにより、両方の応答が並行して取得されます。
await
Python 3.5 では、新しい/async
構文を使用できます。
import asyncio
import requests
async def main():
loop = asyncio.get_event_loop()
future1 = loop.run_in_executor(None, requests.get, 'http://www.google.com')
future2 = loop.run_in_executor(None, requests.get, 'http://www.google.co.uk')
response1 = await future1
response2 = await future2
print(response1.text)
print(response2.text)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
詳細については、 PEP0492を参照してください。
aiohttpはすでに HTTP プロキシで使用できます。
import asyncio
import aiohttp
@asyncio.coroutine
def do_request():
proxy_url = 'http://localhost:8118' # your proxy address
response = yield from aiohttp.request(
'GET', 'http://google.com',
proxy=proxy_url,
)
return response
loop = asyncio.get_event_loop()
loop.run_until_complete(do_request())
Requests は現在サポートasyncio
されておらず、そのようなサポートを提供する予定もありません。を使用する方法を知っているカスタム「トランスポート アダプター」 (ここで説明したように) を実装できる可能性がありますasyncio
。
時間があれば実際に調べてみるかもしれませんが、約束はできません。
免責事項:Following code creates different threads for each function.
これは、使用が簡単なため、一部のケースで役立つ場合があります。ただし、非同期ではなく、複数のスレッドを使用して非同期の錯覚を与えることを知っておいてください。
関数をブロックしないようにするには、デコレータをコピーして、コールバック関数をパラメータとして任意の関数をデコレートします。コールバック関数は、関数から返されたデータを受け取ります。
import asyncio
import requests
def run_async(callback):
def inner(func):
def wrapper(*args, **kwargs):
def __exec():
out = func(*args, **kwargs)
callback(out)
return out
return asyncio.get_event_loop().run_in_executor(None, __exec)
return wrapper
return inner
def _callback(*args):
print(args)
# Must provide a callback function, callback func will be executed after the func completes execution !!
@run_async(_callback)
def get(url):
return requests.get(url)
get("https://google.com")
print("Non blocking code ran !!")