From 3a3d496361316d6e30ed23723a80bba192a80125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=90=D0=BD?= =?UTF-8?q?=D1=84=D0=B8=D0=BC=D0=BE=D0=B2?= Date: Sat, 30 Sep 2023 21:55:43 +0300 Subject: [PATCH 1/2] fix: typo in installation guide --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ee0846c..528059c 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,16 @@ API docs: https://cloud.yandex.com/en/docs/tracker/about-api ## Installation ```shell -pip install ya_tracker_clint +pip install ya_tracker_client ``` +or + +```shell +poetry add ya_tracker_client +``` + + ## Usage ```python From 1401a1b18806d9e9f86425e9147ed1798f43496c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=90=D0=BD?= =?UTF-8?q?=D1=84=D0=B8=D0=BC=D0=BE=D0=B2?= Date: Sat, 30 Sep 2023 22:55:32 +0300 Subject: [PATCH 2/2] feat: add projects support --- examples/get_test_entities.py | 1 + ya_tracker_client/domain/entities/project.py | 44 +++++++ .../domain/repositories/__init__.py | 2 + .../domain/repositories/project.py | 111 ++++++++++++++++++ ya_tracker_client/service/api.py | 2 + 5 files changed, 160 insertions(+) create mode 100644 ya_tracker_client/domain/entities/project.py create mode 100644 ya_tracker_client/domain/repositories/project.py diff --git a/examples/get_test_entities.py b/examples/get_test_entities.py index 72f34f1..96f206f 100644 --- a/examples/get_test_entities.py +++ b/examples/get_test_entities.py @@ -32,6 +32,7 @@ async def main() -> None: 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.get_projects_list(expand='queues') await client.stop() diff --git a/ya_tracker_client/domain/entities/project.py b/ya_tracker_client/domain/entities/project.py new file mode 100644 index 0000000..2bf9ec3 --- /dev/null +++ b/ya_tracker_client/domain/entities/project.py @@ -0,0 +1,44 @@ +from datetime import date + +from pydantic import Field + +from ya_tracker_client.domain.entities.base import AbstractEntity +from ya_tracker_client.domain.entities.queue import QueueShort +from ya_tracker_client.domain.entities.user import UserShort + + +class ProjectCreate(AbstractEntity): + name: str + queues: str + description: str | None = None + lead: str | int | None = None + status: str | None = Field(default=None, examples=["DRAFT", "IN_PROGRESS", "LAUNCHED", "POSTPONED"]) + start_date: date | None = None + end_date: date | None = None + + +class Project(AbstractEntity): + url: str + id: int + version: int + key: str + name: str + description: str | None = None + lead: UserShort + status: str = Field(default=None, examples=["DRAFT", "IN_PROGRESS", "LAUNCHED", "POSTPONED"]) + start_date: date | None = None + end_date: date | None = None + + +class ProjectWithQueues(Project): + queues: list[QueueShort] + + +class ProjectEdit(AbstractEntity): + name: str | None + queues: str + description: str | None = None + lead: str | int | None = None + status: str | None = Field(default=None, examples=["DRAFT", "IN_PROGRESS", "LAUNCHED", "POSTPONED"]) + start_date: date | None = None + end_date: date | None = None diff --git a/ya_tracker_client/domain/repositories/__init__.py b/ya_tracker_client/domain/repositories/__init__.py index 163b661..ea5e164 100644 --- a/ya_tracker_client/domain/repositories/__init__.py +++ b/ya_tracker_client/domain/repositories/__init__.py @@ -4,6 +4,7 @@ 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 +from ya_tracker_client.domain.repositories.project import ProjectRepository from ya_tracker_client.domain.repositories.queue import QueueRepository from ya_tracker_client.domain.repositories.user import UserRepository from ya_tracker_client.domain.repositories.worklog import WorklogRepository @@ -16,6 +17,7 @@ "ComponentRepository", "IssueRelationshipRepository", "IssueRepository", + "ProjectRepository", "QueueRepository", "UserRepository", "WorklogRepository", diff --git a/ya_tracker_client/domain/repositories/project.py b/ya_tracker_client/domain/repositories/project.py new file mode 100644 index 0000000..1e4b1f6 --- /dev/null +++ b/ya_tracker_client/domain/repositories/project.py @@ -0,0 +1,111 @@ +from datetime import date + +from ya_tracker_client.domain.entities.project import Project, ProjectCreate, ProjectEdit, ProjectWithQueues +from ya_tracker_client.domain.entities.queue import Queue +from ya_tracker_client.domain.repositories.base import EntityRepository + + +class ProjectRepository(EntityRepository): + async def create_project( + self, + name: str, + queues: str, + description: str | None = None, + lead: str | int | None = None, + status: str | None = None, + start_date: date | None = None, + end_date: date | None = None, + ) -> Project: + """ + YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/projects/create-project + """ + raw_response = await self._client.request( + method="POST", + uri="/projects", + payload=ProjectCreate( + name=name, + queues=queues, + description=description, + lead=lead, + status=status, + start_date=start_date, + end_date=end_date, + ).model_dump(exclude_none=True, by_alias=True), + ) + return self._decode(raw_response, Project) + + async def get_project(self, project_id: str | int) -> Project: + """ + YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/projects/get-project + """ + raw_response = await self._client.request( + method="GET", + uri=f"/projects/{project_id}", + ) + return self._decode(raw_response, Project) + + async def get_projects_list(self, expand: str | None = None) -> list[Project | ProjectWithQueues]: + """ + YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/projects/get-projects + """ + raw_response = await self._client.request( + method="GET", + uri="/projects", + params={"expand": expand} if expand is not None else None, + ) + return self._decode(raw_response, ProjectWithQueues if expand == "queues" else Project, plural=True) + + async def get_project_queues(self, project_id: str | int) -> list[Queue]: + """ + YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/projects/get-project-queues + """ + raw_response = await self._client.request( + method="GET", + uri=f"/projects/{project_id}/queues", + ) + return self._decode(raw_response, Queue, plural=True) + + async def edit_project( + self, + project_id: str | int, + version: int, + queues: str, + name: str | None = None, + description: str | None = None, + lead: str | int | None = None, + status: str | None = None, + start_date: date | None = None, + end_date: date | None = None, + expand: str | None = None, + ) -> Project | ProjectWithQueues: + """ + YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/projects/update-project + """ + params = {"version": version} + if expand: + params["expand"] = expand + + raw_response = await self._client.request( + method="PATCH", + uri=f"/projects/{project_id}", + payload=ProjectEdit( + name=name, + queues=queues, + description=description, + lead=lead, + status=status, + start_date=start_date, + end_date=end_date, + ).model_dump(exclude_none=True, by_alias=True), + params=params, + ) + return self._decode(raw_response, ProjectWithQueues if expand == "queues" else Project) + + async def delete_project(self, project_id: str | int) -> None: + """ + YC docs: https://cloud.yandex.com/en/docs/tracker/concepts/projects/delete-project + """ + await self._client.request( + method="DELETE", + uri=f"/projects/{project_id}", + ) diff --git a/ya_tracker_client/service/api.py b/ya_tracker_client/service/api.py index e8cb6ba..caf6b2f 100644 --- a/ya_tracker_client/service/api.py +++ b/ya_tracker_client/service/api.py @@ -5,6 +5,7 @@ ComponentRepository, IssueRelationshipRepository, IssueRepository, + ProjectRepository, QueueRepository, UserRepository, WorklogRepository, @@ -22,6 +23,7 @@ class YaTrackerClient( QueueRepository, UserRepository, WorklogRepository, + ProjectRepository, ): def __init__( self,