Skip to content

Commit 9a3305b

Browse files
committed
Tempo API wrap from API specs #446
1 parent ebffad3 commit 9a3305b

20 files changed

+2547
-0
lines changed

atlassian/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from .portfolio import Portfolio
1717
from .service_desk import ServiceDesk
1818
from .service_desk import ServiceDesk as ServiceManagement
19+
from .tempo import TempoCloud, TempoServer
1920
from .xray import Xray
2021

2122
__all__ = [
@@ -35,4 +36,6 @@
3536
"Insight",
3637
"Assets",
3738
"AssetsCloud",
39+
"TempoCloud",
40+
"TempoServer",
3841
]

atlassian/tempo/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# coding=utf-8
2+
"""
3+
Tempo API client package for Atlassian Python API.
4+
5+
This package provides both Cloud and Server implementations of the Tempo API.
6+
"""
7+
8+
from .cloud import Cloud as TempoCloud
9+
from .server import Server as TempoServer
10+
11+
__all__ = [
12+
"TempoCloud",
13+
"TempoServer",
14+
]

atlassian/tempo/cloud/__init__.py

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# coding=utf-8
2+
3+
from .base import TempoCloudBase
4+
5+
6+
class Cloud(TempoCloudBase):
7+
"""
8+
Tempo Cloud REST API wrapper
9+
"""
10+
11+
def __init__(self, url="https://api.tempo.io/", *args, **kwargs):
12+
# Set default API configuration for Tempo Cloud, but allow overrides
13+
if "cloud" not in kwargs:
14+
kwargs["cloud"] = True
15+
if "api_version" not in kwargs:
16+
kwargs["api_version"] = "1"
17+
if "api_root" not in kwargs:
18+
kwargs["api_root"] = "rest/tempo-timesheets/4"
19+
super(Cloud, self).__init__(url, *args, **kwargs)
20+
21+
# Account Management
22+
def get_accounts(self, **kwargs):
23+
"""Get all accounts."""
24+
return self.get("accounts", **kwargs)
25+
26+
def get_account(self, account_id, **kwargs):
27+
"""Get account by ID."""
28+
return self.get(f"accounts/{account_id}", **kwargs)
29+
30+
def create_account(self, data, **kwargs):
31+
"""Create a new account."""
32+
return self.post("accounts", data=data, **kwargs)
33+
34+
def update_account(self, account_id, data, **kwargs):
35+
"""Update an existing account."""
36+
return self.put(f"accounts/{account_id}", data=data, **kwargs)
37+
38+
def delete_account(self, account_id, **kwargs):
39+
"""Delete an account."""
40+
return self.delete(f"accounts/{account_id}", **kwargs)
41+
42+
# Worklog Management
43+
def get_worklogs(self, **kwargs):
44+
"""Get all worklogs."""
45+
return self.get("worklogs", **kwargs)
46+
47+
def get_worklog(self, worklog_id, **kwargs):
48+
"""Get worklog by ID."""
49+
return self.get(f"worklogs/{worklog_id}", **kwargs)
50+
51+
def create_worklog(self, data, **kwargs):
52+
"""Create a new worklog."""
53+
return self.post("worklogs", data=data, **kwargs)
54+
55+
def update_worklog(self, worklog_id, data, **kwargs):
56+
"""Update an existing worklog."""
57+
return self.put(f"worklogs/{worklog_id}", data=data, **kwargs)
58+
59+
def delete_worklog(self, worklog_id, **kwargs):
60+
"""Delete a worklog."""
61+
return self.delete(f"worklogs/{worklog_id}", **kwargs)
62+
63+
# Schedule Management
64+
def get_schedules(self, **kwargs):
65+
"""Get all schedules."""
66+
return self.get("schedules", **kwargs)
67+
68+
def get_schedule(self, schedule_id, **kwargs):
69+
"""Get schedule by ID."""
70+
return self.get(f"schedules/{schedule_id}", **kwargs)
71+
72+
def create_schedule(self, data, **kwargs):
73+
"""Create a new schedule."""
74+
return self.post("schedules", data=data, **kwargs)
75+
76+
def update_schedule(self, schedule_id, data, **kwargs):
77+
"""Update an existing schedule."""
78+
return self.put(f"schedules/{schedule_id}", data=data, **kwargs)
79+
80+
def delete_schedule(self, schedule_id, **kwargs):
81+
"""Delete a schedule."""
82+
return self.delete(f"schedules/{schedule_id}", **kwargs)
83+
84+
# User Management
85+
def get_users(self, **kwargs):
86+
"""Get all users."""
87+
return self.get("users", **kwargs)
88+
89+
def get_user(self, user_id, **kwargs):
90+
"""Get user by ID."""
91+
return self.get(f"users/{user_id}", **kwargs)
92+
93+
def get_user_schedule(self, user_id, **kwargs):
94+
"""Get user's schedule."""
95+
return self.get(f"users/{user_id}/schedule", **kwargs)
96+
97+
def get_user_worklogs(self, user_id, **kwargs):
98+
"""Get user's worklogs."""
99+
return self.get(f"users/{user_id}/worklogs", **kwargs)
100+
101+
# Team Management
102+
def get_teams(self, **kwargs):
103+
"""Get all teams."""
104+
return self.get("teams", **kwargs)
105+
106+
def get_team(self, team_id, **kwargs):
107+
"""Get team by ID."""
108+
return self.get(f"teams/{team_id}", **kwargs)
109+
110+
def create_team(self, data, **kwargs):
111+
"""Create a new team."""
112+
return self.post("teams", data=data, **kwargs)
113+
114+
def update_team(self, team_id, data, **kwargs):
115+
"""Update an existing team."""
116+
return self.put(f"teams/{team_id}", data=data, **kwargs)
117+
118+
def delete_team(self, team_id, **kwargs):
119+
"""Delete a team."""
120+
return self.delete(f"teams/{team_id}", **kwargs)
121+
122+
def get_team_members(self, team_id, **kwargs):
123+
"""Get team members."""
124+
return self.get(f"teams/{team_id}/members", **kwargs)
125+
126+
def add_team_member(self, team_id, user_id, **kwargs):
127+
"""Add member to team."""
128+
return self.post(f"teams/{team_id}/members", data={"userId": user_id}, **kwargs)
129+
130+
def remove_team_member(self, team_id, user_id, **kwargs):
131+
"""Remove member from team."""
132+
return self.delete(f"teams/{team_id}/members/{user_id}", **kwargs)
133+
134+
# Project Management
135+
def get_projects(self, **kwargs):
136+
"""Get all projects."""
137+
return self.get("projects", **kwargs)
138+
139+
def get_project(self, project_id, **kwargs):
140+
"""Get project by ID."""
141+
return self.get(f"projects/{project_id}", **kwargs)
142+
143+
def get_project_worklogs(self, project_id, **kwargs):
144+
"""Get project worklogs."""
145+
return self.get(f"projects/{project_id}/worklogs", **kwargs)
146+
147+
# Activity Management
148+
def get_activities(self, **kwargs):
149+
"""Get all activities."""
150+
return self.get("activities", **kwargs)
151+
152+
def get_activity(self, activity_id, **kwargs):
153+
"""Get activity by ID."""
154+
return self.get(f"activities/{activity_id}", **kwargs)
155+
156+
def create_activity(self, data, **kwargs):
157+
"""Create a new activity."""
158+
return self.post("activities", data=data, **kwargs)
159+
160+
def update_activity(self, activity_id, data, **kwargs):
161+
"""Update an existing activity."""
162+
return self.put(f"activities/{activity_id}", data=data, **kwargs)
163+
164+
def delete_activity(self, activity_id, **kwargs):
165+
"""Delete an activity."""
166+
return self.delete(f"activities/{activity_id}", **kwargs)
167+
168+
# Customer Management
169+
def get_customers(self, **kwargs):
170+
"""Get all customers."""
171+
return self.get("customers", **kwargs)
172+
173+
def get_customer(self, customer_id, **kwargs):
174+
"""Get customer by ID."""
175+
return self.get(f"customers/{customer_id}", **kwargs)
176+
177+
def create_customer(self, data, **kwargs):
178+
"""Create a new customer."""
179+
return self.post("customers", data=data, **kwargs)
180+
181+
def update_customer(self, customer_id, data, **kwargs):
182+
"""Update an existing customer."""
183+
return self.put(f"customers/{customer_id}", data=data, **kwargs)
184+
185+
def delete_customer(self, customer_id, **kwargs):
186+
"""Delete a customer."""
187+
return self.delete(f"customers/{customer_id}", **kwargs)
188+
189+
# Holiday Management
190+
def get_holidays(self, **kwargs):
191+
"""Get all holidays."""
192+
return self.get("holidays", **kwargs)
193+
194+
def get_holiday(self, holiday_id, **kwargs):
195+
"""Get holiday by ID."""
196+
return self.get(f"holidays/{holiday_id}", **kwargs)
197+
198+
def create_holiday(self, data, **kwargs):
199+
"""Create a new holiday."""
200+
return self.post("holidays", data=data, **kwargs)
201+
202+
def update_holiday(self, holiday_id, data, **kwargs):
203+
"""Update an existing holiday."""
204+
return self.put(f"holidays/{holiday_id}", data=data, **kwargs)
205+
206+
def delete_holiday(self, holiday_id, **kwargs):
207+
"""Delete a holiday."""
208+
return self.delete(f"holidays/{holiday_id}", **kwargs)
209+
210+
# Report Generation
211+
def generate_report(self, report_type, params=None, **kwargs):
212+
"""Generate a report."""
213+
if params is None:
214+
params = {}
215+
return self.post(f"reports/{report_type}", data=params, **kwargs)
216+
217+
def get_report_status(self, report_id, **kwargs):
218+
"""Get report generation status."""
219+
return self.get(f"reports/{report_id}/status", **kwargs)
220+
221+
def download_report(self, report_id, **kwargs):
222+
"""Download a generated report."""
223+
return self.get(f"reports/{report_id}/download", **kwargs)
224+
225+
# Utility Methods
226+
def get_metadata(self, **kwargs):
227+
"""Get API metadata."""
228+
return self.get("metadata", **kwargs)
229+
230+
def get_health(self, **kwargs):
231+
"""Get API health status."""
232+
return self.get("health", **kwargs)

atlassian/tempo/cloud/base.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# coding=utf-8
2+
"""
3+
Tempo Cloud API base class.
4+
"""
5+
6+
from ...rest_client import AtlassianRestAPI
7+
8+
9+
class TempoCloudBase(AtlassianRestAPI):
10+
"""
11+
Base class for Tempo Cloud API operations.
12+
"""
13+
14+
def __init__(self, url, *args, **kwargs):
15+
super(TempoCloudBase, self).__init__(url, *args, **kwargs)
16+
17+
def _sub_url(self, url):
18+
"""
19+
Get the full url from a relative one.
20+
21+
:param url: string: The sub url
22+
:return: The absolute url
23+
"""
24+
return self.url_joiner(self.url, url)
25+
26+
@property
27+
def _new_session_args(self):
28+
"""
29+
Get the kwargs for new objects (session, root, version,...).
30+
31+
:return: A dict with the kwargs for new objects
32+
"""
33+
return {
34+
"session": self._session,
35+
"cloud": self.cloud,
36+
"api_root": self.api_root,
37+
"api_version": self.api_version,
38+
}

atlassian/tempo/server/__init__.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# coding=utf-8
2+
3+
from .base import TempoServerBase
4+
from .accounts import Accounts
5+
from .teams import Teams
6+
from .planner import Planner
7+
from .budgets import Budgets
8+
from .timesheets import Timesheets
9+
from .servlet import Servlet
10+
from .events import Events
11+
12+
13+
class Server(TempoServerBase):
14+
"""
15+
Tempo Server REST API wrapper
16+
"""
17+
18+
def __init__(self, url, *args, **kwargs):
19+
# Set default API configuration for Tempo Server, but allow overrides
20+
if "cloud" not in kwargs:
21+
kwargs["cloud"] = False
22+
if "api_version" not in kwargs:
23+
kwargs["api_version"] = "1"
24+
if "api_root" not in kwargs:
25+
kwargs["api_root"] = "rest/tempo-core/1"
26+
super(Server, self).__init__(url, *args, **kwargs)
27+
28+
# Initialize specialized modules with reference to this instance
29+
self.__accounts = Accounts(self._sub_url("accounts"), parent=self, **self._new_session_args)
30+
self.__teams = Teams(self._sub_url("teams"), parent=self, **self._new_session_args)
31+
self.__planner = Planner(self._sub_url("plans"), parent=self, **self._new_session_args)
32+
self.__budgets = Budgets(self._sub_url("budgets"), parent=self, **self._new_session_args)
33+
self.__timesheets = Timesheets(self._sub_url("timesheets"), parent=self, **self._new_session_args)
34+
self.__servlet = Servlet(self._sub_url("worklogs"), parent=self, **self._new_session_args)
35+
self.__events = Events(self._sub_url("events"), parent=self, **self._new_session_args)
36+
37+
@property
38+
def accounts(self):
39+
"""Property to access the accounts module."""
40+
return self.__accounts
41+
42+
@property
43+
def teams(self):
44+
"""Property to access the teams module."""
45+
return self.__teams
46+
47+
@property
48+
def planner(self):
49+
"""Property to access the planner module."""
50+
return self.__planner
51+
52+
@property
53+
def budgets(self):
54+
"""Property to access the budgets module."""
55+
return self.__budgets
56+
57+
@property
58+
def timesheets(self):
59+
"""Property to access the timesheets module."""
60+
return self.__timesheets
61+
62+
@property
63+
def servlet(self):
64+
"""Property to access the servlet module."""
65+
return self.__servlet
66+
67+
@property
68+
def events(self):
69+
"""Property to access the events module."""
70+
return self.__events
71+
72+
def get_health(self, **kwargs):
73+
"""Get API health status."""
74+
return self.get("health", **kwargs)
75+
76+
def get_metadata(self, **kwargs):
77+
"""Get API metadata."""
78+
return self.get("metadata", **kwargs)

0 commit comments

Comments
 (0)