85 lines
3 KiB
Python
85 lines
3 KiB
Python
from typing import Annotated, Any, cast
|
|
|
|
from arcade.sdk import ToolContext, tool
|
|
from arcade.sdk.auth import Atlassian
|
|
|
|
import arcade_jira.cache as cache
|
|
from arcade_jira.client import JiraClient
|
|
from arcade_jira.exceptions import NotFoundError
|
|
from arcade_jira.utils import (
|
|
add_pagination_to_response,
|
|
clean_project_dict,
|
|
remove_none_values,
|
|
)
|
|
|
|
|
|
@tool(requires_auth=Atlassian(scopes=["read:jira-work"]))
|
|
async def list_projects(
|
|
context: ToolContext,
|
|
limit: Annotated[
|
|
int, "The maximum number of projects to return. Min of 1, Max of 50. Defaults to 50."
|
|
] = 50,
|
|
offset: Annotated[
|
|
int, "The number of projects to skip. Defaults to 0 (starts from the first project)"
|
|
] = 0,
|
|
) -> Annotated[dict[str, Any], "Information about the projects"]:
|
|
"""Browse projects available in Jira."""
|
|
return cast(
|
|
dict[str, Any], await search_projects(context, keywords=None, limit=limit, offset=offset)
|
|
)
|
|
|
|
|
|
@tool(requires_auth=Atlassian(scopes=["read:jira-work"]))
|
|
async def search_projects(
|
|
context: ToolContext,
|
|
keywords: Annotated[
|
|
str | None,
|
|
"The keywords to search for projects. Matches against project name and key "
|
|
"(case insensitive). Defaults to None (no keywords filter).",
|
|
] = None,
|
|
limit: Annotated[
|
|
int, "The maximum number of projects to return. Min of 1, Max of 50. Defaults to 50."
|
|
] = 50,
|
|
offset: Annotated[
|
|
int, "The number of projects to skip. Defaults to 0 (starts from the first project)"
|
|
] = 0,
|
|
) -> Annotated[dict[str, Any], "Information about the projects"]:
|
|
"""Get the details of all Jira projects."""
|
|
limit = max(min(limit, 50), 1)
|
|
client = JiraClient(context.get_auth_token_or_empty())
|
|
api_response = await client.get(
|
|
"/project/search",
|
|
params=remove_none_values({
|
|
"expand": ",".join([
|
|
"description",
|
|
"url",
|
|
]),
|
|
"maxResults": limit,
|
|
"startAt": offset,
|
|
"query": keywords,
|
|
}),
|
|
)
|
|
cloud_name = cache.get_cloud_name(context.get_auth_token_or_empty())
|
|
projects = [clean_project_dict(project, cloud_name) for project in api_response["values"]]
|
|
response = {
|
|
"projects": projects,
|
|
"isLast": api_response.get("isLast"),
|
|
}
|
|
return add_pagination_to_response(response, projects, limit, offset)
|
|
|
|
|
|
@tool(requires_auth=Atlassian(scopes=["read:jira-work"]))
|
|
async def get_project_by_id(
|
|
context: ToolContext,
|
|
project: Annotated[str, "The ID or key of the project to retrieve"],
|
|
) -> Annotated[dict[str, Any], "Information about the project"]:
|
|
"""Get the details of a Jira project by its ID or key."""
|
|
client = JiraClient(context.get_auth_token_or_empty())
|
|
|
|
try:
|
|
response = await client.get(f"project/{project}")
|
|
except NotFoundError:
|
|
return {"error": f"Project not found: {project}"}
|
|
|
|
cloud_name = cache.get_cloud_name(context.get_auth_token_or_empty())
|
|
return {"project": clean_project_dict(response, cloud_name)}
|