Skip to main content

CLI tool to backup fitness activities with incremental sync, map visualization, and export (Strava supported)

Project description

MyKrok

Documentation Status

Note: This project was formerly known as "mykrok". The name "MyKrok" comes from Ukrainian "мій крок" meaning "my step" - fitting for a tool that preserves every step of your fitness journey.

CLI tool to backup fitness activities with incremental sync, map visualization, and export capabilities. Currently supports Strava as the data source.

Live Demo - Try the web frontend with synthetic data. It is served directly from gh-pages branch where you could also explore the backup filetree we show below.

Features

  • Backup Activities: Download all your activities including metadata, GPS tracks, photos, comments, and kudos
  • Incremental Sync: Only fetch new activities after initial backup
  • Interactive Maps: Generate HTML maps with route visualization and heatmap mode
  • Statistics: View activity statistics by time period with breakdowns by type
  • Offline Browsing: Browse your backed-up activities locally without internet
  • FitTrackee Export: Export activities to self-hosted FitTrackee instances

Screenshots

The unified web frontend provides a complete activity browsing experience. Screenshots are auto-generated from the demo dataset (tox -e screenshots).

Map View

Map view with activity markers Map view with activity markers

Activities zoomed to fit Activities zoomed to fit

Activity popup with details Activity popup with details

Sessions View

Sessions list with filters Sessions list with filters

Sessions filtered by type Sessions filtered by type

Session detail panel Session detail panel

Session Detail

Full-screen session view Full-screen session view

Activity data streams Activity data streams (elevation, heart rate, cadence)

Statistics

Statistics dashboard Statistics dashboard

Statistics by athlete Statistics by athlete

No Backend Required

The web UI loads data directly from the file tree — no database, no server-side processing, no custom data structures. Just standard formats (TSV, JSON, Parquet) served as static files:

data/
├── athletes.tsv                    # List of athletes
├── athl=alice/
│   ├── sessions.tsv                # Activity index (dates, distances, stats)
│   └── ses=20241218T063000/
│       ├── info.json               # Activity metadata
│       ├── tracking.parquet        # GPS + sensor streams (lat, lng, hr, cadence...)
│       └── photos/
│           └── photo_1.jpg
└── athl=bob/
    ├── sessions.tsv
    └── ses=20241218T063000/        # Shared run (same datetime)
        ├── info.json
        └── tracking.parquet

The browser fetches athletes.tsv → discovers athletes → loads each sessions.tsv → renders the map/table. Clicking an activity fetches its tracking.parquet directly. This means you can:

  • Host anywhere: Any static file server (nginx, GitHub Pages, S3, local python -m http.server)
  • Query with standard tools: DuckDB, pandas, or any Parquet-compatible tool
  • Version with git/DataLad: Text files diff cleanly, binary files handled by git-annex
  • Browse offline: Open mykrok.html directly from disk

Installation

# Clone repository
git clone https://github.com/mykrok/mykrok
cd mykrok

# Install with uv (recommended)
uv venv
source .venv/bin/activate
uv pip install -e ".[devel]"

# Or with pip
pip install -e ".[devel]"

Strava API Setup

Before using MyKrok, you need to create a Strava API application:

  1. Go to https://www.strava.com/settings/api
  2. Click "Create an Application" (or use existing one)
  3. Fill in the form:
    • Application Name: e.g., "My Backup Tool"
    • Category: "Personal"
    • Website: "http://localhost" (or your own)
    • Authorization Callback Domain: "localhost"
  4. After creation, note your Client ID and Client Secret

Quick Start

  1. Authenticate with your Strava API credentials:

    mykrok auth --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET
    

    This opens a browser for OAuth authorization. After approval, tokens are saved automatically.

  2. Sync your activities:

    mykrok sync
    
  3. View your data:

    mykrok view stats
    mykrok create-browser --serve
    

Configuration

MyKrok looks for configuration in the following order:

  1. MYKROK_CONFIG environment variable (explicit path)
  2. .mykrok/config.toml in the current directory (recommended for DataLad datasets)
  3. .mykrok/config.toml in the current directory (legacy, still supported)
  4. .mykrok.toml in the current directory (legacy, still supported)
  5. ~/.config/mykrok/config.toml

OAuth tokens are stored separately in .mykrok/oauth-tokens.toml (gitignored).

Configuration File Format

Create .mykrok/config.toml in your project directory or ~/.config/mykrok/config.toml:

[strava]
client_id = "YOUR_CLIENT_ID"
client_secret = "YOUR_CLIENT_SECRET"
# These are auto-populated after `mykrok auth`:
# access_token = "..."
# refresh_token = "..."
# token_expires_at = 1234567890

[data]
directory = "./data"  # Where to store backed-up activities

[sync]
photos = true    # Download activity photos
streams = true   # Download GPS/sensor data
comments = true  # Download comments and kudos

[fittrackee]
url = "https://fittrackee.example.com"
email = "your@email.com"
# password can be set via FITTRACKEE_PASSWORD env var

Environment Variables

All settings can be overridden with environment variables:

Variable Description
MYKROK_CONFIG Path to config file
STRAVA_CLIENT_ID Strava API client ID
STRAVA_CLIENT_SECRET Strava API client secret
MYKROK_DATA_DIR Data storage directory
FITTRACKEE_URL FitTrackee instance URL
FITTRACKEE_EMAIL FitTrackee login email
FITTRACKEE_PASSWORD FitTrackee login password

Commands

Authentication

# First-time authentication
mykrok auth --client-id YOUR_ID --client-secret YOUR_SECRET

# Re-authenticate (e.g., after token expiry)
mykrok auth --force

Sync Activities

# Incremental sync (default) - only new activities since last sync
mykrok sync

# Full sync - re-download all activities
mykrok sync --what=full

# Refresh social data (kudos/comments) for existing activities
mykrok sync --what=social

# Refresh athlete profile info and avatar
mykrok sync --what=athlete-profiles

# Sync with limits
mykrok sync --limit 100

# Preview without downloading
mykrok sync --dry-run

# Skip photos/comments
mykrok sync --no-photos --no-comments

# Sync specific activities by ID
mykrok sync --activity-ids 12345678901,12345678902

View Statistics

# Overall stats
mykrok view stats

# Stats for specific year
mykrok view stats --year 2025

# Stats for specific month
mykrok view stats --month 2025-06

# Breakdown by month
mykrok view stats --by-month

# Breakdown by activity type
mykrok view stats --by-type

# JSON output
mykrok view stats --json

Generate Interactive Browser

# Generate and serve locally
mykrok create-browser --serve

# Custom port
mykrok create-browser --serve --port 9000

# Generate without serving
mykrok create-browser

# Custom output filename
mykrok create-browser --output my-activities.html

The browser includes:

  • Interactive map with activity markers and GPS tracks
  • Sessions list with filtering by date, type, and search
  • Statistics dashboard with charts
  • Heatmap layer toggle
  • Photo viewing
  • Offline support (works without internet)

Export GPX

# Export specific activity
mykrok gpx 12345678901 --output activity.gpx

# Export all activities
mykrok gpx --all --output-dir ./gpx/

Export to FitTrackee

# Export to FitTrackee
mykrok export fittrackee --url https://fittrackee.example.com --email user@example.com

# Preview what would be exported
mykrok export fittrackee --dry-run

# Force re-export all
mykrok export fittrackee --full

Create DataLad Dataset

Create a version-controlled dataset for reproducible backups using DataLad:

# Create a new DataLad dataset
mykrok create-datalad-dataset ./my-backup

# Navigate to the dataset
cd my-backup

# Edit config with your Strava API credentials
nano .mykrok/config.toml

# Authenticate
mykrok auth

# Sync using datalad run (creates versioned commit)
make sync

# Generate interactive browser for web viewing
mykrok create-browser

This creates a dataset with:

  • text2git configuration: Text files (JSON, TSV) tracked by git, binary files (photos, Parquet) by git-annex
  • Sample config: .mykrok/config.toml with comments explaining each setting
  • README: Documentation for the dataset
  • Makefile: Targets for make sync, make stats, make map, etc. using datalad run

Benefits of DataLad integration:

  • Full version history of all backups
  • Reproducible sync operations with datalad run
  • Efficient storage of binary files with git-annex
  • Easy to clone and share datasets
  • Simple publishing to web servers (see below)

Publishing to a Web Server

With DataLad, publishing your backup to a web server for browser-based viewing is trivial:

# Create a sibling that excludes sensitive files (API credentials)
datalad create-sibling -s public-website \
    --annex-wanted "not metadata=distribution-restrictions=*" \
    user@server.example.com:/var/www/mykrok

# Push your data (sensitive config files are automatically excluded)
datalad push --to=public-website

Then access the map visualization at https://your-server.example.com/mykrok/mykrok.html.

Note: Access restrictions and user management are outside the scope of this project. Implement access control using your web server's authentication mechanisms (HTTP Basic Auth, OAuth proxy, IP allowlisting, etc.).

Data Storage

Activities are stored in a Hive-partitioned directory structure:

data/
├── athletes.tsv                  # Summary of all athletes
├── mykrok.html                   # Generated interactive browser
└── athl={username}/
    ├── athlete.json              # Athlete profile data
    ├── avatar.jpg                # Profile photo
    ├── sessions.tsv              # Activity summary (TSV format)
    ├── gear.json                 # Equipment catalog
    └── ses={datetime}/           # Individual activity folder
        ├── info.json             # Activity metadata, comments, kudos
        ├── tracking.parquet      # GPS + sensor data (Parquet)
        ├── tracking.json         # Data manifest
        └── photos/               # Activity photos
            └── 20251218T063500.jpg

Query with DuckDB

duckdb
-- Activity summary
SELECT sport, SUM(distance_m)/1000 as km, COUNT(*) as activities
FROM read_csv_auto('data/athl=*/sessions.tsv')
GROUP BY sport;

-- GPS track analysis
SELECT ses, AVG(heartrate) as avg_hr, MAX(heartrate) as max_hr
FROM read_parquet('data/**/tracking.parquet', hive_partitioning=true)
WHERE heartrate > 0
GROUP BY ses;

Cron Setup

For automated daily backups:

# Edit crontab
crontab -e

# Add daily sync at 2 AM
0 2 * * * cd /path/to/mykrok && .venv/bin/mykrok sync --quiet

Troubleshooting

Token Expired

mykrok auth --force

Rate Limit Hit

The tool automatically pauses when hitting Strava's rate limits (200 requests/15 minutes, 1000/day) and resumes. For large initial syncs, the process may span multiple days.

Missing GPS Data

Some activities (treadmill, manual entries) have no GPS. They appear in sessions.tsv but not on maps.

Photo Download Failed

Photo URLs expire. Re-run sync to retry:

mykrok sync --full

License

Apache 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mykrok-1.4.1.tar.gz (1.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mykrok-1.4.1-py3-none-any.whl (488.8 kB view details)

Uploaded Python 3

File details

Details for the file mykrok-1.4.1.tar.gz.

File metadata

  • Download URL: mykrok-1.4.1.tar.gz
  • Upload date:
  • Size: 1.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for mykrok-1.4.1.tar.gz
Algorithm Hash digest
SHA256 0280c8e205cfdc0bd29a320a9653278308f5185080adfab53f8e1e06f7d41150
MD5 29ca1cba3351f9db3401c0d5c31a3703
BLAKE2b-256 c7eb6ff52f3c3193e11c48ac6bcc008df19d2ec1ce4ffe9f36839883c8d464d9

See more details on using hashes here.

File details

Details for the file mykrok-1.4.1-py3-none-any.whl.

File metadata

  • Download URL: mykrok-1.4.1-py3-none-any.whl
  • Upload date:
  • Size: 488.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for mykrok-1.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 768f4540d1ca77ba32aa2f52a5e4a5ed8834caf21a28eee060f0e79db3d57479
MD5 92f8c4b9eefd95c76d0b3ef09e57ca49
BLAKE2b-256 9faad9b5347e93e4ab4b96472e790e14dc140bdf364716ca5df73f8355616b24

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page