最近、ToDo管理はTrelloを使っています。WebのGUIは直感的に分かりやすい上、APIも提供されています。
Trello API用のPythonライブラリを探したところ、starの多いpy-trello
が気になりました。
py-trelloの使い方を調べてみたところ、Issueに
There is the main
README
, and there is documentation in the code itself. There are also unit tests which utilize the library.Outside of that, there is no Real Documentation (tm) as of now.
との記載がありました。
そこで、ソースコードとテストコードを読みながら、py-trelloを試してみました。
環境
- Windows10
- Python 3.5.1
- py-trello 0.4.3
共通
py-trelloからTrello APIを扱う際は、Clientオブジェクトを生成して使います。
client = TrelloClient(TRELLO_API_KEY, token=TRELLO_TOKEN)
ボードの操作
API Reference - board | Trello Developers
ボードの作成
created_board = client.add_board("APIで作ったボード")
なお、py-trelloでボードを作成した時の初期リストは、ToDo
・Doing
・Done
の3つでした。
lists = created_board.all_lists() for l in lists: print("list id: {}".format(l.id)) print("list name: {}".format(l.name.decode("utf-8"))) #=> # list id: xxx1 # list name: To Do # list id: xxx2 # list name: Doing # list id: xxx3 # list name: Done
ボードの一覧表示
boards = client.list_boards() for board in boards: print("board id: {id} {closed}".format( id=board.id, closed="(Closed)" if board.closed else "")) print("board name: {}".format(board.name.decode("utf-8")))
注意点は以下の通りです。
- Clientオブジェクトの
list_boards()
はcloseしたボードも取得 - Boardオブジェクトの
name
にはバイト列が入っているため、以下を参考にしてデコードする必要あり
ボードのアーカイブ
created_board.close()
リストの操作
API Reference - list | Trello Developers
リストの作成
board = client.get_board(BOARD_ID)
created_list = board.add_list("APIで作ったリスト")
リストの一覧表示
lists = board.all_lists() for l in lists: print("list id: {id} {closed}".format( id=l.id, closed="(Closed)" if l.closed else "")) print("list name: {}".format(l.name.decode("utf-8")))
注意点は以下の通りです。
- Boardオブジェクトの
all_lists()
はアーカイブしたリストも表示 - Listオブジェクトの
name
もバイト列であるため、デコードする必要あり
リストのアーカイブ
created_list.close()
カードの操作
API Reference - card | Trello Developers
カードの追加
board > list の順で対象のリストを取得し、そのリストにカードを追加する流れになります。
board = client.get_board(BOARD_ID)
target_list = board.get_list(LIST_ID)
created_card = target_list.add_card("APIで作ったカード")
カードの一覧表示
アーカイブしたカードは表示されません。
cards = target_list.list_cards() for c in cards: print("card id: {}".format(c.id)) print("card name: {}".format(c.name.decode("utf-8")))
カードのアーカイブ
created_card.set_closed(True)
カードの削除
TrelloのGUIと異なり、アーカイブしていないカードでも削除できます。
created_card.delete()
カード上のコメント操作
コメントの削除はpy-trelloでは用意されていないようなので、コメントの追加と一覧表示の操作を試してみます。
コメントの追加
card = client.get_card(CARD_ID)
card.comment(datetime.now().strftime("%Y/%m/%d %H:%M:%S"))
コメントの一覧表示
コメントは辞書として格納されていることに注意します。
comments = card.get_comments() for i, c in enumerate(comments): print("comment No{no}: {comment}".format( no=i, comment=c["data"]["text"]))
カード上の添付ファイル操作
APIからファイルを添付する方法の詳細が分からず悩んでいたところ、以下が参考になりました。
Simple python script to upload a file to Trello.
次のコードは、ローカルにあるattachment.txt
ファイルをattach1.txt
というファイル名でカードへ添付します。
card = client.get_card(CARD_ID) text_file_path = os.path.join(path, "attachment.txt") text_file = open(text_file_path, "rb") card.attach(name="attach1.txt", file=text_file)
ただ、attach()
の引数name
に日本語を指定したところ、Upload
という拡張子なしのファイル名になりました。
対処方法を以下を参考にいろいろと調べてみたものの、奥深そうだったので今回は深追いしませんでした。
- encoding - how to utf-8 encode the file name with uploading the file content in multi part post - Stack Overflow
- HTTP/1.1: Appendices - RFC 2616 Fielding, et al.
- Can't set headers per part of multipart requests · Issue #1495 · kennethreitz/requests
- pythonのrequestsでmultipart/form-data送信 - Qiita
ちなみに、他のTrelloライブラリではどうだろうと思い、Trolly
で試してみました。
plish/Trolly
実装はこんな感じです。
text_file_path = os.path.join(path, "attachment.txt") f = open(text_file_path, 'rb').read() card.add_attachment('日本語.txt', f)
結果は、
- 半角英数のファイル名 > OK
- 日本語のファイル名 >
latin-1' codec can't encode characters
エラーが発生し、アップロードできず
でした。
カード上のチェックリスト操作
チェックリストの追加
以下の例では、2項目を持つチェックリストを作成します。
card = client.get_card(CARD_ID) created_checklist = card.add_checklist("APIで作ったチェックリスト", ["アイテム1", "item2"])
チェックリストの一覧表示
Cardオブジェクトのfetch()
メソッドを使うことで、Cardオブジェクトに紐づくChecklistを利用できるようになりました。
card.fetch() for checklist in card.checklists: print("Checklist id:{id} / name: {name}".format( id=checklist.id, name=checklist.name)) for i, item in enumerate(checklist.items): print("Item - index:{index} / id: {id} / name: {name} / checked: {checked}".format( index=i, id=item["id"], name=item["name"], checked=item["checked"]))
チェックリストの削除
created_checklist.delete()
チェックリストの項目にチェックを入れる
created_checklist.set_checklist_item("アイテム1", True)
Trello APIのみの機能を利用
Trello APIには存在するがpy-trelloでは実装されていない機能もあります。
その場合、Clientオブジェクトのfetch_json()
メソッドにより、py-trello経由でAPIを使うことができます。
例えば、コメントの削除はTrello APIにあるものの、py-trelloでは実装されていません。
API Reference - card DELETE | Trello Developers
そのため、
card = client.get_card(CARD_ID) last_comment = card.get_comments()[-1] client.fetch_json( "/cards/{card_id}/actions/{comment_id}/comments".format( card_id=card.id, comment_id=last_comment["id"] ), http_method="DELETE")
とすれば、一番最後のコメントを削除することができます。
なお、Trello APIのドキュメントにあったidActions
については、以下が参考になりました。
その他
Webhook APIとか気になるものもありましたが、今のところ手元では使い道が思いつかないため、今回は試しませんでした。
Trelloに「Webhook API」というのがあったのか(単なる雑記) - Qiita
ソースコード
GitHubに上げました。
thinkAmi-sandbox/py-trello_sample