Skip to content

Commit

Permalink
Merge pull request #153 from M7-Soliman/main
Browse files Browse the repository at this point in the history
seed fix
  • Loading branch information
TrafficCop committed Apr 16, 2024
2 parents 849df3d + d0d4e4d commit 69da2c9
Show file tree
Hide file tree
Showing 10 changed files with 271 additions and 286 deletions.
14 changes: 7 additions & 7 deletions tests/devices/fitbit/test_fitbit_charge_4.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,31 +77,31 @@ def helper_test(device, start_synthetic, end_synthetic, real):
},
)
minutesAsleep = []
for datapoint in sleep:
for datapoint in sleep[0]["sleep"]:
minutesAsleep.append(datapoint["minutesAsleep"])
assert len(minutesAsleep) >= 1, "Number of sleep data points should be at least 1"
assert (
sum(minutesAsleep) / len(minutesAsleep) < 800
), f"Average minutes asleep should be less than 800 but was {sum(minutesAsleep) / len(minutesAsleep)}"

steps_arr = []
for datapoint in steps:
for datapoint in steps[0]["activities-steps"]:
steps_arr.append(datapoint["value"])
assert len(steps_arr) >= 1, "Number of steps data points should be at least 1"
assert (
sum(steps_arr) / len(steps_arr) < 20000
), f"Average steps should be less than 20000 but was {sum(steps_arr) / len(steps_arr)}"

light = []
for datapoint in minutesLightlyActive:
for datapoint in minutesLightlyActive[0]["activities-minutesLightlyActive"]:
light.append(datapoint["value"])
assert (
datapoint["value"] < 1440
), f"Value should be less than 1440 but was {datapoint['value']}"
assert len(light) >= 1, "Number of light activity data points should be at least 1"

fair = []
for datapoint in minutesFairlyActive:
for datapoint in minutesFairlyActive[0]["activities-minutesFairlyActive"]:
fair.append(datapoint["value"])
assert (
datapoint["value"] < 1440
Expand All @@ -111,7 +111,7 @@ def helper_test(device, start_synthetic, end_synthetic, real):
), "Number of fairly active minutes data points should be at least 1"

very = []
for datapoint in minutesVeryActive:
for datapoint in minutesVeryActive[0]["activities-minutesVeryActive"]:
very.append(datapoint["value"])
assert (
datapoint["value"] < 1440
Expand All @@ -121,7 +121,7 @@ def helper_test(device, start_synthetic, end_synthetic, real):
), "Number of very active minutes data points should be at least 1"

sedentary = []
for datapoint in minutesSedentary:
for datapoint in minutesSedentary[0]["activities-minutesSedentary"]:
sedentary.append(datapoint["value"])
assert (
datapoint["value"] < 1440
Expand All @@ -131,7 +131,7 @@ def helper_test(device, start_synthetic, end_synthetic, real):
), "Number of sedentary minutes data points should be at least 1"

distance_arr = []
for datapoint in distance:
for datapoint in distance[0]["activities-distance"]:
distance_arr.append(datapoint["value"])
assert (
sum(distance_arr) / len(distance_arr) < 30
Expand Down
14 changes: 7 additions & 7 deletions tests/devices/fitbit/test_fitbit_sense.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,31 +76,31 @@ def helper_test(device, start_synthetic, end_synthetic, real):
},
)
minutesAsleep = []
for datapoint in sleep:
for datapoint in sleep[0]["sleep"]:
minutesAsleep.append(datapoint["minutesAsleep"])
assert len(minutesAsleep) >= 1, "Number of sleep data points should be at least 1"
assert (
sum(minutesAsleep) / len(minutesAsleep) < 800
), f"Average minutes asleep should be less than 800 but was {sum(minutesAsleep) / len(minutesAsleep)}"

steps_arr = []
for datapoint in steps:
for datapoint in steps[0]["activities-steps"]:
steps_arr.append(datapoint["value"])
assert len(steps_arr) >= 1, "Number of steps data points should be at least 1"
assert (
sum(steps_arr) / len(steps_arr) < 20000
), f"Average steps should be less than 20000 but was {sum(steps_arr) / len(steps_arr)}"

light = []
for datapoint in minutesLightlyActive:
for datapoint in minutesLightlyActive[0]["activities-minutesLightlyActive"]:
light.append(datapoint["value"])
assert (
datapoint["value"] < 1440
), f"Value should be less than 1440 but was {datapoint['value']}"
assert len(light) >= 1, "Number of light activity data points should be at least 1"

fair = []
for datapoint in minutesFairlyActive:
for datapoint in minutesFairlyActive[0]["activities-minutesFairlyActive"]:
fair.append(datapoint["value"])
assert (
datapoint["value"] < 1440
Expand All @@ -110,7 +110,7 @@ def helper_test(device, start_synthetic, end_synthetic, real):
), "Number of fairly active minutes data points should be at least 1"

very = []
for datapoint in minutesVeryActive:
for datapoint in minutesVeryActive[0]["activities-minutesVeryActive"]:
very.append(datapoint["value"])
assert (
datapoint["value"] < 1440
Expand All @@ -120,7 +120,7 @@ def helper_test(device, start_synthetic, end_synthetic, real):
), "Number of very active minutes data points should be at least 1"

sedentary = []
for datapoint in minutesSedentary:
for datapoint in minutesSedentary[0]["activities-minutesSedentary"]:
sedentary.append(datapoint["value"])
assert (
datapoint["value"] < 1440
Expand All @@ -130,7 +130,7 @@ def helper_test(device, start_synthetic, end_synthetic, real):
), "Number of sedentary minutes data points should be at least 1"

distance_arr = []
for datapoint in distance:
for datapoint in distance[0]["activities-distance"]:
distance_arr.append(datapoint["value"])
assert (
sum(distance_arr) / len(distance_arr) < 30
Expand Down
123 changes: 7 additions & 116 deletions wearipedia/devices/fitbit/fitbit_authenticate.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,125 +4,16 @@

import requests

__all__ = ["login", "fitbit_application", "fitbit_token"]
__all__ = ["fitbit_token"]


def login(email, password):
if len(email) == 0: # fake the login
token = ""
user_id = ""
else:
login = requests.post(
"https://accounts.fitbit.com/login",
json={
"grant_type": "password",
"issueRefresh": False,
"password": password,
"username": email,
},
)
def fitbit_token():
"""gives us access token given the login info
:return: access token
:rtype: str
"""

def fitbit_application():
"""gives us access token given the auth_creds + going through the process, it's interactive
Returns the client id and client secret"""

params = {
"Description": "Any thing here should suffice",
"Application Website URL": "Place any url here, even google.com",
"Organization": "type the name of the organization",
"Organization Website URL": " type organization webiste",
"Terms of Service URL": "Any Url should suffice",
"Privacy Policy URL": "Any Url should suffice",
"OAuth 2.0 Application Type": "choose the appropriate type",
"Redirect URL": "https://127.0.0.1/8080",
}

print(
"fill the following parameters in this url then input the resulting client id and secret: ",
"https://dev.fitbit.com/apps/new",
"\n",
)
for key, value in params.items():
print(key, ":", value)

client_id = input("Enter the client id: ")
client_secret = input("Enter the client secret: ")

return client_id, client_secret


def fitbit_token(client_id, client_secret):
"""generates an access token"""

code_verifier = (
base64.urlsafe_b64encode(os.urandom(43)).decode("utf-8")
if "code_verifier" not in locals()
else code_verifier
)
code_challenge = (
base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode("utf-8")).digest())
.decode("utf-8")
.replace("=", "")
)

variables = dict()

# user specified
variables["client_id"] = client_id
variables["client_secret"] = client_secret
variables["expires_in"] = "31536000" # expiry of token in seconds

# constants or one-time generated
variables["code_verifier"] = code_verifier
variables["code_challenge"] = code_challenge
variables["code_challenge_method"] = "S256"
variables["response_type"] = "token" # code
variables["scope"] = (
"weight%20location%20settings%20profile%20nutrition%20"
+ "activity%20sleep%20heartrate%20social"
)
variables["prompt"] = "none"
variables["redirect_uri"] = "https://127.0.0.1/8080"
variables["grant_type"] = "authorization_code"
variables["authorization"] = base64.urlsafe_b64encode(
bytes(variables["client_id"] + ":" + variables["client_secret"], "utf-8")
).decode("utf-8")

# combine all parameters into the url string
url = "https://www.fitbit.com/oauth2/authorize" # authorization endpoint
for key in [
"client_id",
"redirect_uri",
"code_challenge",
"code_challenge_method",
"scope",
"response_type",
"expires_in",
]:
if url == "https://www.fitbit.com/oauth2/authorize":
url += "?" + key + "=" + variables[key]
else:
url += "&" + key + "=" + variables[key]

print(
"Click the URL above to access the Authorization page. Check Allow All and click the Allow button in red then input the resulting url",
url,
)

authurl = input("Enter the resulting url: ")

lst_of_token = []
append = False
for i in authurl:
if i == "=":
append = True
continue
elif i == "&":
break
if append == True:
lst_of_token.append(i)

access_token = "".join(lst_of_token)
access_token = input("Enter your access token: ")

return access_token
38 changes: 27 additions & 11 deletions wearipedia/devices/fitbit/fitbit_charge_4.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from ...utils import bin_search, seed_everything
from ..device import BaseDevice
from .fitbit_authenticate import *
from .fitbit_sense_fetch import *
from .fitbit_sense_gen import *
from .fitbit_charge4_fetch import *
from .fitbit_charge_4_gen import *

class_name = "Fitbit_charge_4"

Expand Down Expand Up @@ -32,8 +32,8 @@ class Fitbit_charge_4(BaseDevice):
def __init__(
self,
seed=0,
synthetic_start_date="2022-03-01",
synthetic_end_date="2022-06-17",
synthetic_start_date="2022-12-01",
synthetic_end_date="2023-01-01",
):

params = {
Expand Down Expand Up @@ -62,6 +62,7 @@ def __init__(

def _default_params(self):
params = {
"seed": 0,
"start_date": "2022-04-24",
"end_date": "2022-04-28",
}
Expand All @@ -83,21 +84,35 @@ def _filter_synthetic(self, data, data_type, params):
num_days_start = delta1.days
num_days_end = delta2.days

return data[num_days_start : -num_days_end + 1]
key_map = {
"sleep": "sleep",
"steps": "activities-steps",
"minutesVeryActive": "activities-minutesVeryActive",
"minutesLightlyActive": "activities-minutesLightlyActive",
"minutesFairlyActive": "activities-minutesFairlyActive",
"distance": "activities-distance",
"minutesSedentary": "activities-minutesSedentary",
}

if data_type in key_map:
key = key_map[data_type]
intermediary = data[0][key][num_days_start : -num_days_end + 1]
return [{key: intermediary}]

def _get_real(self, data_type, params):

data = fetch_real_data(
data_type,
self.user,
start_date=self.init_params["start_date"],
end_date=self.init_params["end_date"],
start_date=params["start_date"],
end_date=params["end_date"],
)
return data

def _gen_synthetic(self):

syn_data = create_syn_data(
self.init_params["seed"],
self.init_params["synthetic_start_date"],
self.init_params["synthetic_end_date"],
)
Expand All @@ -109,8 +124,9 @@ def _gen_synthetic(self):
self.distance = syn_data["distance"]
self.minutesSedentary = syn_data["minutesSedentary"]

def _authenticate(self, client_id):
def _authenticate(self, token=""):
# authenticate this device against API
fitbit_application()
client_secret = input("enter client secret: ")
self.user = fitbit_token(client_id, client_secret)
if token == "":
self.user = fitbit_token()
else:
self.user = token
Loading

0 comments on commit 69da2c9

Please sign in to comment.