What is it? An automated data pipeline, inferential statistical modeling, and interactive dashboard for personal WHOOP wearable data.
Note: Despite the regression outputs, this is not a predictive model - it is an inferential one. The goal is to understand which physiological variables are most associated with recovery and HRV, not to forecast future values. Coefficients are interpreted for insight, not deployed for prediction.
example: https://ido-pi.tail9eb77e.ts.net/
How can be improved? So far, the modeling layer is intentionally inferential — the goal is understanding, not prediction, however, the natural next step is to build a lightweight MLOps layer on top of it
- Temporal train/test split — evaluate on held-out recent data for honest generalization estimates
- Model persistence — save fitted models to disk so they aren't refit on every dashboard load
- Experiment tracking — log parameters, feature sets, R², and MAE per run so changes are traceable
How is it built?
WHOOP API (v2) --> OAuth 2.0 Sync Engine --> SQLite3 --> Streamlit Dashboard
|
Cron (daily)
The platform ingests physiological data from the WHOOP REST API through an OAuth 2.0-authenticated sync engine. Records are upserted into a normalized SQLite database (6 tables, indexed queries). A Streamlit dashboard reads directly from SQLite to render interactive Plotly visualizations and regression model outputs across 7 analytical tabs.
*Two-node Raspberry Pi cluster connected to a home router via switch, with SSD storage. The dashboard container is kept up-to-date automatically via Watchtower and syncs data daily through cron. The site is exposed publicly and continuously over HTTPS using Tailscale Funnel.
| Category | Technology | Purpose |
|---|---|---|
| Language | Python 3.11 | Core application logic |
| Database | SQLite3 | 6 normalized tables, indexed columns, upsert operations |
| API | WHOOP REST API v2 | Paginated data ingestion with cursor-based pagination |
| Auth | OAuth 2.0 | Authorization code grant with automatic token refresh |
| Dashboard | Streamlit | 7-tab interactive analytics interface |
| Visualization | Plotly | Scatter, bar, pie, heatmap, histogram, subplots |
| ML / Statistics | Ridge Regression (scikit-learn) | Recovery score and HRV prediction |
| Data Processing | Pandas, NumPy | Transformation, aggregation, feature engineering |
| Containerization | Docker | Single-container deployment with health checks |
| Scheduling | Cron | Automated daily data sync pipeline |
| CI/CD | Watchtower | Automated container image updates |
Prerequisites: Docker, Docker Compose, and WHOOP Developer API credentials.
git clone https://github.com/idossha/whoop_insights.git
cd whoop_insights
cp .env.example .env
# Edit .env with your WHOOP_CLIENT_ID, WHOOP_CLIENT_SECRET, and WHOOP_REDIRECT_URIdocker compose up -d
docker compose exec dashboard python main.py auth # Complete OAuth flow in browser
docker compose exec dashboard python main.py sync --full # Initial data pullDashboard available at http://localhost:8501. Daily sync runs automatically via cron.
whoop_insights/
|-- main.py # CLI entrypoint (auth, sync, stats, status, reauth)
|-- docker-compose.yml # Dashboard + Watchtower services
|-- Dockerfile # Python 3.11-slim with cron
|-- entrypoint.sh # Container init: cron, auth check, Streamlit launch
|-- requirements.txt
|
|-- src/whoop_sync/
| |-- config.py # Dataclass-based configuration from env vars
| |-- auth.py # OAuth 2.0 flow, token management, callback server
| |-- api.py # WHOOP API v2 client with pagination generator
| |-- db.py # SQLite layer with upsert operations
| |-- models.py # Dataclass models + SQL schema definitions
| |-- mlr.py # Ridge regression models (scikit-learn)
| |-- sync.py # Sync orchestrator: incremental/full/selective
|
|-- dashboard/
| |-- dashboard.py # Streamlit app (7 tabs, Plotly visualizations)
|
|-- scripts/
| |-- setup.sh # One-command setup
| |-- backup.sh # Database backup with gzip + retention policy
|
|-- docs/
| |-- architecture.svg
| |-- correlation_matrix.png
| |-- coefficients.png
| |-- actual_vs_predicted.png
MIT License. See LICENSE for details.



