PythonでRedmineのチケットを操作する
PythonからRedmineのチケットを操作(取得・更新・発行)してみました。
目次
Python Redmineモジュール
環境は、 Windows 10にインストールしたRedmine 4 とPython 3.7です。Redmineへのアクセスには、 Python-Redmineモジュール を使用します。
Python-Redmineモジュールは、Pipでインストールできます。
> pip install python-redmine
PythonからRedmineにアクセスする際にRedmineのREST APIインターフェースを使用します。このため、Redmineの側でREST APIインターフェースを有効にしておく必要があります。
また、APIでアクセスするためにAPIアクセスキーが必要になります。Redmineにログインして「個人設定」を開き、APIアクセスキーの欄の「表示」をクリックするとAPIアクセスキーが表示されます。
指定のプロジェクトのチケットを取得する
砂場という名前のプロジェクトのチケットを取得します。プロジェクトの名前は「砂場」ですが、識別子が「sunaba」になっていることに注意してください。
from redminelib import Redmine
import pprint
redmine = Redmine('http://localhost:3000', key='04xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx35')
project = redmine.project.get('sunaba')
print('Project properties :')
pprint.pprint(list(project))
print('Num of tickets : ', len(project.issues))
print('1st ticket properties :')
pprint.pprint(list(project.issues[0]))
出力
Project properties :
[('wiki_pages', None),
('memberships', None),
('issue_categories', None),
('time_entries', None),
('versions', None),
('news', None),
('issues', None),
('files', None),
('trackers', None),
('enabled_modules', None),
('time_entry_activities', None),
('id', 3),
('name', '砂場'),
('identifier', 'sunaba'),
('description', ''),
('homepage', ''),
('status', 1),
('is_public', False),
('created_on', '2019-10-12T04:32:49Z'),
('updated_on', '2019-10-12T04:32:49Z')]
Num of tickets : 4
1st ticket properties :
[('relations', None),
('time_entries', None),
('children', None),
('attachments', None),
('changesets', None),
('journals', None),
('watchers', None),
('id', 12),
('project', {'id': 3, 'name': '砂場'}),
('tracker', {'id': 3, 'name': 'サポート'}),
('status', {'id': 1, 'name': '新規'}),
('priority', {'id': 2, 'name': '通常'}),
('author', {'id': 5, 'name': 'test user'}),
('assigned_to', {'id': 5, 'name': 'test user'}),
('fixed_version', {'id': 3, 'name': 'リリース'}),
('subject', 'タスクD'),
('description', ''),
('start_date', '2019-10-31'),
('due_date', '2019-11-07'),
('done_ratio', 0),
('is_private', False),
('estimated_hours', None),
('created_on', '2019-10-19T11:18:47Z'),
('updated_on', '2019-10-19T11:18:47Z'),
('closed_on', None)]
Redmine.project.get()メソッドで得られるオブジェクトのissuesは、チケットを列挙するイテレーターになります。
ですから、issuesにインデックスを付ければ特定のチケットの情報を取得できますし、forループで全てのチケットにアクセスすることもできます。
では、「タスクB」という名前のチケットを取得して、チケットID、チケット名、ステータスID、ステータス名を表示してみます。
from redminelib import Redmine
redmine = Redmine('http://localhost:3000', key='04xxxxxxxxxxxxxxxxx35')
project = redmine.project.get('sunaba')
for i in project.issues:
if i.subject == 'タスクB':
print(i.id, i.subject, i.status.id, i.status.name)
break
出力
10 タスクB 1 新規
単純に特定のチケットを取得するだけでしたら、こちらの方が簡単かもしれませんね。
from redminelib import Redmine
redmine = Redmine('http://localhost:3000', key='04xxxxxxxxxxxxxxxxxxx35')
target_issue = redmine.project.get('sunaba').issues.filter(subject='タスクB')
print(target_issue[0].id, target_issue[0].subject, target_issue[0].status.id, target_issue[0].status.name)
出力
10 タスクB 1 新規
filterメソッドの戻りはセットになりますので、インデックスを付けてアクセスする必要があります。
チケットのタイトルで検索する場合は、同じ名前のチケットが登録されていないかどうか気をつけてください。
チケットを更新する
チケットのステータスを変更してみます。チケットの変更にはupdateメソッドを使用します。
from redminelib import Redmine
redmine = Redmine('http://localhost:3000', key='04xxxxxxxxxxxxxxxxxxx35')
redmine.project.get('sunaba').issues.filter(subject='タスクB').update(status_id=2)
チケットのステータスが「進行中」に切り替わりました。
新しいチケットを登録する
新しいチケットを登録してみます。newメソッドでチケットのオブジェクトを作って、そのオブジェクトのプロパティに必要な値を設定し、saveメソッドでRedmineに書き込みます。
チケットを追加する前の状態をガントチャートで表示するとこうなります。
では、追加してみます。
from redminelib import Redmine
import datetime
redmine = Redmine('http://localhost:3000', key='04xxxxxxxxxxxxxxxxxxx35')
new_issue = redmine.issue.new()
new_issue.project_id = 3
new_issue.tracker_id = 1
new_issue.status_id = 1
new_issue.assigned_to_id = 5
new_issue.fixed_version_id = 3
new_issue.subject = '新しいタスク'
new_issue.start_date = datetime.date(2019, 10, 15)
new_issue.due_date = datetime.date(2019, 11, 2)
new_issue.save()
プログラムからチケットを変更したり発行したりできるとなると、定型のチケットを発行する場合にスクリプトを使えばいちいちRedmineにログインする必要もなくなりますし、crontabなどで定期的にチケットを発行することが可能になりますね。
公開日
広告