Skip to content

Commit

Permalink
feat: add comments support (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
danfimov committed Sep 30, 2023
2 parents 6fb7a61 + e82fddb commit b043869
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/code-check.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Checks
name: Linters and tests
on: [pull_request]

jobs:
Expand Down
66 changes: 65 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,71 @@

Async Yandex Tracker Client based on aiohttp and pydantic (v2)

# Current library capabilities
[![Python](https://img.shields.io/badge/python-^3.11-blue)](https://www.python.org/)
[![Code linter: ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v1.json)](https://github.com/charliermarsh/ruff)
[![Linters](https://github.com/danfimov/ya_tracker_client/actions/workflows/code-check.yml/badge.svg)](https://github.com/danfimov/ya_tracker_client/actions/workflows/code-check.yml)

---

API docs: https://cloud.yandex.com/en/docs/tracker/about-api

## Installation

```shell
pip install ya_tracker_clint
```

## Usage

```python
import os
from asyncio import run

from dotenv import load_dotenv

from ya_tracker_client import YaTrackerClient


load_dotenv()
# from registered application at Yandex OAuth - https://oauth.yandex.ru/
API_TOKEN = os.getenv("API_TOKEN")
# from admin panel at Yandex Tracker - https://tracker.yandex.ru/admin/orgs
API_ORGANISATION_ID = os.getenv("API_ORGANISATION_ID")


async def main() -> None:
# init client
client = YaTrackerClient(
organisation_id=API_ORGANISATION_ID,
oauth_token=API_TOKEN,
)

# create issue
new_issue = await client.create_issue('New issue', 'TRACKER-QUEUE')

# get issue
issue = await client.get_issue('KEY-1')

# update issue (just pass kwargs)
issue = await client.edit_issue('KEY-1', description='Hello World')

# don't forget to close tracker on app shutdown
await client.stop()


if __name__ == "__main__":
run(main())
```


## Explanations about naming

- All `self` properties renamed to `url` cause it's incompatible with Python;
- All `camelCase` properties renamed to `pythonic_case`;
- All datetime values converted to python's `datetime.datetime` objects;
- Methods named by author, cause Yandex API has no clear method names.

## Current library capabilities

- Working with queues
- Getting information about issues, priorities and transitions
Expand Down
1 change: 1 addition & 0 deletions examples/get_test_entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ async def main() -> None:
await client.get_worklog("TRACKER-1")
await client.get_worklog_records_by_parameters(me.login)
await client.get_attachments_list('TRACKER-1')
await client.get_issue_comments('TRACKER-1')

await client.stop()

Expand Down
35 changes: 35 additions & 0 deletions ya_tracker_client/domain/entities/comment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from datetime import datetime

from pydantic import Field

from ya_tracker_client.domain.entities.base import AbstractEntity
from ya_tracker_client.domain.entities.mailing_list import MailingList
from ya_tracker_client.domain.entities.user import UserShort


class Comment(AbstractEntity):
url: str
id: int
long_id: str
text: str
created_by: UserShort
created_at: datetime
updated_by: UserShort
updated_at: datetime
summonees: list[UserShort] = Field(default_factory=list)
maillistsummonees: list[MailingList] = Field(default_factory=list)
version: int
type: str = Field(examples=["standard", "incoming", "outcoming"])
transport: str = Field(examples=["internal", "email"])


class CommentCreate(AbstractEntity):
text: str
attachment_ids: list[str] | None = None
summonees: list[UserShort | str] | None = None
maillistsummonees: list[str] | None = None


class CommentEdit(AbstractEntity):
text: str
attachment_ids: list[str] | None = None
7 changes: 7 additions & 0 deletions ya_tracker_client/domain/entities/mailing_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from ya_tracker_client.domain.entities.base import AbstractEntity


class MailingList(AbstractEntity):
url: str
id: str
display: str
4 changes: 3 additions & 1 deletion ya_tracker_client/domain/repositories/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from ya_tracker_client.domain.repositories.attachment import AttachmentRepository
from ya_tracker_client.domain.repositories.checklist import ChecklistRepository
from ya_tracker_client.domain.repositories.comment import CommentRepository
from ya_tracker_client.domain.repositories.component import ComponentRepository
from ya_tracker_client.domain.repositories.issue import IssueRepository
from ya_tracker_client.domain.repositories.issue_relationship import IssueRelationshipRepository
Expand All @@ -11,10 +12,11 @@
__all__ = [
"AttachmentRepository",
"ChecklistRepository",
"CommentRepository",
"ComponentRepository",
"IssueRelationshipRepository",
"IssueRepository",
"QueueRepository",
"WorklogRepository",
"UserRepository",
"WorklogRepository",
]
6 changes: 3 additions & 3 deletions ya_tracker_client/domain/repositories/attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class AttachmentRepository(EntityRepository):
async def get_attachments_list(self, issue_id: str) -> list[Attachment]:
"""
Use this request to get a list of files attached to an issue and to comments below it.
Use this method to get a list of files attached to an issue and to comments below it.
YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/get-attachments-list
"""
Expand All @@ -26,7 +26,7 @@ async def download_attachment(
filename: str,
) -> bytes:
"""
Use this request to download files attached to issues.
Use this method to download files attached to issues.
YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/get-attachment
"""
Expand Down Expand Up @@ -78,7 +78,7 @@ async def upload_temp_file(
"""
Upload temporary file.
Use this request to upload a file to Tracker first, and then
Use this method to upload a file to Tracker first, and then
attach it when creating an issue or adding a comment.
YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/temp-attachment
Expand Down
81 changes: 81 additions & 0 deletions ya_tracker_client/domain/repositories/comment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from ya_tracker_client.domain.entities.comment import Comment, CommentCreate, CommentEdit
from ya_tracker_client.domain.entities.user import UserShort
from ya_tracker_client.domain.repositories.base import EntityRepository


class CommentRepository(EntityRepository):
async def add_comment(
self,
issue_id: str,
text: str,
attachment_ids: list[str] | None = None,
summonees: list[str | UserShort] | None = None,
maillist_summonees: list[str] | None = None,
is_add_to_followers: bool | None = None,
) -> Comment:
"""
Use this method to add a comment to an issue.
YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/add-comment
"""
raw_response = await self._client.request(
method="POST",
uri=f"/issues/{issue_id}/comments",
payload=CommentCreate(
text=text,
attachment_ids=attachment_ids,
summonees=summonees,
maillist_summonees=maillist_summonees,
).model_dump(exclude_none=True, by_alias=True),
params={"is_add_to_followers": is_add_to_followers} if is_add_to_followers is not None else None,
)
return self._decode(raw_response, Comment)

async def get_issue_comments(self, issue_id: str) -> list[Comment]:
"""
Use this method to get a list of comments on an issue.
YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/get-comments
"""
raw_response = await self._client.request(
method="GET",
uri=f"/issues/{issue_id}/comments",
)
return self._decode(raw_response, Comment, plural=True)

async def edit_comment(
self,
issue_id: str,
comment_id: str | int,
text: str,
attachment_ids: list[str] | None = None,
) -> Comment:
"""
Use this method to edit comments.
YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/edit-comment
"""
raw_response = await self._client.request(
method="PATCH",
uri=f"/issues/{issue_id}/comments/{comment_id}",
payload=CommentEdit(
text=text,
attachment_ids=attachment_ids,
).model_dump(exclude_none=True, by_alias=True),
)
return self._decode(raw_response, Comment)

async def delete_comment(
self,
issue_id: str,
comment_id: str | int,
) -> None:
"""
Use this method to delete issue comments.
YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/issues/delete-comment
"""
await self._client.request(
method="DELETE",
uri=f"/issues/{issue_id}/comments/{comment_id}",
)
2 changes: 2 additions & 0 deletions ya_tracker_client/service/api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from ya_tracker_client.domain.repositories import (
AttachmentRepository,
ChecklistRepository,
CommentRepository,
ComponentRepository,
IssueRelationshipRepository,
IssueRepository,
Expand All @@ -13,6 +14,7 @@

class YaTrackerClient(
AttachmentRepository,
CommentRepository,
ChecklistRepository,
ComponentRepository,
IssueRelationshipRepository,
Expand Down

0 comments on commit b043869

Please sign in to comment.