【大阪 / 横浜】インフラ / サーバーサイドエンジニア募集中!

【大阪 / 横浜】インフラ / サーバーサイドエンジニア募集中!

【導入実績 500社以上】AWS 構築・運用保守・監視サービス

【導入実績 500社以上】AWS 構築・運用保守・監視サービス

【CentOS 後継】AlmaLinux OS サーバー構築・移行サービス

【CentOS 後継】AlmaLinux OS サーバー構築・移行サービス

【WordPress 専用】クラウドサーバー『ウェブスピード』

【WordPress 専用】クラウドサーバー『ウェブスピード』

【格安】Webサイト セキュリティ自動診断「クイックスキャナー」

【格安】Webサイト セキュリティ自動診断「クイックスキャナー」

【予約システム開発】EDISONE カスタマイズ開発サービス

【予約システム開発】EDISONE カスタマイズ開発サービス

【100URLの登録が0円】Webサイト監視サービス『Appmill』

【100URLの登録が0円】Webサイト監視サービス『Appmill』

【200ヶ国以上に対応】グローバル eSIM「ビヨンドSIM」

【200ヶ国以上に対応】グローバル eSIM「ビヨンドSIM」

【中国への旅行・出張・駐在なら】中国SIMサービス「チョコSIM」

【中国への旅行・出張・駐在なら】中国SIMサービス「チョコSIM」

【グローバル専用サービス】北米・中国でも、ビヨンドのMSP

【グローバル専用サービス】北米・中国でも、ビヨンドのMSP

【YouTube】ビヨンド公式チャンネル「びよまるチャンネル」

【YouTube】ビヨンド公式チャンネル「びよまるチャンネル」

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

こんにちは。
お弁当は7階層
システムソリューション部のかわです。

6月ですね。祝日として「雨の日」はいつになったらできるんでしょうか。

雨と言えば、先日社内タスク管理とかで使っている Backlog の API を少し触っていまして、色々効率化できそうだったので備忘録がてらに記事に起こそうと思います。
GUI でポチポチやるより楽にデータ取得できるのでとっても便利です。

この記事ではユーザ、カテゴリ、課題の一覧を取得するサンプルコードを載せています。

curl でササッとやりたい場合は、弊社開発部ワイルド担当 まんだいの記事↓を参考にいただければと思います。

BacklogのAPIを有効活用

利用環境

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連携開発までおこなっておりますので、お気軽にお問い合わせください。

この記事がお役に立てば【 いいね 】のご協力をお願いいたします!
9
読み込み中...
9 票, 平均: 1.00 / 19
202
X facebook はてなブックマーク pocket
【2024.6.30 CentOS サポート終了】CentOS サーバー移行ソリューション

【2024.6.30 CentOS サポート終了】CentOS サーバー移行ソリューション

【2025.6.30 Amazon Linux 2 サポート終了】Amazon Linux サーバー移行ソリューション

【2025.6.30 Amazon Linux 2 サポート終了】Amazon Linux サーバー移行ソリューション

【大阪 / 横浜】インフラエンジニア・サーバーサイドエンジニア 積極採用中!

【大阪 / 横浜】インフラエンジニア・サーバーサイドエンジニア 積極採用中!

この記事をかいた人

About the author

かわ けん

システムソリューション部所属
好奇心旺盛ポケ○ン