WebAPI 呼出しと Callback (P)

Web API 呼出し

こちらで紹介した Uplink は コルーチン対応の AiohttpClient を使うことで、コルーチンとして使えるようになります。

プログラムは dict 版とクラス(pydantic)版の2つを準備していますが、あまり差はないので dict 版をつかって説明していきます。

変更点

  • class CalendarService の変更
    • 実はあまり変更なしです。メソッド2つに async を付けただけ
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 不可。
# 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)