プロジェクト管理ツールである Jira は、REST API を使って情報を取得できるようになっています。 ここでは、Python を使って Jira の情報を取得してみます。
jira パッケージのインストール
Python から JIRA の情報を取得するには、PyPI で公開されている jira パッケージ を使用すると簡単です(jira
パッケージ内部で REST API を使っています)。
jira パッケージの基本的な使い方
下記は、JIRA プロジェクトの一覧を取得する簡単な例です。 ユーザー ID やパスワードは適切なものに置き換えてください。
Jira Cloud サービスを使用している場合、パスワードをそのまま指定する方法は 非推奨になった ので、API トークンを発行してパスワードの代わりに指定します。
jira = JIRA(basic_auth=("email", "API token"))
ユーザー名やパスワードの代わりに、パーソナルアクセストークン (PAT) を使うときは次のようにします。
パーソナルアクセストークンを使う場合は、コード内でユーザー名を指定する必要はありません。
パーソナルアクセストークンは、Jira の右上のユーザーアイコンをクリックして、Profile
ページを開くと作成できます。
JIRA_SERVER = "https://<server>"
JIRA_TOKEN = "JiCI65qxea............省略............MzYzOn3Jv1"
jira = JIRA(JIRA_SERVER, token_auth=JIRA_TOKEN)
接続情報を環境変数で設定する
実用上は、Jira のアクセストークンは環境変数や .env
ファイルで設定 できるようにしておくのがよいです。
こうしておけば、CI 環境(GitHub Actions など)のシークレット変数としてトークンを設定できます。
次の config
モジュールでは、環境変数あるいは .env
ファイルで設定された JIRA_SERVER
変数と JIRA_TOKEN
変数の値を取得しています。
これらの変数が設定されていなければエラーを表示して終了します。
上記の config
モジュールを使うと、JIRA
インスタンスの生成部分は次のように簡潔に記述できます。
スニペット集
プロジェクト内のイシューをすべて取得する
issues = jira.search_issues("project = PROJECT_KEY")
for issue in issues:
print(f"{issue.key}:\t{issue.fields.summary}")
jira.search_issues()
はデフォルトで 50 件のイシュー情報を返します。
これ以上の情報をまとめて取得したいときは、maxResults
オプションを指定します。
多数のイシューをページング処理する
多数のイシューをまとめて処理する場合は、必要に応じて下記のようにページング処理します。
startAt
引数の値をずらしながら少しずつデータ取得していきます。
def process_issue(issue: Issue):
"""1 件のイシューを処理する"""
print(f"{issue.key}:\t{issue.fields.summary}")
def process_all_issues():
"""すべてのイシューを 100 件ずつ処理する"""
start_at = 0
MAX_RESULTS = 100
while True:
issues = jira.search_issues("project=PROJ", startAt=start_at, maxResults=MAX_RESULTS)
if len(issues) == 0:
break
for issue in issues:
process_issue(issue)
start_at += MAX_RESULTS
様々な条件でイシューを検索する
# 自分にアサインされたイシューを取得する
issues = jira.search_issues("project = PROJ and assignee != currentUser()")
# 自分が報告したイシューを作成日順(新しい順)に 3 件取得する
issues = jira.search_issues("reporter = currentUser() order by created desc", maxResults=3)
# 自分にアサインされたイシューのうち、今週末が締め切りのものを優先度順に 5 件取得する
issues = jira.search_issues("assignee = currentUser() and due < endOfWeek() order by priority desc", maxResults=5)
イシューの詳細情報を取得する
# キー指定でイシュー情報を取得する
issue = jira.issue("MYPROJ-1234")
# 詳細情報を表示する
print("key:", issue.key)
print("project:", issue.fields.project)
print("summary:", issue.fields.summary)
print("status:", issue.fields.status)
print("created:", issue.fields.created)
print("updated:", issue.fields.updated)
print("assignee:", issue.fields.assignee)
print("creator:", issue.fields.creator)
print("reporter:", issue.fields.reporter)
print("priority:", issue.fields.priority)
print("labels:", issue.fields.labels)
print("issuetype:", issue.fields.issuetype)
print("--- description ---")
print(issue.fields.description)
取得するフィールドを指定すると、効率的にデータを取得できます。
issue = jira.issue("MYPROJ-1234", fields="summary,status")
イシュー内のすべてのコメントを取得する
# キー指定でイシュー情報を取得する
issue = jira.issue("MYPROJ-1234")
# すべてのコメントを列挙
comments = issue.fields.comment.comments # あるいは jira.comments(issue) でも OK
for comment in comments:
print(f"■ {comment.id} / {comment.created} / {comment.author.displayName}")
print(f"{comment.body}\n")
イシュー内の特定のコメントを ID 指定で取得する
comment = jira.comment("MYPROJ-1234", "6580301")
コメントを削除する
comment.delete()
イシューにコメントを追加する
# キー指定でイシュー情報を取得する
issue = jira.issue("MYPROJ-1234")
# そのイシューにコメントを追加する
comment = jira.add_comment(issue, "Comment text")
あるいは、イシューのキーを指定することで Issue
オブジェクトを作成せずにコメントを追加することができます。
jira.add_comment("MYPROJ-1234", "Comment text")
新しいイシューを作成する
new_issue = jira.create_issue(
project="MYPROJ", # プロジェクトのキー
summary="Summary", # 課題の要約(タイトル)
description="Description", # 課題の詳細
issuetype={"name": "Task"} # 課題のタイプを指定
)
print(f"Issue ({new_issue.key}) created")
イシューを作成すると、MYPROJ-1234
のようなキーが自動的に割り当てられます。
イシューを削除する
issue = jira.issue("MYPROJ-1234")
issue.delete()
# サブタスクまで削除する場合
# issue.delete(deleteSubtasks=True)
イシューの Assignee を変更する
issue = jira.issue("MYPROJ-1234")
jira.assign_issue(issue, "newassignee")
# Assignee を削除する場合
# jira.assign_issue(issue, None)
イシューの各種情報をまとめて変更する
issue = jira.issue("MYPROJ-1234")
issue.update(summary="new summary", description="A new summary was added")
# 更新時の Notification を抑制したいとき
issue.update(notify=False, summary="new summary")
ユーザー情報を取得する
user = jira.user("USER_ID")
for key, val in user.raw.items():
print(f"{key}: {val}")
フィールド情報を取得する
fields = jira.fields()
for f in sorted(fields, key=lambda x: x["id"]):
print(f"{f['id']}: {f['name']}")