class IssueSharedFile: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'issues' _config = config if config else None self.rs = RequestSender(_config) def get_list_of_linked_shared_files(self, issue_id_or_key: str, ) -> Response: """ 課題共有ファイル一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-list-of-linked-shared-files/ :param issue_id_or_key: 課題のID または 課題キー :return: レスポンス """ path = self.base_path + '/{issue_id_or_key}/sharedFiles/'.format(issue_id_or_key=issue_id_or_key) return self.rs.send_get_request(path=path, url_param={}) def remove_link_to_shared_file_from_issue(self, issue_id_or_key: str, shared_file_id: int, ) -> Response: """ 課題の共有ファイルのリンクを解除 https://developer.nulab.com/ja/docs/backlog/api/2/remove-link-to-shared-file-from-issue/ :param issue_id_or_key: 課題のID または 課題キー :param shared_file_id: 共有ファイルのID :return: レスポンス """ path = self.base_path + '/{issue_id_or_key}/sharedFiles/{shared_file_id}' \ .format(issue_id_or_key=issue_id_or_key, shared_file_id=shared_file_id) return self.rs.send_delete_request(path=path, request_param={}) def link_shared_files_to_issue(self, issue_id_or_key: str, file_id: List[int] ) -> Response: """ 課題に共有ファイルをリンク https://developer.nulab.com/ja/docs/backlog/api/2/link-shared-files-to-issue/ :param issue_id_or_key: 課題のID または 課題キー :param file_id: 共有ファイルのID :return: レスポンス """ path = self.base_path + '/{issue_id_or_key}/sharedFiles/'.format(issue_id_or_key=issue_id_or_key) payloads = {'fileId[]': file_id} return self.rs.send_post_request(path=path, request_param=payloads)
class Project: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'projects' _config = config if config else None self.rs = RequestSender(_config) def add_project( self, name: str, key: str, chart_enabled: bool, subtasking_enabled: bool, text_formatting_rule: str, project_leader_can_edit_project_leader: Optional[bool] = None, ) -> Response: """ プロジェクトの追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-project/ :param name: プロジェクト名 :param key: プロジェクトキー :param chart_enabled: チャートを使用するかどうか(フリープランでは利用不可) :param project_leader_can_edit_project_leader: プロジェクト管理者も他のプロジェクト管理者を指定可能にする :param subtasking_enabled: 親子課題を使用するかどうか(フリープランでは利用不可) :param text_formatting_rule: テキスト整形のルール backlog または markdown :return: レスポンス """ path = self.base_path if re.match('^[A-Z0-9_]+$', key) is None: raise ValueError('Key は半角英大文字と半角数字とアンダースコアのみが使用できます') if text_formatting_rule not in {'backlog', 'markdown'}: raise ValueError('テキスト整形のルールは backlog または markdownのみが使用できます') # Todo: 契約プランを見て、設定できないものであれば例外を投げる payloads = { 'name': name, 'key': key, 'chartEnabled': chart_enabled, 'subtaskingEnabled': subtasking_enabled, 'textFormattingRule': text_formatting_rule } if project_leader_can_edit_project_leader is not None: payloads[ 'projectLeaderCanEditProjectLeader'] = project_leader_can_edit_project_leader return self.rs.send_post_request(path=path, request_param=payloads) def get_project(self, project_id_or_key: str) -> Response: """ プロジェクト情報の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-project/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :return: レスポンス """ path = self.base_path + '/' + project_id_or_key return self.rs.send_get_request(path=path, url_param={}) def update_project( self, project_id_or_key: str, name: Optional[str] = None, key: Optional[str] = None, chart_enabled: Optional[bool] = None, subtasking_enabled: Optional[bool] = None, project_leader_can_edit_project_leader: Optional[bool] = None, text_formatting_rule: Optional[str] = None, archived: Optional[bool] = None) -> Response: """ プロジェクト情報の更新 https://developer.nulab.com/ja/docs/backlog/api/2/update-project/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param name: プロジェクト名 :param key: プロジェクトキー :param chart_enabled: チャートを使用するかどうか(フリープランでは利用不可) :param subtasking_enabled: 親子課題を使用するかどうか(フリープランでは利用不可) :param project_leader_can_edit_project_leader: プロジェクト管理者も他のプロジェクト管理者を指定可能にする :param text_formatting_rule: テキスト整形のルール backlog または markdown :param archived: プロジェクトの一覧に表示するかどうか :return: レスポンス """ # Todo: 契約プランを見て、設定できないものであれば例外を投げる path = self.base_path + '/' + project_id_or_key payloads = {} if name is not None: payloads['name'] = name if key is not None: if re.match('^[A-Z0-9_]+$', key) is None: raise ValueError('Key は半角英大文字と半角数字とアンダースコアのみが使用できます') payloads['key'] = key if chart_enabled is not None: payloads['chartEnabled'] = chart_enabled if subtasking_enabled is not None: payloads['subtaskingEnabled'] = subtasking_enabled if project_leader_can_edit_project_leader is not None: payloads[ 'projectLeaderCanEditProjectLeader'] = project_leader_can_edit_project_leader if text_formatting_rule is not None: if text_formatting_rule not in ['backlog', 'markdown']: raise ValueError('テキスト整形のルールは backlog または markdownのみが使用できます') payloads['textFormattingRule'] = text_formatting_rule if archived is not None: payloads['archived'] = archived return self.rs.send_patch_request(path=path, request_param=payloads) def delete_project(self, project_id_or_key: str) -> Response: """ プロジェクトの削除 https://developer.nulab.com/ja/docs/backlog/api/2/delete-project/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :return: レスポンス """ path = self.base_path + '/' + project_id_or_key return self.rs.send_delete_request(path=path, request_param={}) def get_project_list(self, archived: Optional[bool] = None, all_projects: Optional[bool] = None) -> Response: """ プロジェクト一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-project-list/ :param archived: 省略された場合は全てのプロジェクト、falseの場合はアーカイブされていないプロジェクト、trueの場合はアーカイブされたプロジェクトを返します。 :param all_projects: ユーザが管理者権限の場合のみ有効なパラメータです。trueの場合はすべてのプロジェクト、falseの場合は参加しているプロジェクトのみを返します。初期値はfalse。 :return: レスポンス """ path = self.base_path payloads = {} if archived is not None: payloads['archived'] = archived if all_projects is not None: payloads['all'] = all_projects return self.rs.send_get_request(path=path, url_param=payloads) def get_project_icon( self, project_id_or_key: Optional[str] = None) -> Tuple[str, Response]: """ プロジェクトアイコンの取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-project-icon/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/image'.format( project_id_or_key=project_id_or_key) return self.rs.get_file(path=path, url_param={}) def get_project_recent_updates( self, project_id_or_key: str, activity_type_id: Optional[List[int]] = None, min_id: Optional[int] = None, max_id: Optional[int] = None, count: Optional[int] = 20, order: Optional[str] = 'desc', update_type: Optional[int] = None, ) -> Response: """ プロジェクトの最近の活動の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-project-recent-updates/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param activity_type_id: type(1-26) :param min_id: 最小ID :param max_id: 最大ID :param count: 取得上限(1-100) 指定が無い場合は20 :param order: “asc”または”desc” 指定が無い場合は”desc” :param update_type: 最近の更新の種別:(1)課題の追加 (2)課題の更新 (3)課題にコメント (4)課題の削除 (5)Wikiを追加 (6)Wikiを更新 (7)Wikiを削除 (8)共有ファイルを追加 (9)共有ファイルを更新(10)共有ファイルを削除 (11)Subversionコミット (12)GITプッシュ (13)GITリポジトリ作成 (14)課題をまとめて更新 (15)ユーザーがプロジェクトに参加 (16)ユーザーがプロジェクトから脱退 (17)コメントにお知らせを追加 (18)プルリクエストの追加 (19)プルリクエストの更新 (20)プルリクエストにコメント (21)プルリクエストの削除 (22)マイルストーンの追加 (23)マイルストーンの更新 (24)マイルストーンの削除 (25)グループがプロジェクトに参加 (26)グループがプロジェクトから脱退 :return: レスポンス """ path = self.base_path + '/' + project_id_or_key payloads = {} if activity_type_id is not None: payloads['activityTypeId[]'] = activity_type_id if min_id is not None: payloads['minId'] = min_id if max_id is not None: payloads['maxId'] = max_id if count is not None: if not 1 <= count <= 100: raise ValueError('count(取得上限)は1-100の範囲で指定してください') payloads['count'] = count if order is not None: if order not in {'desc', 'asc'}: raise ValueError('order は desc または asc のみが使用できます') payloads['order'] = order if update_type is not None: payloads['type'] = update_type return self.rs.send_get_request(path=path, url_param=payloads) def get_project_user_list( self, project_id_or_key: str, exclude_group_members: Optional[bool] = None) -> Response: """ プロジェクトユーザー一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-project-user-list/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param exclude_group_members: グループを介してプロジェクトに参加しているメンバーを除く :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/users'.format( project_id_or_key=project_id_or_key) payloads = {} if exclude_group_members is not None: payloads['excludeGroupMembers'] = exclude_group_members return self.rs.send_get_request(path=path, url_param=payloads) def add_project_user(self, project_id_or_key: str, user_id: int) -> Response: """ プロジェクトユーザーの追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-project-user/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param user_id: 追加するユーザーのID :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/users'.format( project_id_or_key=project_id_or_key) payloads = {} if user_id is not None: payloads['userId'] = user_id return self.rs.send_post_request(path=path, request_param=payloads) def get_list_of_project_administrators(self, project_id_or_key: str) -> Response: """ プロジェクト管理者一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-list-of-project-administrators/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/administrators'.format( project_id_or_key=project_id_or_key) return self.rs.send_delete_request(path=path, request_param={}) def delete_project_user(self, project_id_or_key: str, user_id: int) -> Response: """ プロジェクトユーザーの削除 https://developer.nulab.com/ja/docs/backlog/api/2/delete-project-user/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param user_id: 削除するユーザーのID :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/users'.format( project_id_or_key=project_id_or_key) payloads = {'userId': user_id} return self.rs.send_delete_request(path=path, request_param=payloads) def add_project_administrator(self, project_id_or_key: str, user_id: int) -> Response: """ プロジェクト管理者の追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-project-administrator/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param user_id: 追加するユーザーのID :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/administrators'.format( project_id_or_key=project_id_or_key) payloads = {'userId': user_id} return self.rs.send_post_request(path=path, request_param=payloads) def delete_project_administrator(self, project_id_or_key: str, user_id: int) -> Response: """ プロジェクト管理者の削除 https://developer.nulab.com/ja/docs/backlog/api/2/delete-project-administrator/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param user_id: 削除するユーザーのID :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/administrators'.format( project_id_or_key=project_id_or_key) payloads = {'userId': user_id} return self.rs.send_delete_request(path=path, request_param=payloads)
class ProjectTeam: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'projects' _config = config if config else None self.rs = RequestSender(_config) def get_project_team_list( self, project_id_or_key: str, ) -> Response: """ プロジェクトチーム一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-project-team-list/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/teams'.format( project_id_or_key=project_id_or_key) return self.rs.send_get_request(path=path, url_param={}) def add_project_team( self, project_id_or_key: str, team_id: Optional[int] = None, ) -> Response: """ プロジェクトチームの追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-project-team/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param team_id: 追加するチームのID :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/teams'.format( project_id_or_key=project_id_or_key) payloads = {} if team_id is not None: payloads['teamId'] = team_id return self.rs.send_post_request(path=path, request_param=payloads) def delete_project_team( self, project_id_or_key: str, team_id: Optional[int] = None, ) -> Response: """ プロジェクトチームの削除 https://developer.nulab.com/ja/docs/backlog/api/2/delete-project-team :param project_id_or_key: プロジェクトのID または プロジェクトキー :param team_id: 削除するチームのID :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/teams'.format( project_id_or_key=project_id_or_key) payloads = {} if team_id is not None: payloads['teamId'] = team_id return self.rs.send_delete_request(path=path, request_param=payloads) def get_project_disk_usage( self, project_id_or_key: str, ) -> Response: """ プロジェクトの容量使用状況の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-project-disk-usage/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/diskUsage'.format( project_id_or_key=project_id_or_key) return self.rs.send_get_request(path=path, url_param={})
class Status: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'projects/' _config = config if config else None self.rs = RequestSender(_config) def add_status( self, project_id_or_key: str, name: str, color: str, ) -> Response: """ 権限メソッドURLURL パラメーターリクエストパラメーターレスポンス例 https://developer.nulab.com/ja/docs/backlog/api/2/add-status/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param name: 状態の名前 :param color: 状態の背景色;以下から指定”#ea2c00””#e87758””#e07b9a””#868cb7””#3b9dbd””#4caf93””#b0be3c””#eda62a””#f42858””#393939” :return: レスポンス """ path = self.base_path + project_id_or_key + '/statuses' payloads = {'name': name, 'color': color} return self.rs.send_post_request(path=path, request_param=payloads) def update_status( self, project_id_or_key: str = None, status_id: int = None, name: str = None, color: str = None, ) -> Response: """ 権限メソッドURLURL パラメーターリクエストパラメーターレスポンス例 https://developer.nulab.com/ja/docs/backlog/api/2/update-status/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param status_id: 状態のID :param name: 状態の名前 :param color: 状態の背景色;以下から指定”#ea2c00””#e87758””#e07b9a””#868cb7””#3b9dbd””#4caf93””#b0be3c””#eda62a””#f42858””#393939” :return: レスポンス """ path = self.base_path + '{project_id_or_key}/statuses/{status_id}'\ .format(project_id_or_key=project_id_or_key, status_id=status_id) payloads = {} if name: payloads['name'] = name if color: payloads['color'] = color return self.rs.send_patch_request(path=path, request_param=payloads) def delete_status( self, project_id_or_key: str, status_id: int, substitute_status_id: int, ) -> Response: """ 権限メソッドURLURL パラメーターリクエストパラメーターレスポンス例 https://developer.nulab.com/ja/docs/backlog/api/2/delete-status/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param status_id: 状態のID :param substitute_status_id: 紐づく課題を付け替える先の状態のID。削除対象の状態が設定されている課題がある場合、このパラメーターで指定した状態へ一括変更します。 :return: レスポンス """ path = self.base_path + '{project_id_or_key}/statuses/{status_id}' \ .format(project_id_or_key=project_id_or_key, status_id=status_id) payloads = {'substituteStatusId': substitute_status_id} return self.rs.send_delete_request(path=path, request_param=payloads) def update_order_of_status( self, project_id_or_key: str, status_id: List[int], ) -> Response: """ 権限メソッドURLURL パラメーターリクエストパラメーターレスポンス例 https://developer.nulab.com/ja/docs/backlog/api/2/update-order-of-status/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param status_id: 表示順に並べた、状態のIDのリスト。そのプロジェクトで使える全ての状態を渡してください。表示順には以下の制限があります未対応は先頭にあること完了は末尾にあること処理中は処理済みよりも前にあること :return: レスポンス """ path = self.base_path + '{project_id_or_key}/statuses/updateDisplayOrder'\ .format(project_id_or_key=project_id_or_key) payloads = {'statusId[]': status_id} return self.rs.send_patch_request(path=path, request_param=payloads)
class Version: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'projects' _config = config if config else None self.rs = RequestSender(_config) def get_version_milestone_list( self, project_id_or_key: Optional[str] = None, ) -> Response: """ バージョン(マイルストーン)一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-version-milestone-list/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/versions'.format( project_id_or_key=project_id_or_key) return self.rs.send_get_request(path=path, url_param={}) def update_version_milestone( self, project_id_or_key: str, version_id: int, name: str, description: Optional[str] = None, start_date: Optional[str] = None, release_due_date: Optional[str] = None, archived: Optional[bool] = None, ) -> Response: """ バージョン(マイルストーン)情報の更新 https://developer.nulab.com/ja/docs/backlog/api/2/update-version-milestone/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param version_id: バージョンのID :param name: バージョンの名前 :param description: バージョンの説明 :param start_date: バージョンの開始日 (yyyy-MM-dd) :param release_due_date: バージョンのリリース予定日 (yyyy-MM-dd) :param archived: プロジェクトホームに表示しない場合はtrue :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/versions/{version_id}'\ .format(project_id_or_key=project_id_or_key, version_id=version_id) payloads = {'name': name} if description is not None: payloads['description'] = description if start_date is not None: payloads['startDate'] = start_date if release_due_date is not None: payloads['releaseDueDate'] = release_due_date if archived is not None: payloads['archived'] = archived return self.rs.send_patch_request(path=path, request_param=payloads) def delete_version( self, project_id_or_key: Optional[str] = None, version_id: Optional[int] = None, ) -> Response: """ バージョン(マイルストーン)の削除 https://developer.nulab.com/ja/docs/backlog/api/2/delete-version/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param version_id: バージョンのID :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/versions/{version_id}'\ .format(project_id_or_key=project_id_or_key, version_id=version_id) return self.rs.send_delete_request(path=path, request_param={}) def add_version_milestone( self, project_id_or_key: str, name: str, description: Optional[str] = None, start_date: Optional[str] = None, release_due_date: Optional[str] = None, ) -> Response: """ バージョン(マイルストーン)の追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-version-milestone/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param name: バージョンの名前 :param description: バージョンの説明 :param start_date: バージョンの開始日 (yyyy-MM-dd) :param release_due_date: バージョンのリリース予定日 (yyyy-MM-dd) :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/versions'.format( project_id_or_key=project_id_or_key) payloads = {'name': name} if description is not None: payloads['description'] = description if start_date is not None: payloads['startDate'] = start_date if release_due_date is not None: payloads['releaseDueDate'] = release_due_date return self.rs.send_post_request(path=path, request_param=payloads)
class Webhook: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'projects' _config = config if config else None self.rs = RequestSender(_config) def get_list_of_webhooks(self, project_id_or_key: str ) -> Response: """ Webhook一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-list-of-webhooks/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/webhooks'.format(project_id_or_key=project_id_or_key) return self.rs.send_get_request(path=path, url_param={}) def get_webhook(self, project_id_or_key: str, webhook_id: str, ) -> Response: """ Webhookの取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-webhook/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param webhook_id: WebhookのID :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/webhooks/{webhook_id}'\ .format(project_id_or_key=project_id_or_key, webhook_id=webhook_id) return self.rs.send_get_request(path=path, url_param={}) def update_webhook(self, project_id_or_key: str, webhook_id: str, name: Optional[str] = None, description: Optional[str] = None, hook_url: Optional[str] = None, all_event: Optional[bool] = None, activity_type_ids: Optional[List[int]] = None, ) -> Response: """ Webhookの更新 https://developer.nulab.com/ja/docs/backlog/api/2/update-webhook/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param webhook_id: WebhookのID :param name: 名前 :param description: 詳細 :param hook_url: hook URL :param all_event: 全てのイベントを通知 :param activity_type_ids: 通知するイベントのID :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/webhooks/{webhook_id}'\ .format(project_id_or_key=project_id_or_key, webhook_id=webhook_id) payloads = {} if name is not None: payloads['name'] = name if description is not None: payloads['description'] = description if hook_url is not None: payloads['hookUrl'] = hook_url if all_event is not None: payloads['allEvent'] = all_event if activity_type_ids is not None: payloads['activityTypeIds[]'] = activity_type_ids return self.rs.send_patch_request(path=path, request_param=payloads) def add_webhook(self, project_id_or_key: str, name: Optional[str] = None, description: Optional[str] = None, hook_url: Optional[str] = None, all_event: Optional[bool] = None, activity_type_ids: Optional[List[int]] = None, ) -> Response: """ Webhookの追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-webhook/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param name: 名前 :param description: 詳細 :param hook_url: hook URL :param all_event: 全てのイベントを通知 :param activity_type_ids: 通知するイベントのID :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/webhooks'.format(project_id_or_key=project_id_or_key) payloads = {} if name is not None: payloads['name'] = name if description is not None: payloads['description'] = description if hook_url is not None: payloads['hookUrl'] = hook_url if all_event is not None: payloads['allEvent'] = all_event if activity_type_ids is not None: payloads['activityTypeIds[]'] = activity_type_ids return self.rs.send_post_request(path=path, request_param=payloads) def delete_webhook(self, project_id_or_key: str, webhook_id: str, ) -> Response: """ Webhookの削除 https://developer.nulab.com/ja/docs/backlog/api/2/delete-webhook/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param webhook_id: WebhookのID :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/webhooks/{webhook_id}' \ .format(project_id_or_key=project_id_or_key, webhook_id=webhook_id) return self.rs.send_delete_request(path=path, request_param={})
class WikiSharedFile: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'wikis' _config = config if config else None self.rs = RequestSender(_config) def get_list_of_shared_files_on_wiki(self, wiki_id: int, ) -> Response: """ Wiki共有ファイル一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-list-of-shared-files-on-wiki/ :param wiki_id: WikiページのID :return: レスポンス """ path = self.base_path + '/{wiki_id}/sharedFiles'.format(wiki_id=str(wiki_id)) return self.rs.send_get_request(path=path, url_param={}) def link_shared_files_to_wiki(self, wiki_id: int, file_id: List[int], ) -> Response: """ Wikiに共有ファイルをリンク https://developer.nulab.com/ja/docs/backlog/api/2/link-shared-files-to-wiki/ :param wiki_id: WikiページのID :param file_id: 共有ファイルのID :return: レスポンス """ path = self.base_path + '/{wiki_id}/sharedFiles'.format(wiki_id=str(wiki_id)) payloads = {} if file_id is not None: payloads['fileId[]'] = file_id return self.rs.send_post_request(path=path, request_param=payloads) def remove_link_to_shared_file_from_wiki(self, wiki_id: int, file_id: int, ) -> Response: """ Wikiの共有ファイルのリンクを解除 https://developer.nulab.com/ja/docs/backlog/api/2/remove-link-to-shared-file-from-wiki/ :param wiki_id: WikiページのID :param file_id: 共有ファイルのID :return: レスポンス """ path = self.base_path + '/{wiki_id}/sharedFiles/{file_id}'.format(wiki_id=str(wiki_id), file_id=str(file_id)) return self.rs.send_delete_request(path=path, request_param={})
class CustomField: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'projects' _config = config if config else None self.rs = RequestSender(_config) def get_custom_field_list(self, project_id_or_key: Optional[str] = None, ) -> Response: """ カスタム属性一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-custom-field-list/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/customFields'.format(project_id_or_key=project_id_or_key) return self.rs.send_get_request(path=path, url_param={}) def add_custom_field(self, project_id_or_key: str, type_id: int, name: str, applicable_issue_types: Optional[List[int]] = None, description: Optional[str] = None, required: Optional[bool] = None, min_num: Optional[int] = None, max_num: Optional[int] = None, min_date: Optional[str] = None, max_date: Optional[str] = None, initial_value: Optional[int] = None, unit: Optional[str] = None, initial_value_type: Optional[int] = None, initial_date: Optional[str] = None, initial_shift: Optional[int] = None, items: List[str] = None, allow_input: Optional[bool] = None, allow_add_item: Optional[bool] = None, ) -> Response: """ カスタム属性の追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-custom-field/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param type_id: カスタム属性の形式 (1)文字列 (2)文章 (3)数値 (4)日付 (5)単一リスト (6)複数リスト (7)チェックボックス (8)ラジオ :param name: カスタム属性の名前 :param applicable_issue_types: カスタム属性を有効にする種別ID空の場合、すべての課題種別で有効 :param description: カスタム属性の説明 :param required: 必須な属性とする場合はtrue :param min_num: 最小値 :param max_num: 最大値 :param min_date: 最小値 (yyyy-MM-dd) :param max_date: 最大値 (yyyy-MM-dd) :param initial_value: 初期値 :param unit: 単位 :param initial_value_type: 1:当日 2: 当日 + initialShift 3:指定日 :param initial_date: 初期値 (yyyy-MM-dd) :param initial_shift: 差分日数 :param items: リスト項目 :param allow_input: その他直接入力を許可 :param allow_add_item: 項目の追加を許可 :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/customFields'.format(project_id_or_key=project_id_or_key) payloads = {'typeId': type_id, 'name': name} if applicable_issue_types is not None: payloads['applicableIssueTypes[]'] = applicable_issue_types if description is not None: payloads['description'] = description if required is not None: payloads['required'] = required if type_id == CUSTOM_FIELD_TYPE['数値']: if min_num is not None: payloads['min'] = min_num if max_num is not None: payloads['max'] = max_num if initial_value is not None: payloads['initialValue'] = initial_value if unit is not None: payloads['unit'] = unit if type_id == CUSTOM_FIELD_TYPE['日付']: if min_date is not None: payloads['min'] = min_date if max_date is not None: payloads['max'] = max_date if initial_value_type is not None: payloads['initialValueType'] = initial_value_type if initial_date is not None: payloads['initialDate'] = initial_date if initial_shift is not None: payloads['initialShift'] = initial_shift if type_id in (CUSTOM_FIELD_TYPE['単一リスト'], CUSTOM_FIELD_TYPE['複数リスト'], CUSTOM_FIELD_TYPE['チェックボックス'], CUSTOM_FIELD_TYPE['ラジオ'],): if items is not None: payloads['items[]'] = items if allow_input is not None: payloads['allowInput'] = allow_input if allow_add_item is not None: payloads['allowAddItem'] = allow_add_item return self.rs.send_post_request(path=path, request_param=payloads) def update_custom_field(self, project_id_or_key: str, custom_field_id: int, name: Optional[str] = None, applicable_issue_types: Optional[List[int]] = None, description: Optional[str] = None, required: Optional[bool] = None, min_num: Optional[int] = None, max_num: Optional[int] = None, min_date: Optional[str] = None, max_date: Optional[str] = None, initial_value: Optional[int] = None, unit: Optional[str] = None, initial_value_type: Optional[int] = None, initial_date: Optional[str] = None, initial_shift: Optional[int] = None, items: Optional[List[str]] = None, allow_input: Optional[bool] = None, allow_add_item: Optional[bool] = None, ) -> Response: """ カスタム属性の更新 https://developer.nulab.com/ja/docs/backlog/api/2/update-custom-field/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param custom_field_id: カスタム属性のID :param name: カスタム属性の名前 :param applicable_issue_types: カスタム属性を有効にする種別ID空の場合、すべての課題種別で有効 :param description: カスタム属性の説明 :param required: 必須な属性とする場合はtrue :param min_num: 最小値 :param max_num: 最大値 :param min_date: 最小値 (yyyy-MM-dd) :param max_date: 最大値 (yyyy-MM-dd) :param initial_value: 初期値 :param unit: 単位 :param initial_value_type: (1) 当日 (2) 当日 + initialShift (3)指定日 :param initial_date: 初期値 (yyyy-MM-dd) :param initial_shift: 差分日数 :param items: リスト項目 :param allow_input: その他直接入力を許可 :param allow_add_item: 項目の追加を許可 :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/customFields/{custom_field_id}'\ .format(project_id_or_key=project_id_or_key, custom_field_id=custom_field_id) payloads = {} # TODO: 一度 GET して適切な type_id で分岐 if name is not None: payloads['name'] = name if applicable_issue_types is not None: payloads['applicableIssueTypes[]'] = applicable_issue_types if description is not None: payloads['description'] = description if required is not None: payloads['required'] = required if min_num is not None: payloads['min'] = min_num if max_num is not None: payloads['max'] = max_num if initial_value is not None: payloads['initialValue'] = initial_value if unit is not None: payloads['unit'] = unit if min_date is not None: payloads['min'] = min_date if max_date is not None: payloads['max'] = max_date if initial_value_type is not None: payloads['initialValueType'] = initial_value_type if initial_date is not None: payloads['initialDate'] = initial_date if initial_shift is not None: payloads['initialShift'] = initial_shift if items is not None: payloads['items[]'] = items if allow_input is not None: payloads['allowInput'] = allow_input if allow_add_item is not None: payloads['allowAddItem'] = allow_add_item return self.rs.send_patch_request(path=path, request_param=payloads) def delete_custom_field(self, project_id_or_key: Optional[str] = None, custom_field_id: Optional[int] = None, ) -> Response: """ カスタム属性の削除 https://developer.nulab.com/ja/docs/backlog/api/2/delete-custom-field/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param custom_field_id: カスタム属性のID :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/customFields/{custom_field_id}' \ .format(project_id_or_key=project_id_or_key, custom_field_id=custom_field_id) return self.rs.send_delete_request(path=path, request_param={})
class IssueComment: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'issues' _config = config if config else None self.rs = RequestSender(_config) def get_comment_list( self, issue_id_or_key: Optional[str] = None, min_id: Optional[int] = None, max_id: Optional[int] = None, count: int = 20, order: str = 'desc', ) -> Response: """ 課題コメントの取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-comment-list/ :param issue_id_or_key: 課題のID または 課題キー :param min_id: 最小ID :param max_id: 最大ID :param count: 取得上限(1-100) 指定が無い場合は20 :param order: “asc”または”desc” 指定が無い場合は”desc” :return: レスポンス """ path = self.base_path + '/{issue_id_or_key}/comments'.format( issue_id_or_key=issue_id_or_key) payloads = {} if min_id is not None: payloads['minId'] = min_id if max_id is not None: payloads['maxId'] = max_id if count is not None: if not 1 <= count <= 100: raise ValueError('count(取得上限)は1-100の範囲で指定してください') if order is not None: if order not in {'desc', 'asc'}: raise ValueError('order は desc または asc のみが使用できます') payloads['order'] = order return self.rs.send_get_request(path=path, url_param=payloads) def add_comment( self, issue_id_or_key: str, content: str, notified_user_id: Optional[List[int]] = None, attachment_id: Optional[List[int]] = None, ) -> Response: """ 課題コメントの追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-comment/ :param issue_id_or_key: 課題のID または 課題キー :param content: コメントの本文 :param notified_user_id: コメント登録の通知を受け取るユーザーID :param attachment_id: 添付ファイルの送信APIが返すID :return: レスポンス """ path = self.base_path + '/{issue_id_or_key}/comments'.format( issue_id_or_key=issue_id_or_key) payloads = {'content': content} if notified_user_id is not None: payloads['notifiedUserId[]'] = notified_user_id if attachment_id is not None: payloads['attachmentId[]'] = attachment_id return self.rs.send_post_request(path=path, request_param=payloads) def get_comment( self, issue_id_or_key: str, comment_id: int, ) -> Response: """ 課題コメント情報の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-comment/ :param issue_id_or_key: 課題のID または 課題キー :param comment_id: コメントのID :return: レスポンス """ path = self.base_path + '/{issue_id_or_key}/comments/{comment_id}' \ .format(issue_id_or_key=issue_id_or_key, comment_id=comment_id) return self.rs.send_get_request(path=path, url_param={}) def update_comment( self, issue_id_or_key: str, comment_id: int, content: Optional[str] = None, ) -> Response: """ 課題コメント情報の更新 https://developer.nulab.com/ja/docs/backlog/api/2/update-comment/ :param issue_id_or_key: 課題のID または 課題キー :param comment_id: コメントのID :param content: コメントの本文 :return: レスポンス """ path = self.base_path + '/{issue_id_or_key}/comments/{comment_id}' \ .format(issue_id_or_key=issue_id_or_key, comment_id=comment_id) payloads = {} if content is not None: payloads['content'] = content return self.rs.send_patch_request(path=path, request_param=payloads) def get_list_of_comment_notifications( self, issue_id_or_key: str, comment_id: int, ) -> Response: """ 課題コメントのお知らせ一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-list-of-comment-notifications/ :param issue_id_or_key: 課題のID または 課題キー :param comment_id: コメントのID :return: レスポンス """ path = self.base_path + '/{issue_id_or_key}/comments/{comment_id}/notifications' \ .format(issue_id_or_key=issue_id_or_key, comment_id=comment_id) return self.rs.send_get_request(path=path, url_param={}) def delete_comment( self, issue_id_or_key: str, comment_id: int, ) -> Response: """ 課題コメントの削除 https://developer.nulab.com/ja/docs/backlog/api/2/delete-comment/ :param issue_id_or_key: 課題のID または 課題キー :param comment_id: コメントのID :return: レスポンス """ path = self.base_path + '/{issue_id_or_key}/comments/{comment_id}' \ .format(issue_id_or_key=issue_id_or_key, comment_id=comment_id) return self.rs.send_delete_request(path=path, request_param={}) def count_comment( self, issue_id_or_key: str, ) -> Response: """ 課題コメント数の取得 https://developer.nulab.com/ja/docs/backlog/api/2/count-comment/ :param issue_id_or_key: 課題のID または 課題キー :return: レスポンス """ path = self.base_path + '/{issue_id_or_key}/comments/count'.format( issue_id_or_key=issue_id_or_key) return self.rs.send_get_request(path=path, url_param={}) def add_comment_notification( self, issue_id_or_key: str, comment_id: int, notified_user_id: Optional[List[int]] = None, ) -> Response: """ 課題コメントにお知らせを追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-comment-notification/ :param issue_id_or_key: 課題のID または 課題キー :param comment_id: コメントのID :param notified_user_id: 課題の登録の通知を受け取るユーザーのID :return: レスポンス """ path = self.base_path + '/{issue_id_or_key}/comments/{comment_id}/notifications' \ .format(issue_id_or_key=issue_id_or_key, comment_id=comment_id) payloads = {} if notified_user_id is not None: payloads['notifiedUserId[]'] = notified_user_id return self.rs.send_post_request(path=path, request_param=payloads)
class Notification: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'notifications' _config = config if config else None self.rs = RequestSender(_config) def get_notification( self, min_id: Optional[int] = None, max_id: Optional[int] = None, count: Optional[int] = 20, order: Optional[str] = 'desc', sender_id: Optional[int] = None, ) -> Response: """ お知らせ一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-notification/ :param min_id: 最小ID :param max_id: 最大ID :param count: 取得上限(1-100) 指定が無い場合は20 :param order: “asc”または”desc” 指定が無い場合は”desc” :param sender_id: 送信者ID :return: レスポンス """ path = self.base_path payloads = {} if min_id is not None: payloads['minId'] = min_id if max_id is not None: payloads['maxId'] = max_id if count is not None: if not 1 <= count <= 100: raise ValueError('count(取得上限)は1-100の範囲で指定してください') if order is not None: if order not in {'desc', 'asc'}: raise ValueError('order は desc または asc のみが使用できます') payloads['order'] = order if sender_id is not None: payloads['senderId'] = sender_id return self.rs.send_get_request(path=path, url_param=payloads) def count_notification( self, already_read: Optional[bool] = None, resource_already_read: Optional[bool] = None, ) -> Response: """ お知らせ数の取得 https://developer.nulab.com/ja/docs/backlog/api/2/count-notification/ :param already_read: :param resource_already_read: :return: レスポンス """ path = self.base_path + '/count' payloads = {} if already_read is not None: payloads['alreadyRead'] = already_read if resource_already_read is not None: payloads['resourceAlreadyRead'] = resource_already_read return self.rs.send_get_request(path=path, url_param=payloads) def read_notification( self, notification_id: int, ) -> Response: """ お知らせの既読化 https://developer.nulab.com/ja/docs/backlog/api/2/read-notification/ :param notification_id: お知らせのID :return: レスポンス """ path = self.base_path + '/{notification_id}/markAsRead'.format( notification_id=str(notification_id)) return self.rs.send_post_request(path=path, request_param={}) def reset_unread_notification_count(self, ): """ お知らせ数のリセット https://developer.nulab.com/ja/docs/backlog/api/2/reset-unread-notification-count/ :return: レスポンス """ path = self.base_path + '/markAsRead' return self.rs.send_post_request(path=path, request_param={})
class ListTypeCustomField: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'projects' _config = config if config else None self.rs = RequestSender(_config) def add_list_item_for_list_type_custom_field(self, project_id_or_key: Optional[str] = None, custom_field_id: Optional[int] = None, name: Optional[str] = None, ) -> Response: """ 選択リストカスタム属性のリスト項目の追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-list-item-for-list-type-custom-field/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param custom_field_id: カスタム属性のID :param name: リスト項目の名前 :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/customFields/{custom_field_id}/items'\ .format(project_id_or_key=project_id_or_key, custom_field_id=custom_field_id) payloads = {'name': name} return self.rs.send_post_request(path=path, request_param=payloads) def delete_list_item_for_list_type_custom_field(self, project_id_or_key: str, custom_field_id: int, item_id: int ) -> Response: """ 選択リストカスタム属性のリスト項目の削除 https://developer.nulab.com/ja/docs/backlog/api/2/delete-list-item-for-list-type-custom-field/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param custom_field_id: カスタム属性のID :param item_id: リスト項目のID :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/customFields/{custom_field_id}/items/{item_id}'\ .format(project_id_or_key=project_id_or_key, custom_field_id=custom_field_id, item_id=item_id) return self.rs.send_delete_request(path=path, request_param={}) def update_list_item_for_list_type_custom_field(self, project_id_or_key: Optional[str] = None, custom_field_id: Optional[int] = None, item_id: Optional[int] = None, name: Optional[str] = None, ) -> Response: """ 選択リストカスタム属性のリスト項目の更新 https://developer.nulab.com/ja/docs/backlog/api/2/update-list-item-for-list-type-custom-field/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param custom_field_id: カスタム属性のID :param item_id: リスト項目のID :param name: リスト項目の名前 :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/customFields/{custom_field_id}/items/{item_id}'\ .format(project_id_or_key=project_id_or_key, custom_field_id=custom_field_id, item_id=item_id) payloads = {} if name is not None: payloads['name'] = name return self.rs.send_patch_request(path=path, request_param=payloads)
class PullRequest: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'projects' _config = config if config else None self.rs = RequestSender(_config) def get_number_of_pull_requests(self, project_id_or_key: str, repo_id_or_name: str, status_id: Optional[List[int]] = None, assignee_id: Optional[List[int]] = None, issue_id: Optional[List[int]] = None, created_user_id: Optional[List[int]] = None, offset: Optional[int] = None, count: Optional[int] = 20, ) -> Response: """ プルリクエスト数の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-number-of-pull-requests/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param repo_id_or_name: リポジトリのID または リポジトリ名 :param status_id: 状態のID :param assignee_id: 担当者のID :param issue_id: 関連課題のID :param created_user_id: 登録者のID :param offset: :param count: 取得上限(1-100) 指定が無い場合は20 :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/git/repositories/{repo_id_or_name}/pullRequests/count'\ .format(project_id_or_key=project_id_or_key, repo_id_or_name=repo_id_or_name) payloads = {} if status_id is not None: payloads['statusId[]'] = status_id if assignee_id is not None: payloads['assigneeId[]'] = assignee_id if issue_id is not None: payloads['issueId[]'] = issue_id if created_user_id is not None: payloads['createdUserId[]'] = created_user_id if offset is not None: payloads['offset'] = offset if count is not None: if not 1 <= count <= 100: raise ValueError('count(取得上限)は1-100の範囲で指定してください') payloads['count'] = count return self.rs.send_get_request(path=path, url_param=payloads) def get_pull_request_list(self, project_id_or_key: str, repo_id_or_name: str, status_id: Optional[List[int]] = None, assignee_id: Optional[List[int]] = None, issue_id: Optional[List[int]] = None, created_user_id: Optional[List[int]] = None, offset: Optional[int] = None, count: int = 20, ) -> Response: """ プルリクエスト一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-pull-request-list/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param repo_id_or_name: リポジトリのID または リポジトリ名 :param status_id: 状態のID :param assignee_id: 担当者のID :param issue_id: 関連課題のID :param created_user_id: 登録者のID :param offset: :param count: 取得上限(1-100) 指定が無い場合は20 :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/git/repositories/{repo_id_or_name}/pullRequests/' \ .format(project_id_or_key=project_id_or_key, repo_id_or_name=repo_id_or_name) payloads = {} if status_id is not None: payloads['statusId[]'] = status_id if assignee_id is not None: payloads['assigneeId[]'] = assignee_id if issue_id is not None: payloads['issueId[]'] = issue_id if created_user_id is not None: payloads['createdUserId[]'] = created_user_id if offset is not None: payloads['offset'] = offset if count is not None: if not 1 <= count <= 100: raise ValueError('count(取得上限)は1-100の範囲で指定してください') payloads['count'] = count return self.rs.send_get_request(path=path, url_param=payloads) def get_pull_request(self, project_id_or_key: str, repo_id_or_name: str, number: int, ) -> Response: """ プルリクエストの取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-pull-request/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param repo_id_or_name: リポジトリのID または リポジトリ名 :param number: プルリクエストの番号 :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/git/repositories/{repo_id_or_name}/pullRequests/{number}' \ .format(project_id_or_key=project_id_or_key, repo_id_or_name=repo_id_or_name, number=number) return self.rs.send_get_request(path=path, url_param={}) def add_pull_request(self, project_id_or_key: str, repo_id_or_name: str, summary: str, description: str, base: str, branch: str, issue_id: Optional[int] = None, assignee_id: Optional[int] = None, notified_user_id: Optional[List[int]] = None, attachment_id: List[int] = None, ) -> Response: """ プルリクエストの追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-pull-request/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param repo_id_or_name: リポジトリのID または リポジトリ名 :param summary: プルリクエストの件名 :param description: プルリクエストの詳細 :param base: マージ先のブランチ名 :param branch: マージされるブランチ名 :param issue_id: 関連課題のID :param assignee_id: プルリクエストの担当者のID :param notified_user_id: プルリクエストの登録の通知を受け取るユーザーのID :param attachment_id: 添付ファイルの送信APIが返すID :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/git/repositories/{repo_id_or_name}/pullRequests/' \ .format(project_id_or_key=project_id_or_key, repo_id_or_name=repo_id_or_name) payloads = {'summary': summary, 'description': description, 'base': base, 'branch': branch} if issue_id is not None: payloads['issueId'] = issue_id if assignee_id is not None: payloads['assigneeId'] = assignee_id if notified_user_id is not None: payloads['notifiedUserId[]'] = notified_user_id if attachment_id is not None: payloads['attachmentId[]'] = attachment_id return self.rs.send_post_request(path=path, request_param=payloads) def update_pull_request(self, project_id_or_key: str, repo_id_or_name: str, number: int, summary: Optional[str] = None, description: Optional[str] = None, issue_id: Optional[int] = None, assignee_id: Optional[int] = None, notified_user_id: Optional[List[int]] = None, comment: Optional[str] = None, ) -> Response: """ プルリクエストの更新 https://developer.nulab.com/ja/docs/backlog/api/2/update-pull-request/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param repo_id_or_name: リポジトリのID または リポジトリ名 :param number: プルリクエストの番号 :param summary: プルリクエストの件名 :param description: プルリクエストの詳細 :param issue_id: 関連課題のID :param assignee_id: プルリクエストの担当者のID :param notified_user_id: プルリクエストの登録の通知を受け取るユーザーのID :param comment: コメント :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/git/repositories/{repo_id_or_name}/pullRequests/{number}' \ .format(project_id_or_key=project_id_or_key, repo_id_or_name=repo_id_or_name, number=number) payloads = {} if summary is not None: payloads['summary'] = summary if description is not None: payloads['description'] = description if issue_id is not None: payloads['issueId'] = issue_id if assignee_id is not None: payloads['assigneeId'] = assignee_id if notified_user_id is not None: payloads['notifiedUserId[]'] = notified_user_id if comment is not None: payloads['comment'] = comment return self.rs.send_patch_request(path=path, request_param=payloads)
class PullRequestComment: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'projects' _config = config if config else None self.rs = RequestSender(_config) def get_pull_request_comment(self, project_id_or_key: str, repo_id_or_name: str, number: Optional[int] = None, min_id: Optional[int] = None, max_id: Optional[int] = None, count: int = 20, order: str = 'desc', ) -> Response: """ プルリクエストコメントの取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-pull-request-comment/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param repo_id_or_name: リポジトリのID または リポジトリ名 :param number: プルリクエストの番号 :param min_id: 最小ID :param max_id: 最大ID :param count: 取得上限(1-100) 指定が無い場合は20 :param order: “asc”または”desc” 指定が無い場合は”desc” :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/git/repositories/{repo_id_or_name}/pullRequests/{number}/comments'\ .format(project_id_or_key=project_id_or_key, repo_id_or_name=repo_id_or_name, number=number) payloads = {} if min_id is not None: payloads['minId'] = min_id if max_id is not None: payloads['maxId'] = max_id if count is not None: if not 1 <= count <= 100: raise ValueError('count(取得上限)は1-100の範囲で指定してください') payloads['count'] = count if order is not None: if order not in {'desc', 'asc'}: raise ValueError('order は desc または asc のみが使用できます') payloads['order'] = order return self.rs.send_get_request(path=path, url_param=payloads) def add_pull_request_comment(self, project_id_or_key: str, repo_id_or_name: str, number: int, content: str, notified_user_id: Optional[List[int]] = None, ) -> Response: """ プルリクエストコメントの追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-pull-request-comment/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param repo_id_or_name: リポジトリのID または リポジトリ名 :param number: プルリクエストの番号 :param content: コメントの本文 :param notified_user_id: コメント登録の通知を受け取るユーザーID :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/git/repositories/{repo_id_or_name}/pullRequests/{number}/comments'\ .format(project_id_or_key=project_id_or_key, repo_id_or_name=repo_id_or_name, number=number) payloads = {'content': content} if notified_user_id is not None: payloads['notifiedUserId[]'] = notified_user_id return self.rs.send_post_request(path=path, request_param=payloads) def get_number_of_pull_request_comments(self, project_id_or_key: str, repo_id_or_name: str, number: int, ) -> Response: """ プルリクエストコメント数の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-number-of-pull-request-comments/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param repo_id_or_name: リポジトリのID または リポジトリ名 :param number: プルリクエストの番号 :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/git/repositories/{repo_id_or_name}/' \ 'pullRequests/{number}/comments/count' \ .format(project_id_or_key=project_id_or_key, repo_id_or_name=repo_id_or_name, number=number) return self.rs.send_get_request(path=path, url_param={}) def update_pull_request_comment_information(self, project_id_or_key: str, repo_id_or_name: str, number: int, comment_id: int, content: Optional[str] = None, ) -> Response: """ プルリクエストコメント情報の更新 https://developer.nulab.com/ja/docs/backlog/api/2/update-pull-request-comment-information/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param repo_id_or_name: リポジトリのID または リポジトリ名 :param number: プルリクエストの番号 :param comment_id: コメントのID :param content: コメントの本文 :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/git/repositories/{repo_id_or_name}/' \ 'pullRequests/{number}/comments/{comment_id}' \ .format(project_id_or_key=project_id_or_key, repo_id_or_name=repo_id_or_name, number=number, comment_id=comment_id) payloads = {} if content is not None: payloads['content'] = content return self.rs.send_patch_request(path=path, request_param=payloads)
class Team: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'teams' _config = config if config else None self.rs = RequestSender(_config) def get_list_of_teams( self, order: str = 'desc', offset: Optional[int] = None, count: int = 20, ) -> Response: """ チーム一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-list-of-teams/ :param order: “asc”または”desc” 指定が無い場合は”desc” :param offset: :param count: 取得上限(1-100) 指定が無い場合は20 :return: レスポンス """ path = self.base_path payloads = {} if order is not None: if order not in {'desc', 'asc'}: raise ValueError('order は desc または asc のみが使用できます') payloads['order'] = order if offset is not None: payloads['offset'] = offset if count is not None: if not 1 <= count <= 100: raise ValueError('count(取得上限)は1-100の範囲で指定してください') payloads['count'] = count return self.rs.send_get_request(path=path, url_param=payloads) def add_team( self, name: Optional[str] = None, members: Optional[List[int]] = None, ) -> Response: """ チームの追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-team/ :param name: グループ名 :param members: グループに含めるユーザーID :return: レスポンス """ path = self.base_path payloads = {} if name is not None: payloads['name'] = name if members is not None: payloads['members[]'] = members return self.rs.send_post_request(path=path, request_param=payloads) def update_team( self, team_id: int, name: Optional[str] = None, members: Optional[List[int]] = None, ) -> Response: """ チーム情報の更新 https://developer.nulab.com/ja/docs/backlog/api/2/update-team/ :param team_id: チームのID :param name: チーム名 :param members: チームに含めるユーザーID :return: レスポンス """ path = self.base_path + '{team_id}'.format(team_id=team_id) payloads = {} if name is not None: payloads['name'] = name if members is not None: payloads['members[]'] = members return self.rs.send_patch_request(path=path, request_param=payloads) def delete_team( self, team_id: Optional[int] = None, ) -> Response: """ チームの削除 https://developer.nulab.com/ja/docs/backlog/api/2/delete-team/ :param team_id: チームのID :return: レスポンス """ path = self.base_path + '{team_id}'.format(team_id=team_id) return self.rs.send_delete_request(path=path, request_param={}) def get_team_icon( self, team_id: Optional[int] = None, ) -> Response: """ チームアイコンの取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-team-icon/ :param team_id: チームのID :return: レスポンス """ path = self.base_path + '{team_id}/icon'.format(team_id=team_id) return self.rs.send_get_request(path=path, url_param={}) def get_team( self, team_id: Optional[int] = None, ) -> Response: """ チーム情報の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-team/ :param team_id: チームのID :return: レスポンス """ path = self.base_path + '{team_id}'.format(team_id=team_id) return self.rs.send_get_request(path=path, url_param={})
class Watch: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'watchings' _config = config if config else None self.rs = RequestSender(_config) def count_watching( self, user_id: int, resource_already_read: Optional[bool] = None, already_read: Optional[bool] = None, ) -> Response: """ ウォッチ数の取得 https://developer.nulab.com/ja/docs/backlog/api/2/count-watching/ :param user_id: ユーザーのID :param resource_already_read: 既読かどうか。trueの場合は既読のウォッチ、falseの場合は未読のウォッチ、指定しない場合は両方のウォッチを返します。指定が無い場合は両方 :param already_read: ウォッチメニューの一覧表示後に更新されたウォッチの件数を返します。trueの場合はウォッチメニューを表示した後に更新されていない(既読状態の)件数を返します。falseの場合はウォッチメニューを表示した後に更新された(未読状態の)ウォッチの件数を返します。指定が無い場合は両方を合わせた件数を返します。resourceAlreadyReadが指定してある場合、alreadyReadは使用されません。 :return: レスポンス """ path = 'users/{user_id}/watchings/count'.format(user_id=user_id) payloads = {} if resource_already_read is not None: payloads['resourceAlreadyRead'] = resource_already_read if already_read is not None: payloads['alreadyRead'] = already_read return self.rs.send_get_request(path=path, url_param=payloads) def mark_watching_as_read( self, watching_id: int, ) -> Response: """ ウォッチの既読化 https://developer.nulab.com/ja/docs/backlog/api/2/mark-watching-as-read/ :param watching_id: ウォッチのID :return: レスポンス """ path = self.base_path + '/{watching_id}/markAsRead'.format( watching_id=watching_id) return self.rs.send_get_request(path=path, url_param={}) def add_watching( self, issue_id_or_key: Optional[str] = None, note: Optional[str] = None, ) -> Response: """ ウォッチの追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-watching/ :param issue_id_or_key: 課題のID または 課題キー :param note: メモ :return: レスポンス """ path = self.base_path payloads = {} if issue_id_or_key is not None: payloads['issueIdOrKey'] = issue_id_or_key if note is not None: payloads['note'] = note return self.rs.send_post_request(path=path, request_param=payloads) def get_watching( self, watching_id: int, ) -> Response: """ ウォッチ情報の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-watching/ :param watching_id: ウォッチのID :return: レスポンス """ path = self.base_path + '/{watching_id}'.format( watching_id=watching_id) return self.rs.send_get_request(path=path, url_param={}) def delete_watching( self, watching_id: int, ) -> Response: """ ウォッチの削除 https://developer.nulab.com/ja/docs/backlog/api/2/delete-watching/ :param watching_id: ウォッチのID :return: レスポンス """ path = self.base_path + '/{watching_id}'.format( watching_id=watching_id) return self.rs.send_delete_request(path=path, request_param={}) def update_watching( self, watching_id: int, note: Optional[str] = None, ) -> Response: """ ウォッチの更新 https://developer.nulab.com/ja/docs/backlog/api/2/update-watching/ :param watching_id: ウォッチのID :param note: メモ :return: レスポンス """ path = self.base_path + '/{watching_id}'.format( watching_id=watching_id) payloads = {} if note is not None: payloads['note'] = note return self.rs.send_post_request(path=path, request_param=payloads) def get_watching_list( self, user_id: int, order: str = 'desc', sort: str = 'issueUpdated', count: int = 20, offset: Optional[int] = None, resource_already_read: Optional[bool] = None, issue_id: Optional[List[int]] = None, ) -> Response: """ ウォッチ一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-watching-list/ :param user_id: ユーザーのID :param order: “asc”または”desc” 指定が無い場合は”desc” :param sort: ウォッチ一覧のソートに使用する属性名“created”“updated”“issueUpdated”指定が無い場合は”issueUpdated” :param count: 取得上限(1-100) 指定が無い場合は20 :param offset: :param resource_already_read: ウォッチしている課題の詳細を既読かどうか。trueの場合は既読のウォッチ、falseの場合は未読のウォッチ、指定しない場合は両方のウォッチを返します。指定が無い場合は両方 :param issue_id: 課題のID :return: レスポンス """ path = 'users/{user_id}/watchings'.format(user_id=user_id) payloads = {} if order is not None: if order not in {'desc', 'asc'}: raise ValueError('order は desc または asc のみが使用できます') payloads['order'] = order if sort is not None: payloads['sort'] = sort if count is not None: if not 1 <= count <= 100: raise ValueError('count(取得上限)は1-100の範囲で指定してください') if offset is not None: payloads['offset'] = offset if resource_already_read is not None: payloads['resourceAlreadyRead'] = resource_already_read if issue_id is not None: payloads['issueId[]'] = issue_id return self.rs.send_get_request(path=path, url_param=payloads)
class Issue: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'issues' _config = config if config else None self.rs = RequestSender(_config) def get_issue_list( self, project_id: Optional[List[int]] = None, issue_type_id: Optional[List[int]] = None, category_id: Optional[List[int]] = None, version_id: Optional[List[int]] = None, milestone_id: Optional[List[int]] = None, status_id: Optional[List[int]] = None, priority_id: Optional[List[int]] = None, assignee_id: Optional[List[int]] = None, created_user_id: Optional[List[int]] = None, resolution_id: Optional[List[int]] = None, parent_child: Optional[int] = None, attachment: Optional[bool] = None, shared_file: Optional[bool] = None, sort: Optional[str] = None, order: Optional[str] = 'desc', offset: Optional[int] = None, count: Optional[int] = 20, created_since: Optional[str] = None, created_until: Optional[str] = None, updated_since: Optional[str] = None, updated_until: Optional[str] = None, start_date_since: Optional[str] = None, start_date_until: Optional[str] = None, due_date_since: Optional[str] = None, due_date_until: Optional[str] = None, id_: Optional[List[int]] = None, parent_issue_id: Optional[List[int]] = None, keyword: Optional[str] = None, custom_field_text: Dict[int, str] = None, custom_field_num: Dict[int, Dict[str, int or None]] = None, custom_field_date: Dict[int, Dict[str, int or None]] = None, custom_field_list: Dict[int, List[int]] = None) -> Response: """ 課題一覧の取得 https://developer.nulab-inc.com/ja/docs/backlog/api/2/get-issue-list/ :param project_id: プロジェクトのID :param issue_type_id: 種別のID :param category_id: カテゴリーのID :param version_id: 発生バージョンのID :param milestone_id: マイルストーンのID :param status_id: 状態のID :param priority_id: 優先度のID :param assignee_id: 担当者のID :param created_user_id: 登録者のID :param resolution_id: 完了理由のID :param parent_child: 親子課題の 0:すべて, 1:子課題以外, 2:子課題, 3:親課題でも子課題でもない課題, 4:親課題 :param attachment: 添付ファイルを含む場合はtrue :param shared_file: 共有ファイルを含む場合はtrue :param sort: 課題一覧のソートに使用する属性名 :param order: “asc”または”desc” 指定が無い場合は”desc” :param offset: オフセット :param count: 取得上限(1-100) 指定が無い場合は20 :param created_since: 登録日 (yyyy-MM-dd) :param created_until: 登録日 (yyyy-MM-dd) :param updated_since: 更新日 (yyyy-MM-dd) :param updated_until: 更新日 (yyyy-MM-dd) :param start_date_since: 開始日 (yyyy-MM-dd) :param start_date_until: 開始日 (yyyy-MM-dd) :param due_date_since: 期限日 (yyyy-MM-dd) :param due_date_until: 期限日 (yyyy-MM-dd) :param id_: 課題のID :param parent_issue_id: 親課題のID :param keyword: 検索キーワード :param custom_field_text: カスタム属性(テキスト)の検索キーワード e.g.) {1: 'debug', 2: 'top'} :param custom_field_num: カスタム属性(数値)の最小・最大値 e.g.) {1: {'min': 10, 'max': 20}, 2: {'min': None, 'max': 100}} :param custom_field_date: カスタム属性(日付)の最小・最大値 e.g.) {1: {'min': '2000-01-01', max: '2000-12-31'}} :param custom_field_list: カスタム属性(リスト)の指定ID e.g.) {1: [100, 101, 102], 2: [200]} :return: レスポンス """ path = self.base_path payloads = {} if project_id is not None: payloads['projectId[]'] = project_id if issue_type_id is not None: payloads['issueTypeId[]'] = issue_type_id if category_id is not None: payloads['categoryId[]'] = category_id if version_id is not None: payloads['versionId[]'] = version_id if milestone_id is not None: payloads['milestoneId[]'] = milestone_id if status_id is not None: payloads['statusId[]'] = status_id if priority_id is not None: payloads['priorityId[]'] = priority_id if assignee_id is not None: payloads['assigneeId[]'] = assignee_id if created_user_id is not None: payloads['createdUserId[]'] = created_user_id if resolution_id is not None: payloads['resolutionId[]'] = resolution_id if parent_child is not None: payloads['parentChild'] = parent_child if attachment is not None: payloads['attachment'] = attachment if shared_file is not None: payloads['sharedFile'] = shared_file if sort is not None: payloads['sort'] = sort if order is not None: if order not in {'desc', 'asc'}: raise ValueError('order は desc または asc のみが使用できます') payloads['order'] = order if offset is not None: payloads['offset'] = offset if count is not None: if not 1 <= count <= 100: raise ValueError('count(取得上限)は1-100の範囲で指定してください') payloads['count'] = count if created_since is not None: payloads['createdSince'] = created_since if created_until is not None: payloads['createdUntil'] = created_until if updated_since is not None: payloads['updatedSince'] = updated_since if updated_until is not None: payloads['updatedUntil'] = updated_until if start_date_since is not None: payloads['startDateSince'] = start_date_since if start_date_until is not None: payloads['startDateUntil'] = start_date_until if due_date_since is not None: payloads['dueDateSince'] = due_date_since if due_date_until is not None: payloads['dueDateUntil'] = due_date_until if id_ is not None: payloads['id[]'] = id_ if parent_issue_id is not None: payloads['parentIssueId[]'] = parent_issue_id if keyword is not None: payloads['keyword'] = keyword if custom_field_text is not None: for field_id in custom_field_text: payloads['customField_{field_id}'.format( field_id=field_id)] = custom_field_text[field_id] if custom_field_num is not None: for field_id in custom_field_num: if custom_field_num[field_id]['min']: payloads['customField_{field_id}_min'.format( field_id=field_id)] = custom_field_num[field_id]['min'] if custom_field_num[field_id]['max']: payloads['customField_{field_id}_max'.format( field_id=field_id)] = custom_field_num[field_id]['max'] if custom_field_date is not None: for field_id in custom_field_date: if custom_field_date[field_id]['min']: payloads['customField_{field_id}_min'.format( field_id=field_id )] = custom_field_date[field_id]['min'] if custom_field_date[field_id]['max']: payloads['customField_{field_id}_max'.format( field_id=field_id )] = custom_field_date[field_id]['max'] if custom_field_list is not None: for field_id in custom_field_list: payloads['customField_{field_id}[]'.format( field_id=field_id)] = custom_field_list[field_id] return self.rs.send_get_request(path=path, url_param=payloads) def count_issue( self, project_id: Optional[List[int]] = None, issue_type_id: Optional[List[int]] = None, category_id: Optional[List[int]] = None, version_id: Optional[List[int]] = None, milestone_id: Optional[List[int]] = None, status_id: Optional[List[int]] = None, priority_id: Optional[List[int]] = None, assignee_id: Optional[List[int]] = None, created_user_id: Optional[List[int]] = None, resolution_id: Optional[List[int]] = None, parent_child: Optional[int] = None, attachment: Optional[bool] = None, shared_file: Optional[bool] = None, sort: Optional[str] = None, order: Optional[str] = 'desc', offset: Optional[int] = None, count: Optional[int] = 20, created_since: Optional[str] = None, created_until: Optional[str] = None, updated_since: Optional[str] = None, updated_until: Optional[str] = None, start_date_since: Optional[str] = None, start_date_until: Optional[str] = None, due_date_since: Optional[str] = None, due_date_until: Optional[str] = None, id_: Optional[List[int]] = None, parent_issue_id: Optional[List[int]] = None, keyword: Optional[str] = None, custom_field_text: Dict[int, str] = None, custom_field_num: Dict[int, Dict[str, int or None]] = None, custom_field_date: Dict[int, Dict[str, int or None]] = None, custom_field_list: Dict[int, List[int]] = None) -> Response: """ 課題数の取得 https://developer.nulab.com/ja/docs/backlog/api/2/count-issue/ :param project_id: プロジェクトのID :param issue_type_id: 種別のID :param category_id: カテゴリーのID :param version_id: 発生バージョンのID :param milestone_id: マイルストーンのID :param status_id: 状態のID :param priority_id: 優先度のID :param assignee_id: 担当者のID :param created_user_id: 登録者のID :param resolution_id: 完了理由のID :param parent_child: 親子課題の 0:すべて, 1:子課題以外, 2:子課題, 3:親課題でも子課題でもない課題, 4:親課題 :param attachment: 添付ファイルを含む場合はtrue :param shared_file: 共有ファイルを含む場合はtrue :param sort: 課題一覧のソートに使用する属性名 :param order: “asc”または”desc” 指定が無い場合は”desc” :param offset: オフセット :param count: 取得上限(1-100) 指定が無い場合は20 :param created_since: 登録日 (yyyy-MM-dd) :param created_until: 登録日 (yyyy-MM-dd) :param updated_since: 更新日 (yyyy-MM-dd) :param updated_until: 更新日 (yyyy-MM-dd) :param start_date_since: 開始日 (yyyy-MM-dd) :param start_date_until: 開始日 (yyyy-MM-dd) :param due_date_since: 期限日 (yyyy-MM-dd) :param due_date_until: 期限日 (yyyy-MM-dd) :param id_: 課題のID :param parent_issue_id: 親課題のID :param keyword: 検索キーワード :param custom_field_text: カスタム属性(テキスト)の検索キーワード e.g.) {1: 'debug', 2: 'top'} :param custom_field_num: カスタム属性(数値)の最小・最大値 e.g.) {1: {'min': 10, 'max': 20}, 2: {'min': None, 'max': 100}} :param custom_field_date: カスタム属性(日付)の最小・最大値 e.g.) {1: {'min': '2000-01-01', max: '2000-12-31'}} :param custom_field_list: カスタム属性(リスト)の指定ID e.g.) {1: [100, 101, 102], 2: [200]} :return: レスポンス """ path = self.base_path + '/count' payloads = {} if project_id is not None: payloads['projectId[]'] = project_id if issue_type_id is not None: payloads['issueTypeId[]'] = issue_type_id if category_id is not None: payloads['categoryId[]'] = category_id if version_id is not None: payloads['versionId[]'] = version_id if milestone_id is not None: payloads['milestoneId[]'] = milestone_id if status_id is not None: payloads['statusId[]'] = status_id if priority_id is not None: payloads['priorityId[]'] = priority_id if assignee_id is not None: payloads['assigneeId[]'] = assignee_id if created_user_id is not None: payloads['createdUserId[]'] = created_user_id if resolution_id is not None: payloads['resolutionId[]'] = resolution_id if parent_child is not None: payloads['parentChild'] = parent_child if attachment is not None: payloads['attachment'] = attachment if shared_file is not None: payloads['sharedFile'] = shared_file if sort is not None: payloads['sort'] = sort if order is not None: if order not in {'desc', 'asc'}: raise ValueError('order は desc または asc のみが使用できます') payloads['order'] = order if offset is not None: payloads['offset'] = offset if count is not None: if not 1 <= count <= 100: raise ValueError('count(取得上限)は1-100の範囲で指定してください') if created_since is not None: payloads['createdSince'] = created_since if created_until is not None: payloads['createdUntil'] = created_until if updated_since is not None: payloads['updatedSince'] = updated_since if updated_until is not None: payloads['updatedUntil'] = updated_until if start_date_since is not None: payloads['startDateSince'] = start_date_since if start_date_until is not None: payloads['startDateUntil'] = start_date_until if due_date_since is not None: payloads['dueDateSince'] = due_date_since if due_date_until is not None: payloads['dueDateUntil'] = due_date_until if id_ is not None: payloads['id[]'] = id_ if parent_issue_id is not None: payloads['parentIssueId[]'] = parent_issue_id if keyword is not None: payloads['keyword'] = keyword if custom_field_text is not None: for field_id in custom_field_text: payloads['customField_{field_id}'.format( field_id=field_id)] = custom_field_text[field_id] if custom_field_num is not None: for field_id in custom_field_num: if custom_field_num[field_id]['min']: payloads['customField_{field_id}_min'.format( field_id=field_id)] = custom_field_num[field_id]['min'] if custom_field_num[field_id]['max']: payloads['customField_{field_id}_max'.format( field_id=field_id)] = custom_field_num[field_id]['max'] if custom_field_date is not None: for field_id in custom_field_date: if custom_field_date[field_id]['min']: payloads['customField_{field_id}_min'.format( field_id=field_id )] = custom_field_date[field_id]['min'] if custom_field_date[field_id]['max']: payloads['customField_{field_id}_max'.format( field_id=field_id )] = custom_field_date[field_id]['max'] if custom_field_list is not None: for field_id in custom_field_list: payloads['customField_{field_id}[]'.format( field_id=field_id)] = custom_field_list[field_id] return self.rs.send_get_request(path=path, url_param=payloads) def get_issue( self, issue_id_or_key: str, ) -> Response: """ 課題情報の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-issue/ :param issue_id_or_key: 課題のID または 課題キー :return: レスポンス """ path = self.base_path + '/{issue_id_or_key}'.format( issue_id_or_key=issue_id_or_key) return self.rs.send_get_request(path=path, url_param={}) def add_issue( self, project_id: int, summary: str, issue_type_id: int, priority_id: int, parent_issue_id: Optional[int] = None, description: Optional[str] = None, start_date: Optional[str] = None, due_date: Optional[str] = None, estimated_hours: Optional[int] = None, actual_hours: Optional[int] = None, category_id: Optional[List[int]] = None, version_id: Optional[List[int]] = None, milestone_id: Optional[List[int]] = None, assignee_id: Optional[int] = None, notified_user_id: List[int] = None, attachment_id: Optional[List[int]] = None, **kwargs, ) -> Response: """ 課題の追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-issue/ :param project_id: 課題を登録するプロジェクトのID :param summary: 課題の件名 :param issue_type_id: 課題の種別のID :param priority_id: 課題の優先度のID :param parent_issue_id: 課題の親課題のID :param description: 課題の詳細 :param start_date: 課題の開始日 (yyyy-MM-dd) :param due_date: 課題の期限日 (yyyy-MM-dd) :param estimated_hours: 課題の予定時間 :param actual_hours: 課題の実績時間 :param category_id: 課題のカテゴリーのID :param version_id: 課題の発生バージョンのID :param milestone_id: 課題のマイルストーンのID :param assignee_id: 課題の担当者のID :param notified_user_id: 課題の登録の通知を受け取るユーザーのID :param attachment_id: 添付ファイルの送信APIが返すID :param kwargs: カスタム属性を渡す customField_{id}=[value] または customField_{id}_otherValue=[value] の形式 :return: レスポンス """ path = self.base_path payloads = {} if project_id is not None: payloads['projectId'] = project_id if summary is not None: payloads['summary'] = summary if issue_type_id is not None: payloads['issueTypeId'] = issue_type_id if priority_id is not None: payloads['priorityId'] = priority_id if parent_issue_id is not None: payloads['parentIssueId'] = parent_issue_id if description is not None: payloads['description'] = description if start_date is not None: payloads['startDate'] = start_date if due_date is not None: payloads['dueDate'] = due_date if estimated_hours is not None: payloads['estimatedHours'] = estimated_hours if actual_hours is not None: payloads['actualHours'] = actual_hours if category_id is not None: payloads['categoryId[]'] = category_id if version_id is not None: payloads['versionId[]'] = version_id if milestone_id is not None: payloads['milestoneId[]'] = milestone_id if assignee_id is not None: payloads['assigneeId'] = assignee_id if notified_user_id is not None: payloads['notifiedUserId[]'] = notified_user_id if attachment_id is not None: payloads['attachmentId[]'] = attachment_id for key in kwargs: if re.match( '^customField_[0-9]+_other_value$|^customField_[0-9]+$', key) is None: raise ValueError('カスタム属性の指定方法が正しくありません') payloads[key] = kwargs[key] return self.rs.send_post_request(path=path, request_param=payloads) def update_issue( self, issue_id_or_key: str, summary: Optional[str] = None, parent_issue_id: Optional[int] = None, description: Optional[str] = None, status_id: Optional[int] = None, resolution_id: Optional[int] = None, start_date: Optional[str] = None, due_date: Optional[str] = None, estimated_hours: Optional[int] = None, actual_hours: Optional[int] = None, issue_type_id: Optional[int] = None, category_id: Optional[List[int]] = None, version_id: Optional[List[int]] = None, milestone_id: Optional[List[int]] = None, priority_id: Optional[int] = None, assignee_id: Optional[int] = None, notified_user_id: Optional[List[int]] = None, attachment_id: Optional[List[int]] = None, comment: Optional[str] = None, **kwargs, ) -> Response: """ 課題情報の更新 https://developer.nulab.com/ja/docs/backlog/api/2/update-issue/ :param issue_id_or_key: 課題のID または 課題キー :param summary: 課題の件名 :param parent_issue_id: 課題の親課題のID :param description: 課題の詳細 :param status_id: 状態のID :param resolution_id: 完了理由のID :param start_date: 課題の開始日 (yyyy-MM-dd) :param due_date: 課題の期限日 (yyyy-MM-dd) :param estimated_hours: 課題の予定時間 :param actual_hours: 課題の実績時間 :param issue_type_id: 課題の種別のID :param category_id: 課題のカテゴリーのID :param version_id: 課題の発生バージョンのID :param milestone_id: 課題のマイルストーンのID :param priority_id: 課題の優先度のID :param assignee_id: 課題の担当者のID :param notified_user_id: 課題の登録の通知を受け取るユーザーのID :param attachment_id: 添付ファイルの送信APIが返すID :param comment: コメント :param kwargs: カスタム属性を渡す customField_{id}=[value] または customField_{id}_otherValue=[value] の形式 :return: レスポンス """ path = self.base_path + '/{issue_id_or_key}'.format( issue_id_or_key=issue_id_or_key) payloads = {} if summary is not None: payloads['summary'] = summary if parent_issue_id is not None: payloads['parentIssueId'] = parent_issue_id if description is not None: payloads['description'] = description if status_id is not None: payloads['statusId'] = status_id if resolution_id is not None: payloads['resolutionId'] = resolution_id if start_date is not None: payloads['startDate'] = start_date if due_date is not None: payloads['dueDate'] = due_date if estimated_hours is not None: payloads['estimatedHours'] = estimated_hours if actual_hours is not None: payloads['actualHours'] = actual_hours if issue_type_id is not None: payloads['issueTypeId'] = issue_type_id if category_id is not None: payloads['categoryId[]'] = category_id if version_id is not None: payloads['versionId[]'] = version_id if milestone_id is not None: payloads['milestoneId[]'] = milestone_id if priority_id is not None: payloads['priorityId'] = priority_id if assignee_id is not None: payloads['assigneeId'] = assignee_id if notified_user_id is not None: payloads['notifiedUserId[]'] = notified_user_id if attachment_id is not None: payloads['attachmentId[]'] = attachment_id if comment is not None: payloads['comment'] = comment for key in kwargs: if re.match( '^customField_[0-9]+_other_value$|^customField_[0-9]+$', key) is None: raise ValueError('カスタム属性の指定方法が正しくありません') payloads[key] = kwargs[key] return self.rs.send_patch_request(path=path, request_param=payloads) def delete_issue( self, issue_id_or_key: str, ) -> Response: """ 課題の削除 https://developer.nulab.com/ja/docs/backlog/api/2/delete-issue/ :param issue_id_or_key: 課題のID または 課題キー :return: レスポンス """ path = self.base_path + '/{issue_id_or_key}'.format( issue_id_or_key=issue_id_or_key) return self.rs.send_delete_request(path=path, request_param={})
class WikiAttachment: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'wikis' _config = config if config else None self.rs = RequestSender(_config) def attach_file_to_wiki(self, wiki_id: int, attachment_id: Optional[List[int]] = None, ) -> Response: """ Wiki添付ファイルの追加 https://developer.nulab.com/ja/docs/backlog/api/2/attach-file-to-wiki/ :param wiki_id: WikiページのID :param attachment_id: 添付ファイルの送信APIが返すID :return: レスポンス """ path = self.base_path + '/{wiki_id}/attachments'.format(wiki_id=str(wiki_id)) payloads = {} if attachment_id is not None: payloads['attachmentId[]'] = attachment_id return self.rs.send_post_request(path=path, request_param=payloads) def get_wiki_page_attachment(self, wiki_id: int, attachment_id: Optional[int] = None, ) -> Tuple[str, Response]: """ Wiki添付ファイルのダウンロード https://developer.nulab.com/ja/docs/backlog/api/2/get-wiki-page-attachment/ :param wiki_id: WikiページのID :param attachment_id: 添付ファイルのID :return: 保存されたファイルのPATH """ path = self.base_path + '/{wiki_id}/attachments/{attachment_id}'\ .format(wiki_id=str(wiki_id), attachment_id=attachment_id) return self.rs.get_file(path=path, url_param={}) def get_list_of_wiki_attachments(self, wiki_id: int, ) -> Response: """ Wiki添付ファイル一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-list-of-wiki-attachments/ :param wiki_id: WikiページのID :return: レスポンス """ path = self.base_path + '/{wiki_id}/attachments'.format(wiki_id=str(wiki_id)) return self.rs.send_get_request(path=path, url_param={}) def remove_wiki_attachment(self, wiki_id: int, attachment_id: Optional[int] = None, ) -> Response: """ Wiki添付ファイルの削除 https://developer.nulab.com/ja/docs/backlog/api/2/remove-wiki-attachment/ :param wiki_id: WikiページのID :param attachment_id: 添付ファイルのID :return: レスポンス """ path = self.base_path + '/{wiki_id}/attachments/{attachment_id}'\ .format(wiki_id=wiki_id, attachment_id=attachment_id) return self.rs.send_delete_request(path=path, request_param={})
class IssueType: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'projects' _config = config if config else None self.rs = RequestSender(_config) def get_issue_type_list(self, project_id_or_key: str) -> Response: """ 種別一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-issue-type-list/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/issueTypes'.format( project_id_or_key=project_id_or_key) return self.rs.send_get_request(path=path, url_param={}) def update_issue_type(self, project_id_or_key: str, issue_id: int, name: Optional[str] = None, color: Optional[str] = None) -> Response: """ 種別情報の更新 https://developer.nulab.com/ja/docs/backlog/api/2/update-issue-type/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param issue_id: 種別のID :param name: 種別の名前 :param color: 種別の背景色 :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/issueTypes/{issue_id}' \ .format(project_id_or_key=project_id_or_key, issue_id=issue_id) payloads = {} if name is not None: payloads['name'] = name if color is not None: payloads['color'] = color return self.rs.send_patch_request(path=path, request_param=payloads) def add_issue_type(self, project_id_or_key: Optional[str] = None, name: Optional[str] = None, color: Optional[str] = None) -> Response: """ 種別の追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-issue-type/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param name: 種別の名前 :param color: 種別の背景色:以下から指定”#e30000””#990000””#934981””#814fbc””#2779ca””#007e9a””#7ea800””#ff9200””#ff3265””#666665” :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/issueTypes'.format( project_id_or_key=project_id_or_key) payloads = {} if name is not None: payloads['name'] = name if color is not None: payloads['color'] = color return self.rs.send_post_request(path=path, request_param=payloads) def delete_issue_type( self, project_id_or_key: Optional[str] = None, issue_id: Optional[int] = None, substitute_issue_type_id: Optional[int] = None) -> Response: """ 種別の削除 https://developer.nulab.com/ja/docs/backlog/api/2/delete-issue-type/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param issue_id: 種別のID :param substitute_issue_type_id: 紐づく課題を付け替える先の種別のID :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/issueTypes/{issue_id}' \ .format(project_id_or_key=project_id_or_key, issue_id=issue_id) payloads = {} if substitute_issue_type_id is not None: payloads['substituteIssueTypeId'] = substitute_issue_type_id return self.rs.send_delete_request(path=path, request_param=payloads)
class Wiki: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'wikis' _config = config if config else None self.rs = RequestSender(_config) def update_wiki_page(self, wiki_id: int, name: Optional[str] = None, content: Optional[str] = None, mail_notify: bool = False, ) -> Response: """ Wikiページ情報の更新 https://developer.nulab-inc.com/ja/docs/backlog/api/2/update-wiki-page/ :param wiki_id: WikiページのID :param name: ページ名 :param content: ページの内容 :param mail_notify: ページの更新をメールで通知する場合はtrue :return: レスポンス """ path = self.base_path + '/{wiki_id}'.format(wiki_id=wiki_id) if not (name or content): ValueError('更新される内容がありません') payloads = {'mailNotify': mail_notify} if name is not None: payloads['name'] = name if content is not None: payloads['content'] = content return self.rs.send_patch_request(path=path, request_param=payloads) def get_wiki_page(self, wiki_id: int, ) -> Response: """ Wikiページ情報の取得 https://developer.nulab-inc.com/ja/docs/backlog/api/2/get-wiki-page/ :param wiki_id: WikiページのID :return: レスポンス """ path = self.base_path + '/' + str(wiki_id) return self.rs.send_get_request(path=path) def add_wiki_page(self, project_id: int, name: str, content: str, mail_notify: Optional[bool] = None, ) -> Response: """ Wikiページの追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-wiki-page/ :param project_id: プロジェクトのID :param name: ページ名 :param content: ページの内容 :param mail_notify: ページの追加をメールで通知する場合はtrue :return: レスポンス """ path = self.base_path payloads = {'projectId': project_id, 'name': name, 'content': content} if mail_notify is not None: payloads['mailNotify'] = mail_notify return self.rs.send_post_request(path=path, request_param=payloads) def delete_wiki_page(self, wiki_id: int, mail_notify: Optional[bool] = None, ) -> Response: """ Wikiページの削除 https://developer.nulab.com/ja/docs/backlog/api/2/delete-wiki-page/ :param wiki_id: WikiページのID :param mail_notify: ページの削除をメールで通知する場合はtrue :return: レスポンス """ path = self.base_path + '/{wiki_id}'.format(wiki_id=wiki_id) payloads = {} if mail_notify is not None: payloads['mailNotify'] = mail_notify return self.rs.send_delete_request(path=path, request_param=payloads) def count_wiki_page(self, project_id_or_key: str, ) -> Response: """ Wikiページ数の取得 https://developer.nulab.com/ja/docs/backlog/api/2/count-wiki-page/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :return: レスポンス """ path = self.base_path + '/count' payloads = {} if project_id_or_key is not None: payloads['projectIdOrKey'] = project_id_or_key return self.rs.send_get_request(path=path, url_param=payloads) def get_wiki_page_list(self, project_id_or_key: Optional[str] = None, keyword: Optional[str] = None, ) -> Response: """ Wikiページ一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-wiki-page-list/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param keyword: 検索キーワード :return: レスポンス """ path = self.base_path payloads = {} if project_id_or_key is not None: payloads['projectIdOrKey'] = project_id_or_key if keyword is not None: payloads['keyword'] = keyword return self.rs.send_get_request(path=path, url_param=payloads) def get_wiki_page_tag_list(self, project_id_or_key: Optional[int] = None, ) -> Response: """ Wikiページタグ一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-wiki-page-tag-list/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :return: レスポンス """ path = self.base_path + '/tags' payloads = {} if project_id_or_key is not None: payloads['projectIdOrKey'] = project_id_or_key return self.rs.send_get_request(path=path, url_param=payloads) def get_wiki_page_history(self, wiki_id: Optional[int] = None, min_id: Optional[int] = None, max_id: Optional[int] = None, count: int = 20, order: str = 'desc', ) -> Response: """ Wikiページ更新履歴一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-wiki-page-history/ :param wiki_id: WikiページのID :param min_id: 最小ID :param max_id: 最大ID :param count: 取得上限(1-100) 指定が無い場合は20 :param order: “asc”または”desc” 指定が無い場合は”desc” :return: レスポンス """ path = self.base_path + '/{wiki_id}/history'.format(wiki_id=str(wiki_id)) payloads = {} if min_id is not None: payloads['minId'] = min_id if max_id is not None: payloads['maxId'] = max_id if count is not None: if not 1 <= count <= 100: raise ValueError('count(取得上限)は1-100の範囲で指定してください') if order is not None: if order not in {'desc', 'asc'}: raise ValueError('order は desc または asc のみが使用できます') payloads['order'] = order return self.rs.send_get_request(path=path, url_param=payloads) def get_wiki_page_star(self, wiki_id: Optional[int] = None, ) -> Response: """ Wikiページのスター一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-wiki-page-star/ :param wiki_id: WikiページのID :return: レスポンス """ path = self.base_path + '/{wiki_id}/stars'.format(wiki_id=str(wiki_id)) return self.rs.send_get_request(path=path, url_param={})
class Category: def __init__(self, config: Optional[BacklogConfigure] = None): self.base_path = 'projects' _config = config if config else None self.rs = RequestSender(_config) def get_category_list(self, project_id_or_key: str, ) -> Response: """ カテゴリー一覧の取得 https://developer.nulab.com/ja/docs/backlog/api/2/get-category-list/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/categories'.format(project_id_or_key=project_id_or_key) return self.rs.send_get_request(path=path, url_param={}) def update_category(self, project_id_or_key: str, category_id: int, name: str, ) -> Response: """ カテゴリー情報の更新 https://developer.nulab.com/ja/docs/backlog/api/2/update-category/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param category_id: カテゴリーのID :param name: カテゴリーの名前 :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/categories/{category_id}'\ .format(project_id_or_key=project_id_or_key, category_id=category_id) payloads = {'name': name} return self.rs.send_patch_request(path=path, request_param=payloads) def add_category(self, project_id_or_key: str, name: str, ) -> Response: """ カテゴリーの追加 https://developer.nulab.com/ja/docs/backlog/api/2/add-category/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param name: カテゴリーの名前 :return: レスポンス """ path = self.base_path + '/{project_id_or_key}/categories'.format(project_id_or_key=project_id_or_key) payloads = {'name': name} return self.rs.send_post_request(path=path, request_param=payloads) def delete_category(self, project_id_or_key: str, category_id: int) -> Response: """ カテゴリーの削除 https://developer.nulab.com/ja/docs/backlog/api/2/delete-category/ :param project_id_or_key: プロジェクトのID または プロジェクトキー :param category_id: カテゴリーのID :return: レスポンス """ path = self.base_path + '/projects/{project_id_or_key}/categories/{category_id}'\ .format(project_id_or_key=project_id_or_key, category_id=category_id) return self.rs.send_delete_request(path=path, request_param={})