-
Notifications
You must be signed in to change notification settings - Fork 0
/
retrieve.py
121 lines (92 loc) · 3.57 KB
/
retrieve.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
# Fitbit API docs: https://dev.fitbit.com/docs/
# fitbit-python docs: http://python-fitbit.readthedocs.io/en/latest/
from datetime import date, timedelta
from dateutil.parser import parse
from ratelimit import rate_limited
import fire
import fitbit
import json
import os
DATA_DIR = "intraday_data"
HOURLY_API_LIMIT = 150
def refresh_tokens(dict):
with open('tokens.json') as token_file:
tokens = json.load(token_file)
print("Refreshing tokens!")
tokens["ACCESS"] = dict["access_token"]
tokens["REFRESH"] = dict["refresh_token"]
with open('tokens.json', 'w') as token_file:
json.dump(tokens, token_file)
def get_client():
with open('tokens.json') as token_file:
tokens = json.load(token_file)
return fitbit.Fitbit(tokens["KEY"], tokens["SECRET"],
access_token = tokens["ACCESS"],
refresh_token = tokens["REFRESH"],
refresh_cb = refresh_tokens)
def write_data(data, path):
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, 'w') as f:
json.dump(data, f)
def get_intraday(client, resource = 'activities/steps', date = date.today()):
path = os.path.join(DATA_DIR, resource, str(date) + '.json')
if os.path.exists(path):
with open(path, 'r') as f:
data = json.load(f)
else:
data = fetch_intraday(client, resource, date)
write_data(data, path)
return data
def fetch_intraday(client, resource = 'activities/steps', date = date.today()):
print("Retrieving {} intraday for {}".format(resource, date))
return client.intraday_time_series(resource, base_date = date)
def get_sleep(client, date):
path = os.path.join(DATA_DIR, 'sleep', str(date) + '.json')
if os.path.exists(path):
with open(path, 'r') as f:
data = json.load(f)
else:
data = fetch_sleep(client, date)
write_data(data, path)
return data
def fetch_sleep(client, date):
print("Retrieving sleep data for {}".format(date))
return client.get_sleep(date)
def get_heart(client, date):
path = os.path.join(DATA_DIR, 'heart', str(date) + '.json')
if os.path.exists(path):
with open(path, 'r') as f:
data = json.load(f)
else:
data = fetch_heart(client, date)
write_data(data, path)
return data
def fetch_heart(client, date):
print("Retrieving heart rate data for {}".format(date))
return client.time_series('activities/heart', base_date = date,
period = '1d')
def retrieve(start_date):
client = get_client()
if type(start_date) == str:
start_date = parse(start_date).date()
yesterday = date.today() - timedelta(1)
delta = date.today() - start_date
activities = ('steps','floors','elevation','distance','calories')
if len(activities)*delta.days > HOURLY_API_LIMIT:
global fetch_intraday
global fetch_sleep
global fetch_heart
fetch_intraday = rate_limited(3*HOURLY_API_LIMIT - 1, 7200)(fetch_intraday)
fetch_sleep = rate_limited(3*HOURLY_API_LIMIT - 1, 7200)(fetch_sleep)
fetch_heart = rate_limited(3*HOURLY_API_LIMIT - 1, 7200)(fetch_heart)
for day in (yesterday - timedelta(n) for n in range(delta.days)):
get_sleep(client, day)
get_heart(client, day)
for resource in activities:
get_intraday(client,
resource = "activities/{}".format(resource),
date = day)
if __name__ == '__main__':
fire.Fire({
'retrieve': retrieve
})