Python3で動くBacklog API(v2) wrapper を作ってみた

自分の求めてるモノがなかったので、TDDへの入門も兼ねて作ってみました。~~まだまだAlpha版です。~~

(追記 2019.09.06) 一応Betaと呼べるくらいにはなりました。 `pip install python-backlog` で使用可能です。

PyPI https://pypi.org/project/python-backlog/

# 動機

自社ではSIer稼業をやっており、全社的にBacklogを使いまくっています。

お客様へヒアリングなどのシーンにおいて、ある程度雛形の決まったissueやwikiを一斉起票するユースケースがあり、そうした作業をもっと省力化できるなにかを探していました。

既存では[pybacklog](https://github.com/netmarkjp/pybacklog)という素晴らしいライブラリがあったのですが、wikiやattachmentのサポートが弱いこと、また最近のcommit logを見る限りそれほど活発に開発が行われていないことの2つがネックであり、ならばいっそ自分が使いやすいように一から作ってしまおうと思いました。

現在サポートする操作はissue関係とwiki関係を中心としています。今後拡大予定です。

将来的な構想は

```bash
# 完成形となるCLIインタフェースのイメージ（妄想）

# あるプロジェクト配下のwikiをリスト表示
backlog wiki ls --project xxx

# プロジェクトA配下のwikiをプロジェクトBに移行
backlog wiki cp backlog://project-A/* backlog://project-B/
```

といったようなコマンドラインインタフェースの提供をゴールとしています。

イメージする最終形はCLIツールですが、まずはAPIをラップするCore utilのような存在が必要でしたので、今回はそちらを作ってみたという次第です。

# ソースは？

つ https://github.com/hassaku63/backlog_util

名前がイケてないので、`backloglib` とかのレポジトリ名に変えて（ついでにリファクタリングして）別途公開予定です。PyPIには未登録です。メンテして、もうちょいAPIの守備範囲を増やしたらPyPIデビューする予定。

# 使い方

PyPI未登録なので、試してみたい場合にはgit経由でインストールします。もちろん `git clone` してローカルインストールでも可。

```bash
pip install git+git://github.com/hassaku63/backlog_util@<BRANCH_NAME>
```

[README]
(https://github.com/hassaku63/backlog_util/blob/master/README.md)にも書いていますが、認証情報を `conf.yml` に記載し、それをロードしてapi clientに引き渡すような形で利用します。

```python
from backlog.util import load_conf
from backlog.base import BacklogAPI

conf = load_conf("conf.yml")["backlog"]
api = BacklogAPI(conf["space"], conf["api_key"])
```

例えばwikiのリストが欲しい場合は以下のように書きます。

```python
import json

# list wikis
wikis = api.wiki.list("SampleProject")
print(json.dumps(wikis[0], indent=2))
```

API Clientオブジェクトの配下にBacklogリソースの名前空間があり、そのリソースに関連する操作、例えばwikiのリストは `backlog_client.wiki.list()` のように `wiki` のメソッド呼び出しとして利用します。パラメータの仕様はBacklogのAPIリファレンスに準拠します。

メソッドのdocstringには対応するBacklog APIのリファレンスのリンクを記述しておりますので、メソッドが要求するパラメータは確認可能です。ipythonなどのインタラクティブシェルでご確認ください。

サポートしていない操作はそもそもリソースが未定義であるか、もしくはメソッドが `NotImplemented` を吐いて落ちます。未実装の機能についても、一応は [backlog/base.py](https://github.com/hassaku63/backlog_util/blob/master/backlog/base.py)の `invoke_method` という仕組みで実行可能ですが、あくまで内部的に「操作」を正しいHTTP Requestに変換するプロキシ相当としての位置づけなので、ユーザーが直接使う想定はしていません。

# 実装の参考にしたもの

インタフェースの実装は、よくお世話になっている [Slacker - https://github.com/os/slacker](https://github.com/os/slacker) を作りを大いに参考にしました。前述のように、APIオブジェクトの下に対応するBacklogサービスのリソースが紐付いています。リソースに対する操作は、リソースオブジェクトのメソッドとして実行するスタイルになっています。

また、ユニットテストを書くにあたりBacklog APIのモックが必要でした。...が、ロクに経験がないため勝手がわからず。こちらも、割とよく利用機会のある[pyzabbix - https://github.com/lukecyca/pyzabbix](https://github.com/lukecyca/pyzabbix)での実装を全面的に参考にしつつなんとなく書いています。

# 注意
MacOS(or Linux) + Python3.6を前提としています。Python2.xでは動かないはずです。
Windowsも多分動きません。現状dockerかEC2のようなLinux環境で利用することに成るかと思います。Bash for windowsは、試してないのですが動く _かも_ しれません...。

# 今後やりたい

いろいろありますが、以下のようなことを考えています。

- サポートする操作の拡大
- 適切なレポジトリ名、パッケージ名にリネームして公開し直す。PyPIにも登録する
- 実際のBacklog環境を利用したテストケースを書く
- Windows対応
- Credentialを環境変数から読み込めるようにする
- テストケース書くのが作業的に面倒くさいので、コード量削減のためにヘルパー的なものを書く
- ライセンス明記する - 完全に忘れてました。Apacheあたりを適用します。レポジトリ移行した際に対応予定です
- ドキュメント書く - docstringを最低限書かなければ...。sphinxで生成したい

テストの書き方については、職場の先輩からGolangのネタを紹介いただいたのでこの設計を流用していきたいですね。必要なパラメータをかけば良い、というTable Driven Testの考え方は非常に有用そうです。

参考: https://medium.com/@timakin/go-api-testing-173b97fb23ec

# References

- [50分でわかるテスト駆動開発](https://channel9.msdn.com/Events/de-code/2017/DO03)
- [Pythonプロフェッショナルプログラミング第3版](http://amzn.asia/d/413BSdF) ... パッケージの作り方など
- [Slacker - https://github.com/os/slacker](https://github.com/os/slacker) ... インタフェース設計の参考
- [pyzabbix - https://github.com/lukecyca/pyzabbix](https://github.com/lukecyca/pyzabbix) ... httprettyを使ったユニットテストの外部APIモックの参考