Skip to content

Commit

Permalink
feat: add plenty of methods for work with queues and issues
Browse files Browse the repository at this point in the history
  • Loading branch information
danfimov committed Sep 20, 2023
1 parent 6ae1462 commit d27c4dc
Show file tree
Hide file tree
Showing 18 changed files with 393 additions and 17 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,27 @@
# ya_tracker_client
Async Yandex Tracker Client


# Нереализованная функциональность

## Тикеты

- [ ] Перенести задачу в другую очередь
- [ ] Узнать количество задач
- [ ] Найти задачи
- [ ] Освободить ресурсы просмотра прокрутки
- [ ] Получить приоритеты
- [ ] Получить переходы
- [ ] Выполнить переход в статус
- [ ] Получить историю изменений задачи

## Связи тикетов

- [ ] Создание
- [ ] Получение
- [ ] Удаление

## Очереди

- [ ] Создание
- [ ] Автоматизация (разбить на подзадачи)
3 changes: 2 additions & 1 deletion examples/get_issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ async def main() -> None:
organisation_id=API_ORGANISATION_ID,
oauth_token=API_TOKEN,
)
issue = await client.get_issue('TRACKER-1')
# issue = await client.get_issue('TRACKER-1')
issue =await client.create_issue('New issue', 'TRACKER')
print(issue)
await client.stop()

Expand Down
41 changes: 31 additions & 10 deletions ya_tracker_client/domain/entities/issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
from pydantic import AliasChoices, Field

from ya_tracker_client.domain.entities.base import AbstractEntity
from ya_tracker_client.domain.entities.issue_type import IssueType
from ya_tracker_client.domain.entities.priority import Priority
from ya_tracker_client.domain.entities.queue import Queue
from ya_tracker_client.domain.entities.queue import QueueIdentifier, QueueShort
from ya_tracker_client.domain.entities.sprint import Sprint
from ya_tracker_client.domain.entities.status import Status
from ya_tracker_client.domain.entities.user import User
Expand All @@ -17,13 +18,6 @@ class IssueShort(AbstractEntity):
display: str


class IssueType(AbstractEntity):
url: str = Field(validation_alias=AliasChoices("self", "url"))
id: str
key: str
display: str


class Issue(AbstractEntity):
url: str = Field(validation_alias=AliasChoices("self", "url"))
id: str
Expand All @@ -37,8 +31,8 @@ class Issue(AbstractEntity):
type: IssueType
priority: Priority
followers: list[User] | None = None
queue: Queue
previous_queue: Queue | None = None
queue: QueueShort
previous_queue: QueueShort | None = None
favorite: bool
assignee: User | None = None

Expand All @@ -52,3 +46,30 @@ class Issue(AbstractEntity):
status: Status
previous_status: Status | None = None
direction: str | None = None


class IssueCreate(AbstractEntity):
summary: str
queue: QueueIdentifier | str | int
parent: IssueShort | str | None = None
description: str | None = None
sprint: list[Sprint | str] | None = None
type: IssueType | None = None
priority: Priority | None = None
followers: list[User | str] | None = None
assignee: list[User | str] | None = None
unique: str | None = None
attachment_ids: list[str] | None = Field(
default=None,
validation_alias=AliasChoices("attachmentIds", "attachment_ids"),
)


class IssueEdit(AbstractEntity):
summary: str | None = None
parent: IssueShort | str | None = None
description: str | None = None
sprint: list[Sprint | str] | None = None
type: IssueType | None = None
priority: Priority | None = None
followers: list[User | str] | None = None
10 changes: 10 additions & 0 deletions ya_tracker_client/domain/entities/issue_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from pydantic import AliasChoices, Field

from ya_tracker_client.domain.entities.base import AbstractEntity


class IssueType(AbstractEntity):
url: str = Field(validation_alias=AliasChoices("self", "url"))
id: str
key: str
display: str
12 changes: 12 additions & 0 deletions ya_tracker_client/domain/entities/issue_type_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from pydantic import AliasChoices, Field

from ya_tracker_client.domain.entities.base import AbstractEntity
from ya_tracker_client.domain.entities.issue_type import IssueType
from ya_tracker_client.domain.entities.resolution import ResolutionShort
from ya_tracker_client.domain.entities.workflow import WorkflowShort


class IssueTypeConfig(AbstractEntity):
issue_type: IssueType = Field(validation_alias=AliasChoices("issueType", "issue_type"))
workflow: WorkflowShort
resolutions: list[ResolutionShort]
57 changes: 56 additions & 1 deletion ya_tracker_client/domain/entities/queue.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,65 @@
from pydantic import AliasChoices, Field

from ya_tracker_client.domain.entities.base import AbstractEntity
from ya_tracker_client.domain.entities.issue_type import IssueType
from ya_tracker_client.domain.entities.issue_type_config import IssueTypeConfig
from ya_tracker_client.domain.entities.priority import Priority
from ya_tracker_client.domain.entities.user import User
from ya_tracker_client.domain.entities.workflow import WorkflowShort


class Queue(AbstractEntity):
class QueueIdentifier(AbstractEntity):
id: str
key: str


class QueueShort(AbstractEntity):
url: str = Field(validation_alias=AliasChoices("self", "url"))
id: str
key: str
display: str


class QueueVersion(AbstractEntity):
url: str = Field(validation_alias=AliasChoices("self", "url"))
id: str
display: str


class Queue(AbstractEntity):
url: str = Field(validation_alias=AliasChoices("self", "url"))
id: int
key: str
version: int
name: str
description: str | None = None # TODO: string in documentation, but may be missing in response - TB145879
lead: User
assign_auto: bool = Field(validation_alias=AliasChoices("assignAuto", "assign_auto"))
default_type: IssueType = Field(validation_alias=AliasChoices("defaultType", "default_type"))
default_priority: Priority = Field(validation_alias=AliasChoices("defaultPriority", "default_priority"))
team_users: list[User] = Field(default=list, validation_alias=AliasChoices("teamUsers", "team_users"))
issue_types: list[IssueType] = Field(default=list, validation_alias=AliasChoices("issueTypes", "issue_types"))
versions: list[QueueVersion] = Field(default=list)
workflows: list[WorkflowShort] = Field(default=list)
deny_voting: bool = Field(validation_alias=AliasChoices("denyVoting", "deny_voting"))
issue_types_config: list[IssueTypeConfig] = Field(
default=list,
validation_alias=AliasChoices("issueTypesConfig", "issue_types_config"),
)

# TODO: documentation does not contain this fields - TB145879
deny_conductor_autolink: bool = Field(
validation_alias=AliasChoices("denyConductorAutolink", "deny_conductor_autolink"),
)
deny_tracker_auto_link: bool = Field(
validation_alias=AliasChoices("denyTrackerAutolink", "deny_tracker_auto_link"),
)
use_component_permissions_intersection: bool = Field(
validation_alias=AliasChoices("useComponentPermissionsIntersection", "use_component_permissions_intersection"),
)
workflow_actions_style: str = Field(
validation_alias=AliasChoices("workflowActionsStyle", "workflow_actions_style"),
)
use_last_signature: bool = Field(
validation_alias=AliasChoices("useLastSignature", "use_last_signature"),
)
35 changes: 35 additions & 0 deletions ya_tracker_client/domain/entities/queue_field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from pydantic import AliasChoices, Field

from ya_tracker_client.domain.entities.base import AbstractEntity
from ya_tracker_client.domain.entities.queue_field_category import QueueFieldCategory
from ya_tracker_client.domain.entities.queue_field_options_provider import QueueFieldOptionsProvider
from ya_tracker_client.domain.entities.queue_field_query_provider import QueueFieldQueryProvider
from ya_tracker_client.domain.entities.queue_field_schema import QueueFieldSchema
from ya_tracker_client.domain.entities.queue_field_suggest_provider import QueueFieldSuggestProvider


class QueueField(AbstractEntity):
url: str = Field(validation_alias=AliasChoices("self", "url"))
id: str
name: str
version: int
field_schema: QueueFieldSchema = Field(
validation_alias=AliasChoices("schema"),
)
readonly: bool
options: bool
suggest: bool
options_provider: QueueFieldOptionsProvider | None = Field( # TODO: not required in response - not documented
default=None, validation_alias=AliasChoices("optionsProvider", "options_provider"),
)
query_provider: QueueFieldQueryProvider | None = Field(
default=None, validation_alias=AliasChoices("queryProvider", "query_provider"),
)
order: int

# TODO: documentation does not contain this fields
suggest_provider: QueueFieldSuggestProvider | None = Field(
default=None, validation_alias=AliasChoices("suggestProvider", "suggest_provider"),
)
type: str
category: QueueFieldCategory
9 changes: 9 additions & 0 deletions ya_tracker_client/domain/entities/queue_field_category.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from pydantic import AliasChoices, Field

from ya_tracker_client.domain.entities.base import AbstractEntity


class QueueFieldCategory(AbstractEntity):
url: str = Field(validation_alias=AliasChoices("self", "url"))
id: str
display: str
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from pydantic import Field

from ya_tracker_client.domain.entities.base import AbstractEntity


class QueueFieldOptionsProvider(AbstractEntity):
type: str
values: list = Field(default=list)
defaults: list = Field(default=list)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from ya_tracker_client.domain.entities.base import AbstractEntity


class QueueFieldQueryProvider(AbstractEntity):
type: str
9 changes: 9 additions & 0 deletions ya_tracker_client/domain/entities/queue_field_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from ya_tracker_client.domain.entities.base import AbstractEntity


class QueueFieldSchema(AbstractEntity):
type: str # TODO: "float" or "string" values - maybe better to replace with enum
required: bool | None = None # TODO: bool in documentation, but may be missing in response

# TODO: documentation does not contain this fields
items: str | None = None
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from ya_tracker_client.domain.entities.base import AbstractEntity


class QueueFieldSuggestProvider(AbstractEntity):
type: str
19 changes: 19 additions & 0 deletions ya_tracker_client/domain/entities/queue_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from datetime import date

from pydantic import AliasChoices, Field

from ya_tracker_client.domain.entities.base import AbstractEntity
from ya_tracker_client.domain.entities.queue import QueueShort


class QueueVersion(AbstractEntity):
url: str = Field(validation_alias=AliasChoices("self", "url"))
id: int
version: int
queue: QueueShort
name: str
description: str | None = None # TODO: string in documentation, but may be missing in response - TB145879
start_date: date | None = Field(default=None, validation_alias=AliasChoices("startDate", "start_date"))
due_date: date | None = Field(default=None, validation_alias=AliasChoices("dueDate", "due_date"))
released: bool
archived: bool
10 changes: 10 additions & 0 deletions ya_tracker_client/domain/entities/resolution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from pydantic import AliasChoices, Field

from ya_tracker_client.domain.entities.base import AbstractEntity


class ResolutionShort(AbstractEntity):
url: str = Field(validation_alias=AliasChoices("self", "url"))
id: str
key: str
display: str
10 changes: 10 additions & 0 deletions ya_tracker_client/domain/entities/workflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from pydantic import AliasChoices, Field

from ya_tracker_client.domain.entities.base import AbstractEntity


class WorkflowShort(AbstractEntity):
url: str = Field(validation_alias=AliasChoices("self", "url"))
id: str
key: str
display: str
63 changes: 59 additions & 4 deletions ya_tracker_client/domain/repositories/issue.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,74 @@
from json import loads

from ya_tracker_client.domain.entities.issue import Issue
from ya_tracker_client.domain.entities.issue import Issue, IssueCreate, IssueEdit, IssueShort
from ya_tracker_client.domain.entities.issue_type import IssueType
from ya_tracker_client.domain.entities.priority import Priority
from ya_tracker_client.domain.entities.queue import QueueIdentifier
from ya_tracker_client.domain.entities.sprint import Sprint
from ya_tracker_client.domain.entities.user import User
from ya_tracker_client.domain.repositories.base import EntityRepository


class IssueRepository(EntityRepository):
async def get_issue(self, issue_id: str) -> Issue:
"""
Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/issues/get-issue
:param issue_id: identifier of the issue.
:return: issue DTO.
"""
raw_response = await self._client.request(
method="GET",
uri=f"/issues/{issue_id}",
)
return Issue(**loads(raw_response))

async def create_issue(
self,
summary: str,
queue: QueueIdentifier | str | int,
parent: IssueShort | str | None = None,
description: str | None = None,
sprint: list[Sprint | str] | None = None,
issue_type: IssueType | None = None,
priority: Priority | None = None,
followers: list[User | str] | None = None,
assignee: list[User | str] | None = None,
unique: str | None = None,
attachment_ids: list[str] | None = None,
) -> Issue:
"""
Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/issues/create-issue#queue
"""
raw_response = await self._client.request(
method="POST",
uri="/issues/",
payload=IssueCreate(
summary=summary,
queue=queue,
parent=parent,
description=description,
sprint=sprint,
type=issue_type,
priority=priority,
followers=followers,
assignee=assignee,
unique=unique,
attachment_ids=attachment_ids,
).model_dump(exclude_none=True),
)
return Issue(**loads(raw_response))

async def edit_issue(
self,
issue_id: str,
version: int | None = None,
**kwargs,
) -> Issue:
"""
Yandex Cloud documentation for method: https://cloud.yandex.ru/docs/tracker/concepts/issues/patch-issue
"""
raw_response = await self._client.request(
method="PATCH",
uri=f"/issues/{issue_id}",
params={"version": version} if version is not None else None,
payload=IssueEdit(**kwargs).model_dump(exclude_unset=True),
)
return Issue(**loads(raw_response))
Loading

0 comments on commit d27c4dc

Please sign in to comment.