This application fetches your running stats from Garmin Connect and writes them directly to a Google Sheet using the gspread library.
- Python 3.12+
uvfor dependency management (pip install uv)
Copy the .env.example file to .env and fill in your Garmin credentials:
cp .env.example .envEdit .env:
GARMIN_EMAIL=your_email@example.com
GARMIN_PASSWORD=your_password
SPREADSHEET_ID=your_spreadsheet_idFor a clean integration, we use the gspread library with a Google Cloud Service Account.
- Go to the Google Cloud Console and create a project.
- Enable the Google Sheets API.
- Go to IAM & Admin > Service Accounts, create a Service Account, and download a JSON key.
- You have two options for managing this key:
- Option A (Local File): Rename the downloaded file to
service_account.jsonand place it in this project root. - Option B (Secret Manager): Store the contents of the JSON key in Google Cloud Secret Manager.
- Enable the Secret Manager API.
- Create a secret and paste the JSON key content as the secret value.
- Add
GARMIN_SHEET_SECRET_NAMEto your.envfile with the full resource name (e.g.,projects/YOUR_PROJECT_ID/secrets/YOUR_SECRET_NAME/versions/latest). - Ensure the environment where you run the script has access to Google Cloud credentials (e.g., via
gcloud auth application-default loginor a service account attached to the resource).
- Option A (Local File): Rename the downloaded file to
- Share your Google Sheet with the Service Account email (found in the JSON file) as "Editor".
- Add
SPREADSHEET_IDto your.envfile.
You can use the provided Makefile for common commands:
make syncOr run the script using uv directly:
uv lock
uv run python -m src.sync_statsTo run the sync automatically and handle cases where the laptop is asleep at the scheduled time, you can use crontab.
-
Open your crontab for editing:
crontab -e
-
Add the following entry to run the script every 1 hours:
0 * * * * cd /Users/kashnitsky/Documents/garmin_sheet && make sync >> garmin_sync.log 2>&1
The script includes logic to ensure it only performs the sync once per hour, so running it every hour allows it to catch up if the laptop was asleep
-
Verify the cron job is active:
crontab -l
In a Gemini Chat or Gem, ask
Based on my latest running stats from <link to the sheet>, provide me and advice
on how to improve my running performance.