Python x Backlog API を使ってデータを一括取得する方法とか

こんにちは。
お弁当は7階層
システムソリューション部のかわです。
6月ですね。祝日として「雨の日」はいつになったらできるんでしょうか。
雨と言えば、先日社内タスク管理とかで使っている Backlog の API を少し触っていまして、色々効率化できそうだったので備忘録がてらに記事に起こそうと思います。
GUI でポチポチやるより楽にデータ取得できるのでとっても便利です。
この記事ではユーザ、カテゴリ、課題の一覧を取得するサンプルコードを載せています。
curl でササッとやりたい場合は、弊社開発部ワイルド担当 まんだいの記事↓を参考にいただければと思います。
利用環境
Microsoft Windows 11 Pro
Python 3.12.2
下準備
APIキーの発行、サブドメイン/プロジェクトIDの確認と、Python の requests モジュールを使用するのでそれぞれ準備します。
■ APIキーの発行
Backlog ログイン後、右上プロフィールアイコン→【個人設定】→【API】から発行できます。(アカウント権限によるかも)
○ 公式ドキュメント
■ プロジェクトIDの確認
プロジェクトページの「課題」とかに遷移した際の URL から、サブドメインとプロジェクトIDを確認、メモしておきます。
https://(サブドメイン)/find/xxx?projectId=(ID)
■ requestsモジュール
インストールされていない場合は pip で引っ張ってきます。
pip install requests
ユーザ一覧を取得したいとき
会社で Baklog のような管理ツールを使っていると、問題になってくるのが、アカウント管理だと思います。(日々の業務に追われて、色んなツールの管理でやっていくのって、結構骨が折れます)
ユーザ一覧を一発で取れれば、使用 / 未使用のアカウントが一目で分かるので、公式ドキュメントの記述に倣って情報取得してみましょう。
このコードでは、特定プロジェクト内に参加しているユーザリストをcsvファイルに出力します。
import csv
import requests
# ユーザ取得
def fetch_users(api_key, project_id):
url = f"https://<サブドメイン>/api/v2/projects/{project_id}/users"
params = {
"apiKey": api_key
}
response = requests.get(url, params=params)
if response.status_code == 200:
return response.json()
else:
print("ユーザ取得に失敗しました:", response.text)
return None
# json整形
def json_to_csv(json_data):
csv_data = []
for item in json_data:
user_id = item['id']
user_name = item['name']
csv_data.append([user_id, user_name])
return csv_data
# csvファイルに出力
def main():
api_key = "<APIキーを記載>"
project_id = "<プロジェクトIDを記載>"
users = fetch_users(api_key, project_id)
if users:
csv_data = json_to_csv(users)
with open('users.csv', mode='w', newline='') as file:
csv_writer = csv.writer(file)
csv_writer.writerow(['id', 'name']) # ヘッダー行を出力
csv_writer.writerows(csv_data)
print("ユーザデータをusers.csvに出力しました")
else:
print("ユーザデータを取得できませんでした")
if __name__ == "__main__":
main()
実行後、コードを配置しているディレクトリ配下にuser.csvというファイルが生成されていればokです。
id,name
1234,ビヨンド 太郎
5678,ビヨンド 花子
カテゴリ一覧を取得したいとき
顧客名等をカテゴリとして扱っている場合、その管理をしたい場合もあるかと思います。
先述のユーザー取得コードを少しいじるだけで一括で取れるので、活用してみてください。
import csv
import requests
# カテゴリ取得
def fetch_categories(api_key, project_id):
url = f"https://<サブドメイン>/api/v2/projects/{project_id}/categories"
params = {
"apiKey": api_key
}
response = requests.get(url, params=params)
if response.status_code == 200:
return response.json()
else:
print("カテゴリ取得に失敗しました:", response.text)
return None
# jsonファイル整形
def json_to_csv(json_data):
csv_data = []
for item in json_data:
category_id = item['id']
category_name = item['name']
csv_data.append([category_id, category_name])
return csv_data
# csvファイルに出力
def main():
api_key = "<APIキーを記載>"
project_id = "<プロジェクトIDを記載>"
categories = fetch_categories(api_key, project_id)
if categories:
csv_data = json_to_csv(categories)
with open('categories.csv', mode='w', newline='') as file:
csv_writer = csv.writer(file)
csv_writer.writerow(['id', 'name']) # ヘッダー行を出力
csv_writer.writerows(csv_data)
print("カテゴリデータをcategories.csvに出力しました")
else:
print("カテゴリデータを取得できませんでした")
if __name__ == "__main__":
main()
実行後、コードを配置しているディレクトリ配下に、categories.csv というファイルが生成されていればokです。
id,name
123456,ABC株式会社
654321,株式会社DEF
特定カテゴリの課題一覧を取得する
最後に、特定カテゴリ(弊社では顧客分類で使用)の課題一覧を取得するコードです。
課題については色々指定できる項目があるので、よしなにカスタマイズしてみてください。
ステータス一覧
以下コードはその一例で、今回は以下条件を指定してデータを返します。
status_id
created_since
created_until
今回は期間指定もしたいので、プリセットの datetime も使います。
コード内の created_since/until は形式で手入力な点に注意です。
import json
import csv
import sys
import requests
from datetime import datetime, timedelta
def fetch_issues(api_key, project_id, category_id, status_id, created_since, created_until):
url = "https://<サブドメイン>/api/v2/issues"
params = {
"apiKey": api_key,
"parentChild": 0, # 親課題含めすべて取得
"projectId[]": project_id,
"createdSince": created_since,
"createdUntil": created_until,
"statusId[]": status_id,
"categoryId[]": category_id
}
response = requests.get(url, params=params)
if response.status_code == 200:
return response.json()
else:
print("Failed to fetch issues:", response.text)
return None
def json_to_csv(json_data):
csv_data = []
for item in json_data:
created = item['created']
issue_type = item['issueType']['name']
summary = item['summary']
assignee = item['assignee']['name'] if item.get('assignee') else '' # 担当者がいない場合は空文字列をセット
csv_data.append([created, issue_type, summary, assignee])
return csv_data
def main():
api_key = "<APIキーを記載>"
project_id = <プロジェクトIDを記載>
category_id = <カテゴリIDを記載>
status_id = <ステータスID>
# 日時を指定
created_since = "2024-01-01"
created_until = "2024-01-31"
all_issues = []
seen_issue_ids = set()
while True:
json_data = fetch_issues(api_key, project_id, category_id, status_id, created_since, created_until)
if not json_data:
break
# jsonをcsv形式に変換
csv_data = json_to_csv(json_data)
# 課題IDを記録
for item in json_data:
issue_id = item['id']
if issue_id not in seen_issue_ids:
all_issues.append(item)
seen_issue_ids.add(issue_id)
# 取得したデータの最後のcreated日付を取得して、次のリクエストのstart_dateに設定
if json_data:
last_created = json_data[-1]['created']
last_created_date = datetime.strptime(last_created, "%Y-%m-%dT%H:%M:%SZ").date()
created_until = (last_created_date - timedelta(days=1)).strftime("%Y-%m-%d")
else:
break
# csvで出力
csv_writer = csv.writer(sys.stdout)
csv_writer.writerow(['作成日時', '分類', '内容', '担当者']) # ヘッダー行を出力
csv_writer.writerows(json_to_csv(all_issues))
if __name__ == "__main__":
main()
- 出力例
作成日時,分類,内容,担当者
2024-03-08T23:23:50Z,対応済み,test案件について,ビヨンド 花子
2024-03-08T23:06:50Z,対応済み,xxx設定依頼,ビヨンド 太郎
完
-------------------------------------------------
ビヨンドでは、部署内や部署間連携、外部企業様とのプロジェクト管理に Backlog を利用しています。また、ヌーラボ公式パートナーとして、Backlog の導入からAPI連携開発までおこなっておりますので、お気軽にお問い合わせください。

11