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

雑記帳

ソフトを中心に雑記を書いてる割とすぐ転職したい28歳。

RedmineのREST APIをPythonで弄る

Python プログラミング

今働いている部署でもバグトラッキングシステムを入れた方が良いよねと思って早2年。 結局そういう機会にあまり恵まれずほったらかしでした。 最近、機会がありそうな雰囲気になったのと、社外に出たとしても役に立つだろうし勉強しとくか、と思って家でモニョモニョ弄り始めた次第です。

数日間ダラダラ弄ってようやく動かし方が分かったので備忘録的に書いておきます。*1

とりあえずチケットの登録が出来れば良いやと思っていたので、そこまでしかやってませんが、 基本的には同じと思います。

PythonistaならTrac使えよ!っていうツッコミがあるかもだけどそこは気にしない方向で。。。 最近職場で使ってるのはTracなんだけど、今の職場での運用を考えると、UIがこなれてるし、日本語情報が多いし、 コミュニティはこっちのが活発だし、見た目が良いしということで、Redmineの方が良いのかもと思ったからそうする予定です。
それなのになんでPythonで弄ってるかって?残念ながら私がまだRubyをうまく使えないからです。

ではやってみよう!!

環境

だってDBの準備とかめんどいじゃん。

サンプルを動かす

ググればそれなりに情報はごちゃごちゃ出てくるけど、まずはRedmineの公式ページに載ってるサンプルを試してみる。

1. Python library example

これはpyredmineというライブラリの使い方サンプルのご様子。 早速インストールをば。。。

(env33) C:\Users\ore\Desktop\redmine-py>pip install pyredmine

とコマンドを打ってみると。。。

Downloading/unpacking pyredmine
  Downloading pyredmine-0.2.4.tar.gz
  Running setup.py egg_info for package pyredmine

Installing collected packages: pyredmine
  Running setup.py install for pyredmine
      File "C:\Users\ore\Desktop\redmine-py\env33\Lib\site-packages\red
mine\redmine_rest.py", line 427
        except urllib2.HTTPError, e:
                                ^
    SyntaxError: invalid syntax


Successfully installed pyredmine

ということでイキナリpipに怒られました。
urllbi2とか書いてあるし、残念ながら実装がpython2.x系のようです。 出来るだけpython3.x系を良く使うようにしている私には何とも受け入れづらい事実。 2to3とかで移植するのも出来るかもだけど、目的が変わってしまうのでここはスルー。

2. PyActiveResource example

さて、もう一個のサンプルもやってみる。
これはPyActiveResourceというライブラリが必要なようだ。

(env33) C:\Users\ore\Desktop\redmine-py>pip install pyactiveresource

とすると、、、

Downloading/unpacking pyactiveresource
  Downloading pyactiveresource-1.0.2.tar.gz
  Running setup.py egg_info for package pyactiveresource

Installing collected packages: pyactiveresource
  Running setup.py install for pyactiveresource
      File "C:\Users\ore\Desktop\redmine-py\env33\Lib\site-packages\pya
ctiveresource\activeresource.py", line 784
        except connection.ResourceInvalid, err:
                                         ^
    SyntaxError: invalid syntax

      File "C:\Users\ore\Desktop\redmine-py\env33\Lib\site-packages\pya
ctiveresource\connection.py", line 286
        except urllib2.HTTPError, err:
                                ^
    SyntaxError: invalid syntax

      File "C:\Users\ore\Desktop\redmine-py\env33\Lib\site-packages\pya
ctiveresource\formats.py", line 33
        except util.Error, err:
                         ^
    SyntaxError: invalid syntax

      File "C:\Users\ore\Desktop\redmine-py\env33\Lib\site-packages\pya
ctiveresource\util.py", line 332
        except Exception, err:
                        ^
    SyntaxError: invalid syntax


Successfully installed pyactiveresource
Cleaning up...

こっちも駄目じゃん。
ということで今のサンプルはpython3では使えないことが分かりました。


自分で頑張る

仕方が無いのでRedmine向けのライブラリには頼らずに書く方法は無いかな?と探してたらどこぞの記述でRequestsというライブラリが見つかった。
結果的には普通にurllibを使っても出来たけど、urllibは何度やってもイマイチ私の頭には入らないのでrequestsを使う方がうまくやっていけそうだ。

とりあえず下のようなコードで動きます。

# -*- coding: utf-8 -*-
import json
import requests


class RedmineSender():
    def __init__(self):
        self.POSTData = {}
        self.REDMINE_API_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
        self.REDMINE_HOST = 'http://localhost/redmine/issues.json'
        self.POST_HEADER = {
            'Content-Type': 'application/json',
            'X-Redmine-API-Key': self.REDMINE_API_KEY
        }

    def setMessage(self, payload):
        self.POSTData = json.dumps(payload)
        print(self.POSTData)

    def post(self):
        url = self.REDMINE_HOST+'?format=json'
        r = requests.request('POST', url, data=self.POSTData, headers=self.POST_HEADER)
        print(r)


if __name__ == '__main__':
    f_in = open("sample.json", "r", encoding='utf-8')
    dat = json.load(f_in)
    f_in.close()

    rsender = RedmineSender()
    rsender.setMessage(dat)
    rsender.post()

REDMINE_API_KEYは 左上 の [管理] -> [設定] の [RESTによるWebサービスを有効にする] にチェックを入れてから、 画面右上 の[個人設定]のページにある APIアクセスキー をコピーしてくれば良い。
色んな説明ページを見て回って記載はあったけどここでかなり困った。
どうしてこんなUIになったのか。

追) 読み込んだjsonファイルの形式を書いていなかったので書いておく

{
    "issue" : {
        "project_id" : "sampleproject",
        "subject" : "あなたはそこにいますか?",
        "status_id" : "1",
        "description" : "わたしはここにいます",
        "priority_id" : 1,
        "custom_fields" : [
            { "id":1,"value":"test input"},
            { "id":2,"value":"99876"},
            { "id":3,"value":"さしすせそ"}
        ]
    }
}

*1:数日も掛かったのはRedmineのバグが原因だった。たった4日しかリリースしかない不具合引っかかるとは。。。 issue15427