Files
FitTrack2/FitnessSync/save_garmin_creds.py
2025-12-24 18:12:11 -08:00

117 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
Script to mimic the web UI call when hitting "Save Garmin Credentials".
This script loads Garmin credentials from a .env file and sends them to the backend API.
"""
import os
import requests
import json
from dotenv import load_dotenv
import sys
# Load environment variables from .env file
load_dotenv()
def save_garmin_credentials():
# Get credentials from environment variables
garmin_username = os.getenv('GARMIN_USERNAME')
garmin_password = os.getenv('GARMIN_PASSWORD')
garmin_is_china = os.getenv('GARMIN_IS_CHINA', 'false').lower() == 'true'
if not garmin_username or not garmin_password:
print("Error: GARMIN_USERNAME and GARMIN_PASSWORD must be set in the .env file")
return False
# Backend API details
backend_host = os.getenv('BACKEND_HOST', 'localhost')
backend_port = os.getenv('BACKEND_PORT', '8000')
# Construct the API endpoint URL
api_url = f"http://{backend_host}:{backend_port}/api/setup/garmin"
# Prepare the payload
payload = {
"username": garmin_username,
"password": garmin_password,
"is_china": garmin_is_china
}
headers = {
"Content-Type": "application/json"
}
print(f"Sending Garmin credentials to: {api_url}")
print(f"Username: {garmin_username}")
print(f"Is China: {garmin_is_china}")
try:
# Make the POST request to the API endpoint
response = requests.post(api_url, json=payload, headers=headers, timeout=30)
print(f"Response Status Code: {response.status_code}")
if response.status_code == 200:
response_data = response.json()
print(f"Response: {json.dumps(response_data, indent=2)}")
if response_data.get("status") == "success":
print("✓ Garmin credentials saved and authenticated successfully!")
return True
elif response_data.get("status") == "mfa_required":
print(" Multi-factor authentication required!")
session_id = response_data.get("session_id")
print(f"MFA Session ID: {session_id}")
return "mfa_required" # Return special value to indicate MFA required
else:
print(f"⚠ Unexpected response status: {response_data.get('status')}")
return False
else:
print(f"Error Response: {response.text}")
# Provide helpful error messages based on common issues
if response.status_code == 500:
error_resp = response.json() if response.content else {}
error_msg = error_resp.get('message', '')
if 'could not translate host name "db" to address' in error_msg:
print("\nNote: This error occurs when the database container is not running.")
print("You might need to start the full stack with Docker Compose:")
print(" docker-compose up -d")
elif 'Invalid credentials' in error_msg or 'Authentication' in error_msg:
print("\nNote: Invalid Garmin username or password. Please check your credentials.")
elif 'MFA' in error_msg or 'mfa' in error_msg:
print("\nNote: Multi-factor authentication required.")
return False
except requests.exceptions.ConnectionError:
print(f"❌ Error: Could not connect to the backend at {api_url}")
print("Make sure the backend service is running on the specified host and port.")
print("\nTo start the backend service:")
print(" cd backend")
print(" docker-compose up -d")
return False
except requests.exceptions.Timeout:
print(f"❌ Error: Request timed out. The backend at {api_url} might be slow to respond or unavailable.")
return False
except requests.exceptions.RequestException as e:
print(f"❌ Request failed: {str(e)}")
return False
except json.JSONDecodeError:
print(f"❌ Error: Could not parse the response from the server.")
print(f"Raw response: {response.text}")
return False
if __name__ == "__main__":
result = save_garmin_credentials()
if result is True:
print("\n✓ Script executed successfully")
sys.exit(0)
elif result == "mfa_required":
print("\n✓ Script executed successfully (MFA required)")
sys.exit(0) # Exit with success code since this is expected behavior
else:
print("\n❌ Script execution failed")
sys.exit(1)