"""
GitCode Issue API
"""
from typing import Any, Dict, List, Optional, Union
from datetime import datetime
from ..base.client import BaseAPI
class IssueAPI(BaseAPI):
"""Issue API"""
async def list_issues(
self,
owner: str,
repo: str,
state: Optional[str] = None,
labels: Optional[Union[str, List[str]]] = None,
sort: Optional[str] = None,
direction: Optional[str] = None,
since: Optional[Union[str, datetime]] = None,
per_page: Optional[int] = None,
page: Optional[int] = None
) -> List[Dict[str, Any]]:
"""
获取仓库的Issue列表
Args:
owner: 仓库所有者
repo: 仓库名称
state: Issue状态 ('open'|'closed'|'all')
labels: 标签过滤(逗号分隔字符串或标签列表)
sort: 排序字段 ('created'|'updated'|'comments')
direction: 排序方向 ('asc'|'desc')
since: 过滤日期(ISO 8601格式字符串或datetime对象)
per_page: 每页结果数
page: 页码
Returns:
Issue列表
"""
if isinstance(labels, list):
labels_str = ",".join(labels)
else:
labels_str = labels
if isinstance(since, datetime):
since_str = since.isoformat()
else:
since_str = since
params = {
"state": state,
"labels": labels_str,
"sort": sort,
"direction": direction,
"since": since_str,
"per_page": per_page,
"page": page
}
params = {k: v for k, v in params.items() if v is not None}
return await self.request("GET", f"/repos/{owner}/{repo}/issues", params=params)
async def get_issue(self, owner: str, repo: str, issue_number: int) -> Dict[str, Any]:
"""
获取特定Issue的详细信息
Args:
owner: 仓库所有者
repo: 仓库名称
issue_number: Issue编号
Returns:
Issue信息
"""
return await self.request("GET", f"/repos/{owner}/{repo}/issues/{issue_number}")
async def create_issue(
self,
owner: str,
repo: str,
title: str,
body: Optional[str] = None,
assignees: Optional[List[str]] = None,
milestone: Optional[int] = None,
labels: Optional[List[str]] = None
) -> Dict[str, Any]:
"""
创建新Issue
Args:
owner: 仓库所有者
repo: 仓库名称
title: Issue标题
body: Issue内容
assignees: 指派人用户名列表
milestone: 里程碑ID
labels: 标签列表
Returns:
创建的Issue信息
"""
data = {
"title": title,
"body": body,
"assignees": assignees,
"milestone": milestone,
"labels": labels
}
data = {k: v for k, v in data.items() if v is not None}
return await self.request("POST", f"/repos/{owner}/{repo}/issues", data=data)
async def update_issue(
self,
owner: str,
repo: str,
issue_number: int,
title: Optional[str] = None,
body: Optional[str] = None,
state: Optional[str] = None,
assignees: Optional[List[str]] = None,
milestone: Optional[int] = None,
labels: Optional[List[str]] = None
) -> Dict[str, Any]:
"""
更新Issue
Args:
owner: 仓库所有者
repo: 仓库名称
issue_number: Issue编号
title: 新标题
body: 新内容
state: 新状态 ('open'|'closed')
assignees: 指派人用户名列表
milestone: 里程碑ID
labels: 标签列表
Returns:
更新后的Issue信息
"""
data = {
"title": title,
"body": body,
"state": state,
"assignees": assignees,
"milestone": milestone,
"labels": labels
}
data = {k: v for k, v in data.items() if v is not None}
return await self.request("PATCH", f"/repos/{owner}/{repo}/issues/{issue_number}", data=data)
async def list_comments(
self,
owner: str,
repo: str,
issue_number: int,
since: Optional[Union[str, datetime]] = None,
per_page: Optional[int] = None,
page: Optional[int] = None
) -> List[Dict[str, Any]]:
"""
获取Issue评论
Args:
owner: 仓库所有者
repo: 仓库名称
issue_number: Issue编号
since: 过滤日期(ISO 8601格式字符串或datetime对象)
per_page: 每页结果数
page: 页码
Returns:
评论列表
"""
if isinstance(since, datetime):
since_str = since.isoformat()
else:
since_str = since
params = {
"since": since_str,
"per_page": per_page,
"page": page
}
params = {k: v for k, v in params.items() if v is not None}
return await self.request("GET", f"/repos/{owner}/{repo}/issues/{issue_number}/comments", params=params)
async def add_comment(self, owner: str, repo: str, issue_number: int, body: str) -> Dict[str, Any]:
"""
添加Issue评论
Args:
owner: 仓库所有者
repo: 仓库名称
issue_number: Issue编号
body: 评论内容
Returns:
创建的评论信息
"""
data = {"body": body}
return await self.request("POST", f"/repos/{owner}/{repo}/issues/{issue_number}/comments", data=data)
async def update_comment(self, owner: str, repo: str, comment_id: int, body: str) -> Dict[str, Any]:
"""
更新Issue评论
Args:
owner: 仓库所有者
repo: 仓库名称
comment_id: 评论ID
body: 新评论内容
Returns:
更新后的评论信息
"""
data = {"body": body}
return await self.request("PATCH", f"/repos/{owner}/{repo}/issues/comments/{comment_id}", data=data)
async def delete_comment(self, owner: str, repo: str, comment_id: int) -> None:
"""
删除Issue评论
Args:
owner: 仓库所有者
repo: 仓库名称
comment_id: 评论ID
"""
await self.request("DELETE", f"/repos/{owner}/{repo}/issues/comments/{comment_id}")
async def list_labels(self, owner: str, repo: str) -> List[Dict[str, Any]]:
"""
获取仓库标签列表
Args:
owner: 仓库所有者
repo: 仓库名称
Returns:
标签列表
"""
return await self.request("GET", f"/repos/{owner}/{repo}/labels")
async def create_label(
self,
owner: str,
repo: str,
name: str,
color: str,
description: Optional[str] = None
) -> Dict[str, Any]:
"""
创建仓库标签
Args:
owner: 仓库所有者
repo: 仓库名称
name: 标签名称
color: 颜色代码(无#前缀,例如"f29513")
description: 标签描述
Returns:
创建的标签信息
"""
data = {
"name": name,
"color": color,
"description": description
}
data = {k: v for k, v in data.items() if v is not None}
return await self.request("POST", f"/repos/{owner}/{repo}/labels", data=data)
async def get_label(self, owner: str, repo: str, name: str) -> Dict[str, Any]:
"""
获取标签信息
Args:
owner: 仓库所有者
repo: 仓库名称
name: 标签名称
Returns:
标签信息
"""
return await self.request("GET", f"/repos/{owner}/{repo}/labels/{name}")
async def update_label(
self,
owner: str,
repo: str,
current_name: str,
new_name: Optional[str] = None,
color: Optional[str] = None,
description: Optional[str] = None
) -> Dict[str, Any]:
"""
更新标签
Args:
owner: 仓库所有者
repo: 仓库名称
current_name: 当前标签名称
new_name: 新标签名称
color: 新颜色代码
description: 新描述
Returns:
更新后的标签信息
"""
data = {
"new_name": new_name,
"color": color,
"description": description
}
data = {k: v for k, v in data.items() if v is not None}
return await self.request("PATCH", f"/repos/{owner}/{repo}/labels/{current_name}", data=data)
async def delete_label(self, owner: str, repo: str, name: str) -> None:
"""
删除标签
Args:
owner: 仓库所有者
repo: 仓库名称
name: 标签名称
"""
await self.request("DELETE", f"/repos/{owner}/{repo}/labels/{name}")
async def list_milestones(
self,
owner: str,
repo: str,
state: Optional[str] = None,
sort: Optional[str] = None,
direction: Optional[str] = None
) -> List[Dict[str, Any]]:
"""
获取仓库里程碑列表
Args:
owner: 仓库所有者
repo: 仓库名称
state: 里程碑状态 ('open'|'closed'|'all')
sort: 排序字段 ('due_on'|'completeness')
direction: 排序方向 ('asc'|'desc')
Returns:
里程碑列表
"""
params = {
"state": state,
"sort": sort,
"direction": direction
}
params = {k: v for k, v in params.items() if v is not None}
return await self.request("GET", f"/repos/{owner}/{repo}/milestones", params=params)