-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreportdemo.py
176 lines (144 loc) · 6.3 KB
/
reportdemo.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
'''
Simple demonstration of the use of the InContact Reporting API
@author: Joey Whelan <[email protected]>
'''
import requests
import base64
import time
app = 'yourApp'
vendor = 'yourVendor'
reportId = 'yourId'
bu = 'yourBu'
username = 'yourName'
password = 'yourPwd'
outfile = 'report.csv'
class CustomReport(object):
"""Class providing an object wrapper for REST calls to the InContact Reporting API.
"""
def __init__(self, app, vendor, bu, username, password):
"""Initializes state variables for class.
Args:
self: Instance reference
app: InContact app name for API access
vendor: InContact vendor name for API access
bu: InContact business unit
username: InContact username
password: InContact password
Returns:
None
Raises:
None
"""
auth = app + '@' + vendor + ':' + bu
self.authCode = base64.b64encode(auth.encode());
self.username = username;
self.password = password;
def getToken(self):
"""Uses a base64-encoded key to make an request for a password-grant API token. Will propagate exceptions.
Args:
self: Instance reference
Returns:
JSON object containing the API token and base URL
Raises:
HTTPError: Any sort of HTTP 400/500 response returned from InContact.
"""
print('getToken()')
url = 'https://api.incontact.com/InContactAuthorizationServer/Token'
header = {'Authorization' : b'basic ' + self.authCode, 'Content-Type': 'application/json'}
body = {'grant_type' : 'password', 'username' : self.username, 'password' : self.password}
resp = requests.post(url, headers=header, json=body)
resp.raise_for_status()
return resp.json()
def startReportJob(self, reportId, reportURL, token):
"""Kicks off custom reporting job. Will propagate exceptions.
Args:
self: Instance reference
reportId: String. reportID custom report ID
reportURL: String. base URL for the reporting API
token: String. InContact API token
Returns:
String. jobId of the reporting job
Raises:
HTTPError: Any sort of HTTP 400/500 response returned from InContact.
"""
url = reportURL + reportId
print('startReportJob() - url: ' + url);
body = {
'fileType': 'CSV',
'includeHeaders': 'true',
'appendDate': 'true',
'deleteAfter': '7',
'overwrite': 'true'
}
header = { 'Content-Type' : 'application/json', 'Authorization' : 'bearer ' + token}
resp = requests.post(url, headers=header, json=body)
resp.raise_for_status()
return resp.json()['jobId']
def getFileURL(self, jobId, reportURL, token):
"""Checks on the status of a reporting job. Loops for up to 10 retries waiting for the job to complete.
By default, waits up to 10 minutes for a job to complete.
Args:
self: Instance reference
jobId: String. id of the reporting job
reportURL: String. base URL for the reporting API
token: String. InContact API token
Returns:
String. URL of the report file location
Raises:
HTTPError: Any sort of HTTP 400/500 response returned from InContact.
"""
url = reportURL + jobId
header = { 'Content-Type' : 'application/x-www-form-urlencoded', 'Authorization' : 'bearer ' + token }
resp = requests.get(url, headers=header)
fileURL = resp.json()['jobResult']['resultFileURL']
numTries = 10
while (not fileURL and numTries > 0):
print('getFileURL() - jobId: ' + jobId + ' numTries: ' + str(numTries))
time.sleep(60)
resp = requests.get(url, headers=header)
fileURL = resp.json()['jobResult']['resultFileURL']
numTries -= 1
return fileURL
def downloadReport(self, url, token):
"""Pulls down the report data. Fetchs the base64-encoded data of the report.
Args:
self: Instance reference
url: String. InContact API file fetch url
token: String. InContact API token
Returns:
String. base64 data
Raises:
HTTPError: Any sort of HTTP 400/500 response returned from InContact.
"""
print('downLoadReport() - url: ' + url)
header = { 'Content-Type' : 'application/x-www-form-urlencoded', 'Authorization' : 'bearer ' + token }
resp = requests.get(url, headers=header)
return resp.json()['files']['file']
def getReport(self, reportId, target):
"""Main procedure. Performs a series of InContact API calls to get an API token, start a reporting job,
check status/get file URL of the resulting job, download the base64-encoded string of the job,
and convert that string to binary and write it to a local file.
Args:
self: Instance reference
reportId: String. ID of the custom report template to be executed
target: String. name of filename where report data is to be written
Returns:
none
Raises:
HTTPError: Any sort of HTTP 400/500 response returned from InContact.
"""
print('getReport() - reportId: ' + reportId)
version = 'v13.0'
json = self.getToken()
reportURL = json['resource_server_base_uri'] + 'services/' + version + '/report-jobs/'
token = json['access_token']
jobId = self.startReportJob(reportId, reportURL, token)
url = self.getFileURL(jobId, reportURL, token)
b64bytes = self.downloadReport(url, token)
file = open(target, 'w')
file.write(base64.b64decode(b64bytes).decode('utf-8'))
file.close()
print('Job Complete')
if __name__ == '__main__':
report = CustomReport(app, vendor, bu, username, password)
report.getReport(reportId, outfile)