WebAPI 呼出しと Callback (P)
Web API 呼出し
こちらで紹介した Uplink は コルーチン対応の AiohttpClient
を使うことで、コルーチンとして使えるようになります。
プログラムは dict 版とクラス(pydantic)版の2つを準備していますが、あまり差はないので dict 版をつかって説明していきます。
変更点
class CalendarService
の変更- 実はあまり変更なしです。メソッド2つに
async
を付けただけ
- 実はあまり変更なしです。メソッド2つに
class CalendarService(Consumer): # カレンダー共有サービスの定義
"""A Python Client for the GitHub API."""
@returns.json() # 「結果 JSON だから dict にしてね」の指定
@get('public.json') # path の指定
async def get_users(self): # method 宣言 (self は service.get_users() の service 相当
"""Get a user list.""" # 定義部はライブラリが自動対応
@returns.json()
@get('events/{user_id}.json') # path の指定、引数 user_id が {user_id} に埋め込まれる
async def get_events(self, user_id): # method 宣言 (service.get_events(user_id) って感じで利用)
"""Get an event list of the given user.""" # 定義部はライブラリが自動対応
ClassService
オブジェクトの生成- 引数に
client=AiohttpClient()
を追加 - ClassService の作成は コルーチン外でおこない、コルーチンの稼働も
event_loop
を使う
- 引数に
service = CalendarService(base_url='...',
client=AiohttpClient())
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(request_sample())
- 同期呼出しっぽい呼出しは、これで OK
- await 部分で、別コルーチンにスイッチすることは可能
dct = await service.get_users()
future と callback
- future っぽいのはこんな感じ
- 二つのユーザのカレンダーを並行問合せ
task_a = asyncio.create_task(service.get_events(user_a))
task_k = asyncio.create_task(service.get_events(user_k))
resp_a = await task_a
resp_k = await task_k
print('resp for ', user_a, resp_a)
print('resp for ', user_k, resp_k)
- callback は task に対して指定すると、問い合わせ完了時に実行してくれる。
- 引数に Task を取るので、
arg.result()
で問合せ結果を使った処理が可能 - callback は await 不可。
- 引数に Task を取るので、
# callback 定義
def callback0(arg: asyncio.Task):
print("callback called. result > ", arg.result())
# 呼出し側
task_k = asyncio.create_task(service.get_events(user_k))
task_k.add_done_callback(callback0)