読者です 読者をやめる 読者になる 読者になる

Python + py-trelloで、Trello APIを使ってみた

Python Trello

最近、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.

Documentation · Issue #112 · sarumont/py-trello

との記載がありました。

 
そこで、ソースコードとテストコードを読みながら、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でボードを作成した時の初期リストは、ToDoDoingDoneの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")))

注意点は以下の通りです。

 

ボードのアーカイブ
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という拡張子なしのファイル名になりました。

対処方法を以下を参考にいろいろと調べてみたものの、奥深そうだったので今回は深追いしませんでした。

 
ちなみに、他の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

 

その他参考

Pythonスクリプトを作る上で、参考になったところを残しておきます。