File size: 5,139 Bytes
976c655 d9c9ba1 149df1f 976c655 d9c9ba1 976c655 149df1f 976c655 32fbb4d 976c655 149df1f 976c655 d0c827a 149df1f d0c827a 976c655 d0c827a 149df1f d0c827a dee50ec 976c655 149df1f 32fbb4d 149df1f d0c827a 976c655 d9c9ba1 ddebb16 d0c827a 976c655 |
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 |
import os
from datetime import datetime, timedelta
import logging
import gradio as gr
from whoop import WhoopClient
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Global Whoop client
whoop_client = None
def initialize_whoop_client_with_input(email, password):
"""
Authenticates a user using the provided WHOOP email and password.
Stores credentials in the environment variables and initializes the WhoopClient.
"""
global whoop_client
if not email or not password:
return "β Please enter both email and password."
os.environ["WHOOP_EMAIL"] = email
os.environ["WHOOP_PASSWORD"] = password
try:
whoop_client = WhoopClient(username=email, password=password)
return "β
Successfully authenticated with Whoop."
except Exception as e:
return f"β Authentication failed: {e}"
def get_latest_cycle_gr():
"""
Retrieves the most recent WHOOP cycle (recovery data) for the authenticated user.
"""
if not whoop_client:
return "β Not authenticated."
try:
end_date = datetime.now().strftime("%Y-%m-%d")
start_date = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")
cycles = whoop_client.get_cycle_collection(start_date, end_date)
return cycles
except Exception as e:
return f"β Error: {e}"
def get_average_strain_gr(days):
"""
Calculates the average strain over a given number of past days.
"""
if not whoop_client:
return "β Not authenticated."
try:
end_date = datetime.now().strftime("%Y-%m-%d")
start_date = (datetime.now() - timedelta(days=int(days))).strftime("%Y-%m-%d")
cycles = whoop_client.get_cycle_collection(start_date, end_date)
if not cycles:
return "β οΈ No cycle data available."
strains = [c['score']['strain'] for c in cycles if c.get('score') and c['score'].get('strain') is not None]
if not strains:
return "β οΈ No strain data available."
avg = sum(strains) / len(strains)
return f"π Average Strain over {days} days: {avg:.2f} (from {len(strains)} entries)"
except Exception as e:
return f"β Error: {e}"
def get_workouts_gr():
"""
Fetches recent workouts for the authenticated user.
"""
if not whoop_client:
return "β Not authenticated."
try:
end_date = datetime.now().strftime("%Y-%m-%d")
start_date = (datetime.now() - timedelta(days=10)).strftime("%Y-%m-%d")
workouts = whoop_client.get_workout_collection(start_date, end_date)
if not workouts:
return "β οΈ No workout data available."
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"
for i, w in enumerate(workouts)])
return summary
except Exception as e:
return f"β Error fetching workouts: {e}"
def get_sleeps_gr():
"""
Fetches recent sleep records for the authenticated user.
"""
if not whoop_client:
return "β Not authenticated."
# try:
end_date = datetime.now().strftime("%Y-%m-%d")
start_date = (datetime.now() - timedelta(days=10)).strftime("%Y-%m-%d")
sleeps = whoop_client.get_sleep_collection(start_date, end_date)
return sleeps
# UI definition
with gr.Blocks(title="Whoop API Explorer") as demo:
gr.Markdown("# π§ WHOOP API Dashboard")
gr.Markdown("Easily authenticate and explore your WHOOP recovery and strain data.")
with gr.Group():
gr.Markdown("## π Authentication")
with gr.Row():
email_input = gr.Textbox(label="WHOOP Email", placeholder="[email protected]")
password_input = gr.Textbox(label="WHOOP Password", type="password", placeholder="β’β’β’β’β’β’β’β’")
auth_button = gr.Button("Authenticate")
auth_output = gr.Label(label="Auth Status")
with gr.Group():
gr.Markdown("## π Latest Recovery Cycle")
cycle_button = gr.Button("Fetch Latest Cycle")
latest_recovery = gr.Label(label="Recovery Score")
cycle_details = gr.Textbox(label="Full Cycle Data", visible=True, lines=6)
with gr.Group():
gr.Markdown("## ποΈ Workout Summary")
workout_button = gr.Button("Fetch Recent Workouts")
workout_output = gr.Textbox(label="Workout Summary", lines=10)
with gr.Group():
gr.Markdown("## π΄ Sleep Summary")
sleep_button = gr.Button("Fetch Recent Sleeps")
sleep_output = gr.Textbox(label="Sleep Summary", lines=10)
# Bind actions
auth_button.click(fn=initialize_whoop_client_with_input, inputs=[email_input, password_input], outputs=auth_output)
cycle_button.click(fn=get_latest_cycle_gr, outputs=cycle_details)
workout_button.click(fn=get_workouts_gr, outputs=workout_output)
sleep_button.click(fn=get_sleeps_gr, outputs=sleep_output)
# Launch app
if __name__ == "__main__":
demo.launch(mcp_server=True) |