-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPyUp.py
More file actions
373 lines (292 loc) · 14.3 KB
/
Copy pathPyUp.py
File metadata and controls
373 lines (292 loc) · 14.3 KB
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
import urllib
import requests
UP_API_OAUTH_HOST = "https://jawbone.com/auth/oauth2/auth"
UP_API_OAUTH_TOKEN_HOST = 'https://jawbone.com/auth/oauth2/token'
UP_API_HOST = "https://jawbone.com/nudge/api"
def _build_param_dict(items):
"""
Function which builds the dictionary for encoding the url parameters.
:param items: A dictionary contain key,values
:return: A cleaned dictionary used for url encoding parameters
"""
p = {}
for k, v in items.iteritems():
if k is not 'self' and k is not 'access_token':
if v:
p[k] = v
return p
def _url_handler(url, access_token, request_type=None):
"""
Private method used to handle url requests for the api methods
:param url: The url to access
:param access_token: A valid access token
:param request_type: Default is GET, the HTTP request type
:return: The data of the request, or error code
"""
try:
if request_type is 'POST':
res = requests.post(url, headers=dict(Authorization="Bearer " + str(access_token)))
pass
elif request_type is 'DELETE':
res = requests.delete(url, headers=dict(Authorization="Bearer " + str(access_token)))
else:
res = requests.get(url, headers=dict(Authorization="Bearer " + str(access_token)))
if res.status_code == 200:
return res.json()
return dict(status_code=res.status_code)
except requests.ConnectionError, e:
return dict(status_code=e.message)
class UpAPI():
def __init__(self, scopes=None):
self.refresh_token = ''
self.code = ''
self.client_id = ''
self.app_secret = ''
self.redirect_uri = ''
self.scope = scopes or "basic_read extended_read move_read sleep_read"
self.access_token = ''
def get_initial_connect_auth_code_url(self):
"""
Gets the initial url required for the authentication code
:return: The url needed to authenticate
"""
q = dict(response_type='code', client_id=self.client_id, redirect_uri=self.redirect_uri, scope=self.scope)
return UP_API_OAUTH_HOST + "?" + urllib.urlencode(q)
def get_auth_code(self):
"""
Gets the authentication code from Jawbone
:return: The authentication code
"""
if self.code:
return self.code
url = self.get_initial_connect_auth_code_url()
res = requests.get(url)
if res.status_code == 200:
code = res.json()['code']
self.code = code
return self.code
return None
@property
def get_access_token(self):
return self.access_token
def exchange_code_for_token(self, code):
"""
Exchanges the authentication code for an access token
:param code (str): The code we plan on exchanging for an access token
:return : Access Token
"""
u = UP_API_OAUTH_TOKEN_HOST + '?client_id=' + self.client_id
u += '&client_secret=' + self.app_secret
u += '&grant_type=authorization_code'
u += '&code=' + code
res = requests.get(u)
if res.status_code == 200:
self.refresh_token = res.json()['refresh_token']
self.access_token = res.json()['access_token']
return self.access_token
return None
@staticmethod
def get_band_events(access_token, date=None, start_time=None, end_time=None, created_after=None):
"""
Returns the band hardware events generated by the UP24 bluetooth connected band.
:param access_token (str): The valid access token
:param date (str): Date, formatted as YYYYMMDD. If omitted, returns the information for today.
:param start_time (int): To be used along with end_time.
:param end_time (int): To be used with start_time.
:param created_after (int): Epoch timestamp to list events that are created later than the timestamp.
:return: The response or error code of the request
"""
url = UP_API_HOST + '/users/@me/bandevents' + '?' + urllib.urlencode(_build_param_dict(locals()))
return _url_handler(url, access_token)
@staticmethod
def get_user_goals(access_token):
"""
Returns the goals the user has set for UP. Currently takes no parameters and is read only.
:param access_token (str): The valid access token
:return: The response or error code of the request
"""
return _url_handler(UP_API_HOST + '/users/@me/goals', access_token)
@staticmethod
def set_user_goal(access_token, move_steps=None, sleep_total=None, body_weight=None, body_weight_intent=None):
"""
Updates the user goal. Note your app must have the correct scope to update the respective goal.
:param access_token (str): The valid access token
:param move_steps: Move goal per day in number of steps. Need scope move_write.
:param sleep_total: Sleep goal per day in seconds. Need scope sleep_write.
:param body_weight: Body weight goal. MUST be in metric (kg). Need scope body_write.
:param body_weight_intent: User's desired weight management intent. 0=lose, 1=maintain, 2=gain. Need body_write.
:return: The response or error code of the request
"""
url = UP_API_HOST + '/users/@me/goals' + '?' + urllib.urlencode(_build_param_dict(locals()))
return _url_handler(url, access_token, request_type='POST')
@staticmethod
def get_resting_heartrate(access_token, date=None, page_token=None, start_time=None, end_time=None,
updated_after=None,
limit=None):
"""
Returns a single resting heart rate measurement captured at a specific, non-configurable time via an UP3 device.
:param access_token (str): The valid access token
:param date (str): Date, formatted as YYYYMMDD. If omitted, returns the information for today.
:param page_token (int): Timestamp used to paginate the list of events.
:param start_time (int): To be used along with end_time.
:param end_time (int): To be used with start_time.
:param updated_after (int): Epoch timestamp to list events that have been updated later than the timestamp.
:param limit (int): Maximum number of results to return
:return: The response or error code of the request
"""
url = UP_API_HOST + '/users/@me/heartrates' + '?' + urllib.urlencode(_build_param_dict(locals()))
return _url_handler(url, access_token)
@staticmethod
def get_user_details(access_token):
"""
Returns the basic information of the user
:param access_token (str): The access token required
:return: The response or error code of the request
"""
url = UP_API_HOST + '/users/@me'
return _url_handler(url, access_token)
@staticmethod
def get_friends_list(access_token):
"""
Returns the list of unique identifiers (XIDs) of the user's friends.
:param access_token: The access token required
:return: The response or error code of the request
"""
return _url_handler(UP_API_HOST + '/users/@me/friends', access_token)
@staticmethod
def get_workouts_list(access_token, date=None, page_token=None, start_time=None, end_time=None, updated_after=None,
limit=None):
"""
Returns the list of workouts of the current user.
:param access_token (str): The valid access token
:param date (int): Date, formatted as YYYYMMDD. If omitted, returns the information for today.
:param page_token (int): Timestamp used to paginate the list of workouts.
:param start_time (int): To be used along with end_time.
:param end_time (int): To be used with start_time.
:param updated_after (int): Epoch timestamp to list events that are updated later than the timestamp.
:param limit (int): Maximum number of results to return
:return: The response or error code of the request
"""
url = UP_API_HOST + '/users/@me/workouts?' + urllib.urlencode(_build_param_dict(locals()))
return _url_handler(url, access_token)
@staticmethod
def get_workout_info(access_token, xid):
"""
Returns detailed information about the given workout.
:param access_token (str): The valid access token
:param xid (str): The workout xid
:return: The response or error code of the request
"""
return _url_handler(UP_API_HOST + '/users/@me/workouts/' + str(xid), access_token)
@staticmethod
def get_workout_graph(access_token, xid):
"""
Returns the image of the given workout.
:param access_token (str): The valid access token
:param xid (str): The workout xid
:return: The image of the workout or error code of the request
"""
return _url_handler(UP_API_HOST + '/users/@me/workouts/' + str(xid) + '/image', access_token)
@staticmethod
def get_workout_ticks(access_token, xid):
"""
Returns granular details for the specific Workout event.
:param access_token (str): The valid access token
:param xid (str): The workout xid
:return: The response or error code of the request
"""
return _url_handler(UP_API_HOST + '/users/@me/workouts/' + str(xid) + '/ticks', access_token)
@staticmethod
def get_trends(access_token, num_buckets, bucket_size=None, end_date=None):
"""
Returns the user's trends over a period of time (e.g. 5 weeks), using the given granularity (e.g. by day).
:param access_token (str): The valid access token
:param num_buckets (int): Required. The number of buckets to return, starting at the given end_date and going
backwards in time. Maximum is 100.
:param bucket_size (str): Determines the granularity to use when aggregating the values.
Possible values are: d (for days), w (for weeks), m (for months), y (for years). If omitted will default to days
:param end_date (int): Date, formatted as YYYYMMDD. If omitted will default to today.
:return: The response or error code of the request
"""
url = UP_API_HOST + '/users/@me/trends' + '?' + urllib.urlencode(_build_param_dict(locals()))
return _url_handler(url, access_token)
@staticmethod
def get_moves_list(access_token, date=None, start_time=None, end_time=None, updated_after=None,
page_token=None):
"""
Returns the list of moves of the current user.
:param access_token (str):
:param date (int): Date, formatted as YYYYMMDD. If omitted, returns the information for today.
:param start_time (int): To be used along with end_time.
:param end_time (int): To be used with start_time.
:param updated_after (int): Epoch timestamp to list move events that are updated later than the timestamp.
:param page_token (int): Timestamp used to paginate the list of moves.
:return: The response or error code of the request
"""
url = UP_API_HOST + '/users/@me/moves?' + urllib.urlencode(_build_param_dict(locals()))
return _url_handler(url, access_token)
@staticmethod
def get_move_info(access_token, move_xid):
"""
Returns the detailed information of the given move.
:param access_token (str): The valid access token
:param move_xid (str): The xid of the move
:return: The response or error code of the request
"""
url = UP_API_HOST + '/users/@me/moves/' + str(move_xid)
return _url_handler(url, access_token)
@staticmethod
def get_move_graph(access_token, move_xid):
"""
Returns the image of the given move.
:param access_token (str): The valid access token
:param move_xid (str): The xid of the move
:return: The response or error code of the request
"""
url = UP_API_HOST + '/users/@me/moves/' + str(move_xid) + "/image"
return _url_handler(url, access_token)
@staticmethod
def get_move_ticks(access_token, move_xid):
"""
Returns granular details for the specific Move event.
:param access_token (str): The valid access token
:param move_xid (str): The xid of the move
:return: The response or error code of the request
"""
url = UP_API_HOST + '/users/@me/moves/' + move_xid + "/ticks"
return _url_handler(url, access_token)
@staticmethod
def get_sleeps_list(access_token, date=None, start_time=None, end_time=None, updated_after=None,
page_token=None):
"""
Returns the list of sleeps of the current user.
:param access_token (str): The valid access token
:param date (int): Date, formatted as YYYYMMDD. If omitted, returns the information for today.
:param start_time (int): To be used along with end_time.
:param end_time (int): To be used with start_time.
:param updated_after (int): Epoch timestamp to list events that are updated later than the timestamp.
:param page_token (int): Timestamp used to paginate the list of sleeps.
:return:The response or error code of the request
"""
url = UP_API_HOST + '/users/@me/sleeps?' + urllib.urlencode(_build_param_dict(locals()))
return _url_handler(url, access_token)
@staticmethod
def get_generic_api_call(access_token, endpoint='/users/@me', **kwargs):
"""
Generic method for any API get call to Jawbone.
:param access_token (str): The access_token
:param endpoint (str): Endpoint we want to go against eg '/users/@me/'
:param **kwargs: Any additional parameters
:return: The response or error
"""
url = UP_API_HOST + endpoint + '?' + urllib.urlencode(kwargs.items())
return _url_handler(url, access_token)
@staticmethod
def revoke_access_token(access_token):
"""
Disconnects user from application
:param access_token (str): The access token required
:return: The response of the request
"""
return requests.delete(UP_API_HOST + '/users/@me/PartnerAppMembership',
headers=dict(Authorization="Bearer " + access_token))