Skip to content

Commit

Permalink
feat: add support for some actions with issues
Browse files Browse the repository at this point in the history
  • Loading branch information
danfimov committed Oct 1, 2023
1 parent 74da0fc commit 5c825a8
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 2 deletions.
4 changes: 4 additions & 0 deletions examples/get_test_entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ async def main() -> None:
await client.get_user(uid=me.uid)
await client.get_users()
await client.get_issue('TRACKER-1')
await client.get_issue('TRACKER-1', expand='transitions')
await client.get_issue('TRACKER-1', expand='attachments')
await client.get_issue_transitions('TRACKER-1')
await client.get_queue('TRACKER')
await client.get_issue_relationships('TRACKER-1')
Expand All @@ -37,6 +39,8 @@ async def main() -> None:
await client.get_external_applications()
await client.get_external_links("TRACKER-1")
await client.get_macros('TRACKER')
await client.find_number_of_issues(issue_filter={'queue': 'TRACKER', "assignee": "empty()"})
await client.get_history_issue_changes('TRACKER-1')

await client.stop()

Expand Down
6 changes: 6 additions & 0 deletions ya_tracker_client/domain/entities/attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@ class Attachment(AbstractEntity):
mimetype: str = Field(..., examples=["text/plain", "image/png"])
size: int
metadata: AttachmentMetadata | None = None


class AttachmentShort(AbstractEntity):
url: str
id: int
display: str
13 changes: 13 additions & 0 deletions ya_tracker_client/domain/entities/issue.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from datetime import datetime
from typing import Any

from pydantic import Field

from ya_tracker_client.domain.entities.attachment import AttachmentShort
from ya_tracker_client.domain.entities.base import AbstractEntity
from ya_tracker_client.domain.entities.checklist import ChecklistItem
from ya_tracker_client.domain.entities.issue_status import IssueStatus
Expand All @@ -10,6 +12,7 @@
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.transition import TransitionShort
from ya_tracker_client.domain.entities.user import UserShort


Expand Down Expand Up @@ -49,6 +52,9 @@ class Issue(AbstractEntity):
previous_status: Status | None = None
direction: str | None = None

transitions: list[TransitionShort] = Field(default_factory=list)
attachments: list[AttachmentShort] = Field(default_factory=list)


class IssueCreate(AbstractEntity):
summary: str
Expand Down Expand Up @@ -103,3 +109,10 @@ class IssueWithChecklist(AbstractEntity):
deadline: datetime | None = None

checklist_items: list[ChecklistItem] = Field(default_factory=list)


class IssueFindParameters(AbstractEntity):
filter: dict[str, Any] | None = None
query: str | None = None
keys: str | None = None
queue: str | None = None
39 changes: 39 additions & 0 deletions ya_tracker_client/domain/entities/issue_change_history.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from datetime import datetime

from pydantic import Field

from ya_tracker_client.domain.entities.base import AbstractEntity
from ya_tracker_client.domain.entities.issue import IssueShort
from ya_tracker_client.domain.entities.issue_field import IssueFieldShort
from ya_tracker_client.domain.entities.user import UserShort


class FieldChangeHistoryState(AbstractEntity):
id: str
url: str
key: str
display: str


class FieldChangeHistory(AbstractEntity):
field: IssueFieldShort
change_from: FieldChangeHistoryState | str | list | None = Field(default=None, alias="from")
change_to: FieldChangeHistoryState | str | list | None = Field(default=None, alias="to")


class IssueChangeHistory(AbstractEntity):
id: str
url: str
issue: IssueShort
updated_at: datetime
updated_by: UserShort
transport: str
type: str
fields: list[FieldChangeHistory] = Field(default_factory=list)


class IssueChangeHistoryParameters(AbstractEntity):
id: str | None = None
per_page: int = 50
field: str | None = None
type: str | None = None
6 changes: 6 additions & 0 deletions ya_tracker_client/domain/entities/transition.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ class Transition(AbstractEntity):
id: str
to: IssueStatus
display: str


class TransitionShort(AbstractEntity):
url: str
id: str
display: str
162 changes: 160 additions & 2 deletions ya_tracker_client/domain/repositories/issue.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from ya_tracker_client.domain.entities.issue import Issue, IssueCreate, IssueEdit, IssueShort
from typing import Any

from ya_tracker_client.domain.entities.issue import Issue, IssueCreate, IssueEdit, IssueFindParameters, IssueShort
from ya_tracker_client.domain.entities.issue_change_history import IssueChangeHistory, IssueChangeHistoryParameters
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
Expand All @@ -9,13 +12,14 @@


class IssueRepository(EntityRepository):
async def get_issue(self, issue_id: str) -> Issue:
async def get_issue(self, issue_id: str, expand: str = "") -> Issue:
"""
YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/get-issue
"""
raw_response = await self._client.request(
method="GET",
uri=f"/issues/{issue_id}",
params={"expand": expand},
)
return self._decode(raw_response, Issue)

Expand Down Expand Up @@ -98,3 +102,157 @@ async def get_issue_transitions(
uri=f"/issues/{issue_id}/transitions/",
)
return self._decode(raw_response, Transition, plural=True)

async def move_issue_to_another_queue(
self,
issue_id: str,
queue_id: str,
notify: bool = True,
notify_author: bool = False,
move_all_fields: bool = False,
initial_status: bool = False,
expand: str | None = None,
**kwargs,
) -> Issue:
"""
Move an issue to a different queue.
Before executing the method, make sure the user has permission
to edit the issues to be moved and is allowed to create them in
the new queue.
Warning!
If an issue you want to move has a type and status that are
missing in the target queue, no transfer will be made. To reset
the issue status to the initial value when moving it, use the
InitialStatus parameter.
By default, when an issue is moved, the values of its
components, versions, and projects are cleared. If the new queue
has the same values of the fields specified, use the
MoveAllFields parameter to move the components, versions, and
projects.
If the issue has the local field values specified, they will be
reset when moving the issue to a different queue.
You can use the kwargs if you need to change the
parameters of the issue being moved. The kwargs has the
same format as when editing issues.
YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/move-issue
"""
raw_response = await self._client.request(
method="POST",
uri=f"/issues/{issue_id}/_move",
params={
"queue": queue_id,
"notify": str(notify),
"notifyAuthor": str(notify_author),
"moveAllFields": str(move_all_fields),
"initialStatus": str(initial_status),
"expand": expand or "",
},
payload=IssueEdit(**kwargs).model_dump(exclude_unset=True),
)
return self._decode(raw_response, Issue)

async def find_number_of_issues(self, issue_filter: dict[str, Any] | None = None, query: str | None = None) -> int:
"""
Use this method to find out how many issues meet the criteria in your request.
YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/count-issues
"""
raw_response = await self._client.request(
method="POST",
uri="/issues/_count",
payload={
"filter": issue_filter,
"query": query,
},
)
return int(raw_response)

async def release_scroll_view_resources(self, scroll_id: str, scroll_token: str) -> None:
"""
YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/search-release
:param scroll_id: ID of the page with scroll results. The ID value is taken from the `X-Scroll-Id` header of the response to the search for issues request.
:param scroll_token: token that certifies that the request belongs to the current user. The ID value is taken from the `X-Scroll-Token` header of the response to the search for issues request.
:return: None
""" # noqa: E501
await self._client.request(
method="POST",
uri="/system/search/scroll/_clear",
payload={scroll_id: scroll_token},
)

async def make_status_transition(
self,
issue_id: str,
transition_id: int | str,
comment: str,
**kwargs,
) -> list[Transition]:
"""
YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/new-transition
"""
payload = {"comment": comment}
payload.update(kwargs)
raw_response = await self._client.request(
method="POST",
uri=f"/issues/{issue_id}/transitions/{transition_id}/_execute",
payload=payload,
)
return self._decode(raw_response, Transition, plural=True)

async def get_history_issue_changes(
self,
issue_id: str,
change_id: str | None = None,
per_page: int = 50,
field: str | None = None,
change_type: str | None = None,
) -> list[IssueChangeHistory]:
"""
YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/get-changelog
"""
raw_response = await self._client.request(
method="GET",
uri=f"/issues/{issue_id}/changelog",
payload=IssueChangeHistoryParameters(
id=change_id,
per_page=per_page,
field=field,
type=change_type,
).model_dump(exclude_none=True, by_alias=True),
)
return self._decode(raw_response, IssueChangeHistory, plural=True)

async def find_issues(
self,
issue_filter: dict[str, str] | None = None,
query: str | None = None,
order: str | None = None,
expand: str | None = None,
keys: str | None = None,
queue: str | None = None,
) -> list[Issue]:
params = {}
if order:
params["order"] = order
if expand:
params["expand"] = expand

raw_response = await self._client.request(
method="POST",
uri="/issues/_search",
params=params,
payload=IssueFindParameters(
filter=issue_filter,
query=query,
keys=keys,
queue=queue,
).model_dump(exclude_none=True, by_alias=True),
)
return self._decode(raw_response, Issue, plural=True)

0 comments on commit 5c825a8

Please sign in to comment.