Update whoop_gradio_server.py
Browse files- whoop_gradio_server.py +54 -23
whoop_gradio_server.py
CHANGED
@@ -1,4 +1,3 @@
|
|
1 |
-
#!/usr/bin/env python3
|
2 |
import os
|
3 |
from datetime import datetime, timedelta
|
4 |
import logging
|
@@ -17,13 +16,6 @@ def initialize_whoop_client_with_input(email, password):
|
|
17 |
"""
|
18 |
Authenticates a user using the provided WHOOP email and password.
|
19 |
Stores credentials in the environment variables and initializes the WhoopClient.
|
20 |
-
|
21 |
-
Args:
|
22 |
-
email (str): WHOOP account email.
|
23 |
-
password (str): WHOOP account password.
|
24 |
-
|
25 |
-
Returns:
|
26 |
-
str: Success or error message indicating authentication status.
|
27 |
"""
|
28 |
global whoop_client
|
29 |
|
@@ -42,9 +34,6 @@ def initialize_whoop_client_with_input(email, password):
|
|
42 |
def get_latest_cycle_gr():
|
43 |
"""
|
44 |
Retrieves the most recent WHOOP cycle (recovery data) for the authenticated user.
|
45 |
-
|
46 |
-
Returns:
|
47 |
-
str: Summary of latest recovery data or an error message.
|
48 |
"""
|
49 |
if not whoop_client:
|
50 |
return "β Not authenticated."
|
@@ -66,12 +55,6 @@ def get_latest_cycle_gr():
|
|
66 |
def get_average_strain_gr(days):
|
67 |
"""
|
68 |
Calculates the average strain over a given number of past days.
|
69 |
-
|
70 |
-
Args:
|
71 |
-
days (int): Number of days to include in the average.
|
72 |
-
|
73 |
-
Returns:
|
74 |
-
str: Average strain value or an error message.
|
75 |
"""
|
76 |
if not whoop_client:
|
77 |
return "β Not authenticated."
|
@@ -93,15 +76,51 @@ def get_average_strain_gr(days):
|
|
93 |
except Exception as e:
|
94 |
return f"β Error: {e}"
|
95 |
|
96 |
-
def
|
97 |
"""
|
98 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
|
100 |
-
|
101 |
-
|
102 |
|
103 |
-
|
104 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
"""
|
106 |
if raw_text.startswith("β") or raw_text.startswith("β οΈ"):
|
107 |
return raw_text, ""
|
@@ -139,10 +158,22 @@ with gr.Blocks(title="Whoop API Explorer") as demo:
|
|
139 |
strain_button = gr.Button("Calculate Average Strain")
|
140 |
average_strain = gr.Label(label="Average Strain")
|
141 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
# Bind actions
|
143 |
auth_button.click(fn=initialize_whoop_client_with_input, inputs=[email_input, password_input], outputs=auth_output)
|
144 |
cycle_button.click(fn=lambda: format_latest_cycle(get_latest_cycle_gr()), outputs=[latest_recovery, cycle_details])
|
145 |
strain_button.click(fn=get_average_strain_gr, inputs=days_input, outputs=average_strain)
|
|
|
|
|
146 |
|
147 |
# Launch app
|
148 |
if __name__ == "__main__":
|
|
|
|
|
1 |
import os
|
2 |
from datetime import datetime, timedelta
|
3 |
import logging
|
|
|
16 |
"""
|
17 |
Authenticates a user using the provided WHOOP email and password.
|
18 |
Stores credentials in the environment variables and initializes the WhoopClient.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
"""
|
20 |
global whoop_client
|
21 |
|
|
|
34 |
def get_latest_cycle_gr():
|
35 |
"""
|
36 |
Retrieves the most recent WHOOP cycle (recovery data) for the authenticated user.
|
|
|
|
|
|
|
37 |
"""
|
38 |
if not whoop_client:
|
39 |
return "β Not authenticated."
|
|
|
55 |
def get_average_strain_gr(days):
|
56 |
"""
|
57 |
Calculates the average strain over a given number of past days.
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
"""
|
59 |
if not whoop_client:
|
60 |
return "β Not authenticated."
|
|
|
76 |
except Exception as e:
|
77 |
return f"β Error: {e}"
|
78 |
|
79 |
+
def get_workouts_gr():
|
80 |
"""
|
81 |
+
Fetches recent workouts for the authenticated user.
|
82 |
+
"""
|
83 |
+
if not whoop_client:
|
84 |
+
return "β Not authenticated."
|
85 |
+
|
86 |
+
try:
|
87 |
+
end_date = datetime.now().strftime("%Y-%m-%d")
|
88 |
+
start_date = (datetime.now() - timedelta(days=10)).strftime("%Y-%m-%d")
|
89 |
+
workouts = whoop_client.get_workout_collection(start_date, end_date)
|
90 |
|
91 |
+
if not workouts:
|
92 |
+
return "β οΈ No workout data available."
|
93 |
|
94 |
+
summary = "\n\n".join([f"ποΈ Workout {i+1}:\nType: {w.get('sport_id')}, Avg HR: {w.get('avg_heart_rate')}, Calories: {w.get('kilojoule')} KJ"
|
95 |
+
for i, w in enumerate(workouts)])
|
96 |
+
return summary
|
97 |
+
except Exception as e:
|
98 |
+
return f"β Error fetching workouts: {e}"
|
99 |
+
|
100 |
+
def get_sleeps_gr():
|
101 |
+
"""
|
102 |
+
Fetches recent sleep records for the authenticated user.
|
103 |
+
"""
|
104 |
+
if not whoop_client:
|
105 |
+
return "β Not authenticated."
|
106 |
+
|
107 |
+
try:
|
108 |
+
end_date = datetime.now().strftime("%Y-%m-%d")
|
109 |
+
start_date = (datetime.now() - timedelta(days=10)).strftime("%Y-%m-%d")
|
110 |
+
sleeps = whoop_client.get_sleep_collection(start_date, end_date)
|
111 |
+
|
112 |
+
if not sleeps:
|
113 |
+
return "β οΈ No sleep data available."
|
114 |
+
|
115 |
+
summary = "\n\n".join([f"π΄ Sleep {i+1}:\nScore: {s.get('score', {}).get('sleep_score')}, Duration: {s.get('sleep_duration') // 60} min"
|
116 |
+
for i, s in enumerate(sleeps)])
|
117 |
+
return summary
|
118 |
+
except Exception as e:
|
119 |
+
return f"β Error fetching sleeps: {e}"
|
120 |
+
|
121 |
+
def format_latest_cycle(raw_text):
|
122 |
+
"""
|
123 |
+
Formats the raw text returned by get_latest_cycle_gr for display.
|
124 |
"""
|
125 |
if raw_text.startswith("β") or raw_text.startswith("β οΈ"):
|
126 |
return raw_text, ""
|
|
|
158 |
strain_button = gr.Button("Calculate Average Strain")
|
159 |
average_strain = gr.Label(label="Average Strain")
|
160 |
|
161 |
+
with gr.Group():
|
162 |
+
gr.Markdown("## ποΈ Workout Summary")
|
163 |
+
workout_button = gr.Button("Fetch Recent Workouts")
|
164 |
+
workout_output = gr.Textbox(label="Workout Summary", lines=10)
|
165 |
+
|
166 |
+
with gr.Group():
|
167 |
+
gr.Markdown("## π΄ Sleep Summary")
|
168 |
+
sleep_button = gr.Button("Fetch Recent Sleeps")
|
169 |
+
sleep_output = gr.Textbox(label="Sleep Summary", lines=10)
|
170 |
+
|
171 |
# Bind actions
|
172 |
auth_button.click(fn=initialize_whoop_client_with_input, inputs=[email_input, password_input], outputs=auth_output)
|
173 |
cycle_button.click(fn=lambda: format_latest_cycle(get_latest_cycle_gr()), outputs=[latest_recovery, cycle_details])
|
174 |
strain_button.click(fn=get_average_strain_gr, inputs=days_input, outputs=average_strain)
|
175 |
+
workout_button.click(fn=get_workouts_gr, outputs=workout_output)
|
176 |
+
sleep_button.click(fn=get_sleeps_gr, outputs=sleep_output)
|
177 |
|
178 |
# Launch app
|
179 |
if __name__ == "__main__":
|