1+ from __future__ import annotations
2+
13from typing import Any
24
3- from ..models .epics import Epic , PaginatedEpicResponse
5+ from ..models .epics import (
6+ AddEpicWorkItems ,
7+ CreateEpic ,
8+ Epic ,
9+ EpicIssue ,
10+ PaginatedEpicIssueResponse ,
11+ PaginatedEpicResponse ,
12+ UpdateEpic ,
13+ )
414from ..models .query_params import PaginatedQueryParams , RetrieveQueryParams
515from .base_resource import BaseResource
616
@@ -9,6 +19,69 @@ class Epics(BaseResource):
919 def __init__ (self , config : Any ) -> None :
1020 super ().__init__ (config , "/workspaces/" )
1121
22+ def create (self , workspace_slug : str , project_id : str , data : CreateEpic ) -> Epic :
23+ """Create a new epic in a project.
24+
25+ Args:
26+ workspace_slug: The workspace slug identifier
27+ project_id: UUID of the project
28+ data: Epic creation data
29+ """
30+ # enable epics feature flag
31+ response = self ._post (
32+ f"{ workspace_slug } /projects/{ project_id } /epics" ,
33+ data .model_dump (exclude_none = True ),
34+ )
35+ return Epic .model_validate (response )
36+
37+ def retrieve (
38+ self ,
39+ workspace_slug : str ,
40+ project_id : str ,
41+ epic_id : str ,
42+ params : RetrieveQueryParams | None = None ,
43+ ) -> Epic :
44+ """Retrieve an epic by ID.
45+
46+ Args:
47+ workspace_slug: The workspace slug identifier
48+ project_id: UUID of the project
49+ epic_id: UUID of the epic
50+ params: Optional query parameters for expand, fields, etc.
51+ """
52+ query_params = params .model_dump (exclude_none = True ) if params else None
53+ response = self ._get (
54+ f"{ workspace_slug } /projects/{ project_id } /epics/{ epic_id } " , params = query_params
55+ )
56+ return Epic .model_validate (response )
57+
58+ def update (
59+ self , workspace_slug : str , project_id : str , epic_id : str , data : UpdateEpic
60+ ) -> Epic :
61+ """Partially update an existing epic.
62+
63+ Args:
64+ workspace_slug: The workspace slug identifier
65+ project_id: UUID of the project
66+ epic_id: UUID of the epic
67+ data: Epic update data
68+ """
69+ response = self ._patch (
70+ f"{ workspace_slug } /projects/{ project_id } /epics/{ epic_id } " ,
71+ data .model_dump (exclude_none = True ),
72+ )
73+ return Epic .model_validate (response )
74+
75+ def delete (self , workspace_slug : str , project_id : str , epic_id : str ) -> None :
76+ """Delete an epic.
77+
78+ Args:
79+ workspace_slug: The workspace slug identifier
80+ project_id: UUID of the project
81+ epic_id: UUID of the epic
82+ """
83+ self ._delete (f"{ workspace_slug } /projects/{ project_id } /epics/{ epic_id } " )
84+
1285 def list (
1386 self ,
1487 workspace_slug : str ,
@@ -26,23 +99,45 @@ def list(
2699 response = self ._get (f"{ workspace_slug } /projects/{ project_id } /epics" , params = query_params )
27100 return PaginatedEpicResponse .model_validate (response )
28101
29- def retrieve (
102+ def list_issues (
30103 self ,
31104 workspace_slug : str ,
32105 project_id : str ,
33106 epic_id : str ,
34- params : RetrieveQueryParams | None = None ,
35- ) -> Epic :
36- """Retrieve an epic by ID .
107+ params : PaginatedQueryParams | None = None ,
108+ ) -> PaginatedEpicIssueResponse :
109+ """List work items under an epic .
37110
38111 Args:
39112 workspace_slug: The workspace slug identifier
40113 project_id: UUID of the project
41114 epic_id: UUID of the epic
42- params: Optional query parameters for expand, fields, etc.
115+ params: Optional query parameters for pagination
43116 """
44117 query_params = params .model_dump (exclude_none = True ) if params else None
45118 response = self ._get (
46- f"{ workspace_slug } /projects/{ project_id } /epics/{ epic_id } " , params = query_params
119+ f"{ workspace_slug } /projects/{ project_id } /epics/{ epic_id } /issues" ,
120+ params = query_params ,
47121 )
48- return Epic .model_validate (response )
122+ return PaginatedEpicIssueResponse .model_validate (response )
123+
124+ def add_issues (
125+ self ,
126+ workspace_slug : str ,
127+ project_id : str ,
128+ epic_id : str ,
129+ data : AddEpicWorkItems ,
130+ ) -> list [EpicIssue ]:
131+ """Add work items as sub-issues under an epic.
132+
133+ Args:
134+ workspace_slug: The workspace slug identifier
135+ project_id: UUID of the project
136+ epic_id: UUID of the epic
137+ data: Work item IDs to add
138+ """
139+ response = self ._post (
140+ f"{ workspace_slug } /projects/{ project_id } /epics/{ epic_id } /issues" ,
141+ data .model_dump (exclude_none = True ),
142+ )
143+ return [EpicIssue .model_validate (item ) for item in response ]
0 commit comments