前回作ったプログラムですが、実行に10秒ほどかかっていて、これならブラウザで複数プロジェクトのボードを全部開いてまわってもたいして効率が変わらない感じです。
おそらく遅い原因はボード一覧の取得->ボード毎にリスト一覧の取得->リスト毎にカード一覧の取得という一連の流れの中で、毎回O(N)相当のhttpリクエストを投げてるところだろうと思います。なんとか早くする方法が無いかと思って調べてたんですが、trelloのAPIリファレンスのページを見てると、こういう複数リクエストをまとめて投げるAPIがありました。
https://developers.trello.com/advanced-reference/batch
これを使えばこのプログラムのhttpリクエストは次の3回までに減らすことができます。
- ボード一覧の取得
- ボード内のリスト一覧の取得
- 所定のリスト(WIPとかToDoとか)内のカード一覧の取得
さっそく、前回てきとーに作ったTrelloClientクラスにbatch_fetch関数を追加してみます。
class TrelloClient: def __init__(self, api_key, token): self.api_key=api_key self.token=token self.base_url="https://api.trello.com/1" def fetch(self, category, api, target_id, option=""): url='{}/{}/{}/{}?key={}&token={}{}'.format(self.base_url,category,target_id,api,self.api_key,self.token,option) with urllib.request.urlopen(url) as r: return json.loads(r.read().decode('utf-8')) def batch_fetch(self, category, api, target_ids, option=""): batch_url="" for target_id in target_ids: batch_url += "/{}/{}/{}/{},".format(category, id, api,option) batch_url=urllib.parse.quote(batch_url.rstrip(',')) url="{}/batch/?urls={}&key={}&token={}".format(self.base_url, batch_url, self.api_key, self.token) with urllib.request.urlopen(url) as r: return json.loads(r.read().decode('utf-8'))
これを使って全ボード内のリストの一覧を取得するとこんな感じのコードになります。
tc=TrelloClient(trello_api_key, trello_token) boards=tc.fetch(category="member", api="boards", target_id="me", option="&filter=open&fields=name") board_ids=[board['id'] for board in boards] lists=tc.batch_fetch(category="boards", api="lists", target_ids=board_ids, option="?filter=open&fields=name&fields=idBoard")
今の時点のコードはこんな感じになってます。
n_so5 / TaskReporter / commit / 7197ec9bb6da — Bitbucket
新旧バージョンで実行時間を比較してみると
elapsed time for first version = 1.22e+01 sec
elapsed time for second version = 1.32e+00 sec
10倍早くなってますね。