-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjama_api_helper.py
125 lines (96 loc) · 3.62 KB
/
jama_api_helper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import requests
from typing import Callable
from pprint import pprint
def log(msg: str):
print(msg)
def exception_handler(func: Callable) -> Callable:
"""Exception handler decorator function."""
def inner(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
error_msg = f'Error calling function: {func.__name__}'
error_msg += '\n' + str(e)
log(error_msg)
return inner
class JamaInterface:
"""A helper class for interacting with the Jama REST API."""
def __init__(self, endpoint_url: str) -> object:
self.endpoint_url = endpoint_url
self.access_token = None
@exception_handler
def authenticate(
self,
client_id: str,
client_secret: str
) -> None:
"""Authenticate an HTTP session using the API client ID and client
secret generated in the Jama web interface. Saves the access token
provided by Jama in exchange for the client API credentials. By
default, the access token is valid for one hour."""
req = requests.post(
url='https://clarios.jamacloud.com/rest/oauth/token',
params={'grant_type': 'client_credentials'},
auth=(client_id, client_secret)
)
if req.ok is not True:
raise RuntimeError('Failed to authenticate.')
req_json = req.json()
self.access_token = req_json['access_token']
@exception_handler
def get_item(
self,
project_id: int = None,
item_project_id: str = None,
item_global_id: str = None
) -> object:
"""Get an item specified either by the item global ID or the project
ID and the item project ID."""
if self.access_token is None:
raise RuntimeError(
'Tried to access Jama items without first authenticating.')
if item_global_id is not None:
response = requests.get(
url=self.endpoint_url + '/abstractitems',
params={
'documentKey': item_global_id
}
)
elif project_id is not None and item_project_id is not None:
response = requests.get(
url=self.endpoint_url + '/abstractitems',
params={
'documentKey': item_project_id,
'project': project_id
},
headers={
'Authorization': f'Bearer {self.access_token}'
}
)
else:
raise RuntimeError('Error: Item insufficiently defined.')
return JamaItem(response)
class JamaItem:
"""Represents an item in Jama."""
def __init__(self, response: object = None) -> object:
response_json = response.json()
data = response_json['data'][0]
self.id = data['id']
self.item_project_id = data['documentKey']
self.global_id = data['globalId']
self.project_id = data['project']
self.fields: dict = data['fields']
def __str__(self) -> str:
"""String representation of the JamaItem."""
items = [
f'Item Project ID: {self.item_project_id}',
f'Item Global ID: {self.global_id}',
]
if 'name' in self.fields.keys():
items.append(f'Name: {self.fields["name"]}')
if 'description' in self.fields.keys():
items.append(f'Description: {self.fields["description"]}')
return '\n'.join(items)
def print_fields(self) -> None:
"""Pretty prints the self.fields dictionary."""
pprint(self.fields)