A personal tool to fetch and analyze my Strava activities using the Strava API with OAuth2 authentication.
I wanted to get the most out of my training data. Strava gives you the basics, but there's so much more buried in those activity files. By pulling all my data locally, I can dig deeper, run custom analysis, build visualizations that actually matter to me, and discover insights that the standard apps just don't show.
Plus, let's be honest, this was a perfect excuse to write SQL queries again!
- Create a Strava app: https://www.strava.com/settings/api
- Get your client ID and secret
- Get your refresh token
- Create a
.envfile with your Strava app credentials:
STRAVA_CLIENT_ID=your_client_id
STRAVA_CLIENT_SECRET=your_client_secret
STRAVA_REFRESH_TOKEN=your_refresh_token # Will be updated after first authThe workflow is the following:
uv run fetch.py→ fetches activities from Strava APIuv run analyze.py→ processes the JSON data into DuckDB databaseduckdb strava_activities.duckdb -f queries/<query-name>.sql→ runs analysis queries
Note: Re-run
uv run analyze.pywhenever you fetch new activities to update your DuckDB database with the latest data.
What it does:
- Launches a local auth server on http://localhost:8000
- Opens your browser automatically for Strava authorization
- Handles the OAuth callback seamlessly
- Fetches ALL your historical activities (using pagination)
- Saves everything to
activities/<username>_yyyy-mm-dd_export.jsonwith a nice summary breakdown - Stores activities in a DuckDB database for fast querying
- uv (recommended) or Python 3.11+ installed on your machine
- DuckDB for database queries and UI
- A Strava API app (free to create)
- Your Strava credentials in a
.envfile
Your activities get saved to activities/<username>_yyyy-mm-dd_export.json with all the juicy details:
- Performance metrics: Distance, time, elevation, pace/speed
- Physiological data: Heart rate zones, power output, cadence
- Route data: GPS coordinates, polyline for mapping
- Activity metadata: Kudos, photos, gear used, weather conditions
Perfect for building your own analysis dashboards, tracking progress, or feeding into ML models for performance insights.
Your activities are stored in a DuckDB database (strava_activities.duckdb) for fast querying. Pre-built queries are organized by sport for personalized analysis:
queries/global/- Overall activity analysisqueries/running/- Running and trail running specific analysisqueries/strength/- CrossFit and weight training analysisqueries/dashboard/- Comprehensive training dashboard with all metrics
Get a complete overview of your training with the comprehensive dashboard:
duckdb strava_activities.duckdb -f queries/dashboard/dashboard.sqlThis shows:
- Weekly & Monthly Trends: Training volume, intensity, and progression
- Performance Analysis: Pace trends, heart rate zones, personal records
- Training Balance: Sport distribution, consistency scores, workout scheduling
- Recent Activity Log: Latest workouts with key metrics
- Strength Training: Session frequency, intensity patterns, optimal training days
Run any specific query with:
duckdb strava_activities.duckdb -f queries/<folder>/<query-name>.sqlOr launch the DuckDB web UI for interactive exploration:
duckdb -ui strava_activities.duckdb- Port 8000 busy? The app will tell you - just kill whatever's using it
- Browser won't open? Copy the authorization URL manually
- Empty activities? Check your Strava privacy settings and API permissions