Skip to content

gchris79/Stryder

Repository files navigation

Stryder 🏃‍♂️

Local Running Data Analysis — TUI & Web Viewer

Stryder is a modular, local-first running data management system built around Stryd and Garmin CSV exports.

It provides multiple interfaces on top of the same shared core:

  • Stryder Core handles parsing, matching, normalization, and metrics.
  • Stryder TUI (Textual) provides a full-screen interactive terminal interface.
  • Stryder Web (Django) provides a read-only web viewer on the same database.

Stryder is designed both as a personal analytics tool and as a software architecture learning project focused on modular design and multi-interface systems.


🧱 Architecture Overview

Stryder's Architecture

Stryder is structured as a multi-layer application:

🧠 Stryder Core

  • Shared business logic used by all interfaces
  • CSV parsing and normalization
  • Timezone-aware Garmin ↔ Stryd matching (±60s tolerance)
  • Canonical metrics and summaries
  • SQLite database schema

🖥️ Stryder TUI (Textual)

  • Interactive terminal-based UI built with Textual
  • Async import workflow with live progress
  • Integrated find-unparsed review flow
  • DataTable-based run navigation with pagination
  • Terminal graph visualizations (plotext)
  • Non-blocking background workers

🌐 Stryder Web (Django)

  • Local web viewer running on Django
  • Single run detailed reports with interactive graphs
  • Custom date range reports
  • User-selectable X/Y axes
  • Read-only by design (no imports via web)

All interfaces operate on the same Stryder data database (runs_data.db),
while Django maintains a separate internal database for framework features.


📽️ TUI Demo

▶ Watch 1 minute demo: https://youtu.be/VWjr1V5QczQ


📽️ Demo (Web Viewer)

1. Custom range run view

View your stored runs filtering them by custom dates or keywords.

Custom range run view


2. Single run summary view

Visualize your training load with selectable axes.

Single Run Summary View


✨ Features

Core

  • Timezone-aware Stryd ↔ Garmin matching (±60s tolerance)
  • Canonical metrics system (distance_km, avg_power, etc.)
  • Normalized workout naming
  • Local SQLite storage

TUI

  • Full-screen interactive terminal interface
  • Background worker-based imports
  • Integrated unmatched-run review workflow
  • Paginated run views
  • Terminal graph visualizations

Web

  • Single run detailed reports
  • Custom date range analysis
  • Interactive X/Y axis selection
  • Clean page-based layout

📄 Files You Need

Before using Stryder, make sure you have:

✅ Stryd CSV Files

Detailed per-run CSV files exported from Stryd PowerCenter or the mobile app.

Each file contains second-by-second metrics (pace, power, cadence, etc.).

Export them in bulk and place them in a folder.

Example filenames:

5059274362093568.csv  
5073428460371968.csv  

✅ Garmin CSV Export

A single CSV file containing summary data for your Garmin runs.

To download:

  1. Visit https://connect.garmin.com/
  2. Go to Activities
  3. Export all (or running-only) activities as .csv

Example filename:

activities.csv 

⚠️ Stryder matches runs using start timestamps with timezone-aware comparison and a ±60 second tolerance.


🧪 Demo Data (Included)

For quick testing, the repository includes example files:

  • assets/stryd/ → Sample Stryd per-run CSV files
  • assets/garmin/ → Matching Garmin activities CSV

You can use these to test the full import and reporting pipeline without exporting your own data.

Simply point Stryder to these paths during import.


▶️ Getting Started

Requirements

  • Tested on Python 3.13 (recommended)
  • Previously developed on Python 3.11

1️⃣ Setup

python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt

2️⃣ Run the Textual TUI (Recommended)

python -m stryder_tui

The TUI allows you to:

  • Import Stryd and Garmin CSV files
  • Review unmatched runs
  • View reports and summaries
  • Navigate runs interactively

3️⃣ Run the Web Viewer

python manage.py runserver

The web interface:

  • Reads from the same SQLite database
  • Provides interactive visual reports
  • Does not import or modify data

⚠️ The Web viewer requires an initialized database.
Import data first using the TUI before running the web interface.

Troubleshooting

If the TUI fails to start, verify:

  • Python 3.13 is being used
  • the virtual environment is activated
  • dependencies were installed from requirements.txt

🐳 Docker (Web Viewer Deployment)

Stryder Web can be run in a production-style container setup:

Client → Nginx → Gunicorn → Django (Stryder Web)

📦 Requirements

  • Docker
  • Docker Compose

▶️ Run with Docker

1️⃣ Build and start services

docker compose up --build

2️⃣ Apply Django migrations (first run only)

docker compose run --rm web python manage.py migrate

3️⃣ Open in browser

http://localhost:8000

🧩 CLI Status

Stryder is currently TUI-first, with the Web interface focused on visualization.

The CLI is considered legacy and will be redesigned or deprecated in a future version.


🛠 Tech Stack

Core

  • Python 3.13
  • SQLite
  • Pandas

TUI

  • Textual
  • Plotext

Web

  • Django
  • HTML / CSS (Django templates)
  • Matplotlib (server-side rendering)

🧭 Roadmap

  • CLI import & summaries
  • Canonical metrics refactor
  • Web viewer (Django)
  • Textual TUI interface
  • Redesign CLI as command-driven interface (v2.0)
  • Advanced run comparisons
  • Segment-based analysis
  • Export filtered data to CSV
  • Support FIT / TCX / GPX parsing

👤 Author

Giorgos Chrysopoulos
Junior Python Developer & Hobbyist Runner

🔗 LinkedIn: https://www.linkedin.com/in/giorgos-chrisopoulos-277989374/

💡 Want to contribute? Open an issue or fork the repo!


📃 License

MIT License — see the LICENSE file.

About

Parse, store, and explore Stryd running data with usisng TUI, and Django web interfaces.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages