Files
containers/fitbit-collect/run_collect.py
2023-11-28 20:10:38 +00:00

226 lines
7.5 KiB
Python
Executable File

#! /usr/bin/env nix-shell
#! nix-shell -i python3 -p python310Packages.google-api-python-client -p python310Packages.fitbit -p python310Packages.consul -p python310Packages.google-auth-oauthlib
"""
Script to retrieve Fitbit data for the given user
"""
from __future__ import print_function
import json
from pprint import pprint
from fitbit import Fitbit
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from datetime import date, timedelta
import time
import consul
dt = date.today() - timedelta(7)
c = consul.Consul(host='consul.service.dc1.consul')
# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
# The ID and range of a sample spreadsheet.
SAMPLE_SPREADSHEET_ID = '1YkMf_3m2YroHhtyS2FrdLzm3HnJDk4-q8r4cSagYrrg'
SAMPLE_RANGE_NAME = 'fitbit_export!A2:E'
FITBIT_API = 'https://api.fitbit.com'
CLIENT_DETAILS_FILE = 'client_details.json' # configuration for for the client
#USER_DETAILS_FILE = 'user_details.json' # user details file
RESULT_FILE = 'fitbit_data.json' # The place where we will place the results
def refresh_callback(token):
c.kv.put('access_token', token["access_token"])
c.kv.put('refresh_token', token["refresh_token"])
c.kv.put('expires_at', str(token["expires_at"]))
def _get_user_details():
access_token = c.kv.get('access_token')[1]["Value"].decode("utf-8")
refresh_token = c.kv.get('refresh_token')[1]["Value"].decode("utf-8")
expires_at = float(c.kv.get('expires_at')[1]["Value"].decode("utf-8"))
return access_token, refresh_token, expires_at
def _get_client_details():
"""The client is the application which requires access"""
with open(CLIENT_DETAILS_FILE) as f:
client_details = json.load(f)
client_id = client_details['client_id']
client_secret = client_details['client_secret']
return client_id, client_secret
def _write_results(json_response):
with open(RESULT_FILE, 'w') as f:
json.dump(json_response, f)
print(f'Successfully written result data to file {RESULT_FILE}')
def _get_api_call():
"""
Date Api in this format:
GET /<api-version>/user/<user-id>/<resource-path>/date/<base-date>/<end-date>.<response-format>
<user-id> can be left as - to get the current user
date format is '%Y-%m-%d' for example 2020-04-01
Some examples below
"""
# # Steps in the last 7 days
# steps_last_seven_days = '/1/user/-/activities/log/steps/date/today/7d.json'
# # Steps between two dates
# steps_dates = '/1/user/-/activities/log/steps/date/2020-04-12/2020-04-18.json'
# # calories last 7 days
# calories_last_seven_days = '/1/user/-/activities/log/calories/date/today/7d.json'
# # profile info
# profile_info = '/1/user/-/profile.json'
# # Sleep between two dates
# sleep_dates = '/1.2/user/-/sleep/date/2020-04-13/2020-04-17.json'
weight = '/1/user/-/body/log/weight/date/' + str(date_start) + '/' + str(date_end) + '.json'
print("API:", weight)
return weight
def ReadSheet():
"""Shows basic usage of the Sheets API.
Prints values from a sample spreadsheet.
"""
creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('sheets', 'v4', credentials=creds)
# Call the Sheets API
sheet = service.spreadsheets()
result = sheet.values().get(spreadsheetId=SAMPLE_SPREADSHEET_ID,
range=SAMPLE_RANGE_NAME).execute()
curr_values = result.get('values', [])
return curr_values
def UpdateSheet(values):
"""Shows basic usage of the Sheets API.
Prints values from a sample spreadsheet.
"""
creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('sheets', 'v4', credentials=creds)
body = {
'values': values
}
result = service.spreadsheets().values().append(
spreadsheetId=SAMPLE_SPREADSHEET_ID,range=SAMPLE_RANGE_NAME,
valueInputOption='RAW', body=body).execute()
print('{0} cells appended.'.format(result \
.get('updates') \
.get('updatedCells')))
def run():
client_id, client_secret = _get_client_details()
access_token, refresh_token, expires_at = _get_user_details()
print("client_id: ", client_id)
print("client_secret: ", client_secret)
print("access_token: ", access_token)
print("refresh_token: ", refresh_token)
print("expires_at: ", expires_at)
auth2_client = Fitbit(client_id, client_secret, oauth2=True,
access_token=access_token,
refresh_token=refresh_token, expires_at=expires_at,
refresh_cb=refresh_callback)
fitbit_url = FITBIT_API + _get_api_call()
json_response = auth2_client.make_request(fitbit_url)
values = []
sheet_values = ReadSheet()
for row in json_response["weight"]:
row_exists = 0
for sheetrow in sheet_values:
if sheetrow[0] == row["date"]:
row_exists = 1
# print(row)
if row_exists == 0:
if 'fat' in row.keys():
row_list = [row["date"],row["weight"],row["fat"],row["bmi"]]
else:
row_list = [row["date"],row["weight"],"0",row["bmi"]]
values.append(row_list)
pprint(values)
UpdateSheet(values)
if __name__ == '__main__':
date_start = date.today() - timedelta(10)
date_end = date.today()
# print("Grabbin': ", date_start, date_end)
run()
# ###Bulk import
# date_start = date(2022, 8, 1)
# end_date = date(2023, 11, 1)
# print(date_start, end_date)
# #set first block of 30days
# date_end = date_start + timedelta(days=30)
# while date_end < end_date:
# print(date_start, date_end)
# run()
# time.sleep(10)
# date_start = date_start + timedelta(days=30)
# date_end = date_end + timedelta(days=30)