Coverage for health / config.py: 89%
27 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-02 17:44 +0800
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-02 17:44 +0800
1"""
2Configuration management for Garmin Health Sync system.
4Loads environment variables and defines data type configurations.
5"""
7import os
8from pathlib import Path
9from typing import Dict, Any
10from dotenv import load_dotenv
11from health.utils.env_loader import load_env_with_extras
13# Load environment variables
14load_env_with_extras()
16# Project paths
17PROJECT_ROOT = Path(__file__).parent.parent
19# Support environment override for testing
20_data_dir_env = os.getenv("DATA_DIR")
21if _data_dir_env:
22 DATA_DIR = Path(_data_dir_env)
23else:
24 DATA_DIR = PROJECT_ROOT / "data" / "health"
26DB_PATH = DATA_DIR / "health.db"
27LOGS_DIR = PROJECT_ROOT / "logs"
28TOKEN_STORE = Path.home() / ".garmin" / "tokens"
30# Ensure directories exist
31DATA_DIR.mkdir(parents=True, exist_ok=True)
32LOGS_DIR.mkdir(parents=True, exist_ok=True)
33TOKEN_STORE.mkdir(parents=True, exist_ok=True)
35# Garmin credentials (optional during setup, required for actual sync)
36GARMIN_EMAIL = os.getenv("GARMIN_EMAIL")
37GARMIN_PASSWORD = os.getenv("GARMIN_PASSWORD")
40def validate_credentials() -> None:
41 """Validate that Garmin credentials are set.
43 Raises:
44 ValueError: If credentials are missing
45 """
46 if not GARMIN_EMAIL or not GARMIN_PASSWORD:
47 raise ValueError(
48 "Missing Garmin credentials. Please set GARMIN_EMAIL and GARMIN_PASSWORD "
49 "in your .env file. See .env.example for reference."
50 )
52# Data type configurations
53# Maps each data type to its API method, model, and storage path
54DATA_TYPE_CONFIG: Dict[str, Dict[str, Any]] = {
55 "steps": {
56 "api_method": "get_steps_data",
57 "storage_path": "daily_metrics/steps",
58 "description": "Daily step count, distance, and calories",
59 },
60 "heart_rate": {
61 "api_method": "get_heart_rates",
62 "storage_path": "daily_metrics/heart_rate",
63 "description": "Heart rate data including min, max, resting",
64 },
65 "sleep": {
66 "api_method": "get_sleep_data",
67 "storage_path": "daily_metrics/sleep",
68 "description": "Sleep stages, duration, and quality scores",
69 },
70 "stress": {
71 "api_method": "get_stress_data",
72 "storage_path": "daily_metrics/stress",
73 "description": "Stress levels throughout the day",
74 },
75 "body_battery": {
76 "api_method": "get_body_battery",
77 "storage_path": "daily_metrics/body_battery",
78 "description": "Body Battery charge and drain",
79 },
80 "spo2": {
81 "api_method": "get_spo2_data",
82 "storage_path": "daily_metrics/spo2",
83 "description": "Blood oxygen saturation levels",
84 },
85 "respiration": {
86 "api_method": "get_respiration_data",
87 "storage_path": "daily_metrics/respiration",
88 "description": "Breathing rate data",
89 },
90 "hydration": {
91 "api_method": "get_hydration_data",
92 "storage_path": "daily_metrics/hydration",
93 "description": "Daily water intake tracking",
94 },
95 "floors": {
96 "api_method": "get_floors",
97 "storage_path": "daily_metrics/floors",
98 "description": "Floors climbed per day",
99 },
100 "intensity_minutes": {
101 "api_method": "get_intensity_minutes",
102 "storage_path": "daily_metrics/intensity_minutes",
103 "description": "Active intensity minutes (moderate and vigorous)",
104 },
105 "hrv": {
106 "api_method": "get_hrv_data",
107 "storage_path": "daily_metrics/hrv",
108 "description": "Heart rate variability",
109 },
110 "rhr": {
111 "api_method": "get_rhr_day",
112 "storage_path": "daily_metrics/rhr",
113 "description": "Resting heart rate",
114 },
115 "activities": {
116 "api_method": "get_activities_by_date",
117 "storage_path": "activities",
118 "description": "Exercise activities and workouts",
119 "batch_by_date_range": True,
120 },
121 "weight": {
122 "api_method": "get_weigh_ins",
123 "storage_path": "body_metrics/weight",
124 "description": "Body weight measurements",
125 },
126 "lifestyle_logging": {
127 "api_method": "get_lifestyle_logging_data",
128 "storage_path": "daily_metrics/lifestyle_logging",
129 "description": "Lifestyle behaviors: alcohol, caffeine, meals, fasting, light exercise",
130 },
131}
133# Sync settings
134DEFAULT_BATCH_SIZE_DAYS = 30 # Process 30 days at a time for batch operations
135MAX_RETRIES = 3 # Maximum retry attempts for API calls
136RETRY_DELAY_SECONDS = 2 # Initial delay before retrying (exponential backoff)
138# Historical data start date (user configurable)
139HISTORICAL_START_DATE = "2024-01-01" # Default, can be overridden via CLI