A Python package for analyzing running data from Garmin Connect, with a focus on comparing different running power metrics (Stryd, Garmin, RunPowerModel). This code is also showed just for transparency on how data was gathered and was posted to my Facebook page: Run with Data.
- Fetch running activities from Garmin Connect
- Compare power metrics from different sources:
- Stryd Running Power
- Garmin Running Power
- RunPowerModel (third-party CIQ app)
- Cache activity details locally to minimize API calls
- Support for various running metrics including:
- Power
- Speed/Pace
- Cadence
- Ground Contact Time
- Vertical Oscillation
- And more...
- Clone this repository
- Install dependencies:
pip install -r requirements.txt
- Create a
.env
file with your Garmin credentials:
GARMIN_EMAIL=your.email@example.com
GARMIN_PASSWORD=your_password
Here's a basic example of fetching running activities and analyzing power data:
from running_dot.client.garmin import GarminClient
from running_dot.utils import get_power_indices
# Initialize client
client = GarminClient()
# Get last 10 running activities
activities = client.get_run_activities(total=10)
# Load details for first activity
activity = activities[0]
activity.load_details(client)
# Get power data indices
power_indices = get_power_indices(activity)
# Access different power metrics
stryd_power = activity.run_metrics[power_indices["stryd"]].value
garmin_power = activity.run_metrics[power_indices["garmin"]].value
rpm_power = activity.run_metrics[power_indices["runpowermodel"]].value
# get dataframe from run
df = activity.load_df(client)
running_dot/
client/
- API client implementationsdata_field/
- Data field definitions for different metricsschema/
- Data models and schemasfont/
- Store brand's font (Open Sauce).utils.py
- Utility functionsstyle.py
- Store matplotlib plot style that corresponded to page CI.
Key dependencies include:
garminconnect
matplotlib
numpy
pandas
folium
tqdm
Activity details are cached locally to minimize API calls. Cache location:
def __init__(self, cache_dir: str = "~/.cache/garmin_activities") -> None:
super().__init__()
self.cache_dir = os.path.expanduser(cache_dir)
self.details_cache_dir = os.path.join(self.cache_dir, "details")
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request
MIT License
Chompakorn Chaksangchaichot