A CLI tool for managing personal health data from Apple Health and SleepCycle. Load data into a local DuckDB database, generate AI-powered health narratives with Claude, and build interactive static HTML dashboards — no database server required.
Features
vitalog load— Extract Apple Health XML exports and SleepCycle CSV data into a local DuckDB databasevitalog narrative— Generate AI-written health journal entries using Claude, with trend analysis and period-over-period comparisonsvitalog dashboard— Build self-contained static HTML dashboards with D3.js charts, Leaflet workout route maps, dark mode, and interactive tooltips
Installation
pip install vitalog
Or install from source with uv:
git clone https://github.com/geocoug/vitalog.git
cd vitalog
uv sync --all-extras
Usage
Load data
# Load an Apple Health export (ZIP from iPhone → Health → Export)
vitalog load apple --file data/export.zip
# Load SleepCycle app data (CSV export)
vitalog load sleep --file data/sleepdata.csv
# Load both at once
vitalog load all --apple data/export.zip --sleep data/sleepdata.csv
# Apple Health only (SleepCycle is optional)
vitalog load all --apple data/export.zip
Both commands write to vitalog.duckdb in the current directory by default. Override with --db path/to/file.duckdb.
Generate a health narrative
# Last week summary
vitalog narrative --period last-week
# Custom date range, saved to file
vitalog narrative --start 2025-01-01 --end 2025-03-31 --output q1-narrative.md
# Ask a specific question about your health data
vitalog narrative --question "How has my sleep quality changed?"
# Question with a specific time period
vitalog narrative --period last-month -q "Am I exercising enough?"
Set your profile (optional)
# Provide demographics for personalized health context in narratives
vitalog profile --age 35 --weight 175 --height 70 --sex male
# View current profile
vitalog profile --show
Demographics are stored in the DuckDB database and used to contextualize metrics in narratives (e.g., age-appropriate resting HR norms, BMI, VO2Max percentiles).
Generate a health narrative
Requires ANTHROPIC_API_KEY set in your environment or .env file.
Optionally set ANTHROPIC_MODEL to choose a specific Claude model (defaults to claude-sonnet-4-20250514).
Build a dashboard
# Last year dashboard (opens in browser)
vitalog dashboard --period last-year
# Custom range, no auto-open
vitalog dashboard --start 2024-01-01 --end 2024-12-31 --output 2024.html --no-open
Generates a self-contained HTML file with 20+ interactive charts across 6 tabs: Overview, Vitals, Sleep, Training, Activity, and Routes.
Data Sources
Apple Health Export
How to export: iPhone → Health app → profile icon → Export All Health Data → save ZIP file.
Expected format: A ZIP archive containing:
apple_health_export/export.xml— All health records, workouts, and activity summariesapple_health_export/workout-routes/*.gpx— GPS tracks for outdoor workouts
What gets extracted:
| Category | Metrics |
|---|---|
| Activity | Steps, flights climbed, walking speed, distance |
| Heart | Heart rate, resting HR, HRV, VO2Max |
| Body | SpO2, respiratory rate |
| Workouts | Type, duration, distance, running pace, power, cycling stats |
| Sleep | Apple Health sleep analysis (duration) |
| Activity Rings | Move, Exercise, Stand — values and goals |
| Routes | GPS trackpoints with elevation, speed, accuracy |
SleepCycle CSV
How to export: SleepCycle app → Profile → More → Database → Export Database → save CSV file.
Expected format: Semicolon-delimited CSV (;) with headers including:
Start;End;Sleep Quality;Regularity;Deep (seconds);Light (seconds);Dream (seconds);
Awake (seconds);Heart rate (bpm);Steps;...
What gets extracted: Sleep duration, quality percentage, stage breakdown (deep/light/REM/awake), heart rate, environmental data (air pressure, temperature, weather), and snore time.
What Gets Produced
DuckDB Database
A local vitalog.duckdb file with staging tables and analytical views:
| Table | Contents |
|---|---|
stg_records |
All Apple Health records (steps, HR, VO2Max, etc.) with a record_type discriminator |
stg_workouts |
Workout sessions (type, duration, distance) |
stg_activity_summary |
Daily activity ring data (move, exercise, stand) |
stg_workout_routes |
GPS trackpoints from workout GPX files |
stg_sleep_cycle |
SleepCycle app data |
Plus analytical views: daily_steps, daily_heart_rate, daily_resting_hr, daily_summary, workout_summary, sleep_combined.
Dashboard
A single self-contained HTML file (~700KB) with:
- 6 tabbed sections with 20+ interactive charts built with D3.js
- Summary cards with sparkline trends
- Personal records section
- Monthly summary table with conditional formatting
- Workout route maps with GPS tracks built with Leaflet
- Dark/light mode toggle
- Print-friendly CSS
Narrative
A markdown document with a 3-5 paragraph AI-generated health journal entry covering steps, heart rate, sleep, workouts, and activity rings — with trend analysis vs. the prior equivalent period.
Development
# Clone and install
git clone https://github.com/geocoug/vitalog.git
cd vitalog
uv sync --all-extras
# Run tests
just test
# Lint + format
just lint
# Run pre-commit hooks
just pre-commit
# See all available recipes
just
License
Release files for vitalog 0.2.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| vitalog-0.2.3.tar.gz | 192.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vitalog-0.2.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 281.1 kB
Release files / vitalog-0.2.3.tar.gz
| Download URL | vitalog-0.2.3.tar.gz |
|---|---|
| Size | 192.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
78cc3f5ab40ba17b42f871b92cd6fa90171d8f9bd96c3d829ffcd269e6a98023
|
|
BLAKE2b-256 checksum How to use checksums |
97a90f6b1cc0ca6bce59b7d605e41b7a5ee012c74e927a46a8d5ca65f7400f04
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 27, 2026.
Transparency logRelease files / vitalog-0.2.3-py3-none-any.whl
| Download URL | vitalog-0.2.3-py3-none-any.whl |
|---|---|
| Size | 88.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3af16141baf9919f3637f8eb7cfa27b5bcd72910a440b00f510b63303fb3da77
|
|
BLAKE2b-256 checksum How to use checksums |
6f2e789d29582ae6e9bf4f551d1bf6a89921a0f3840aaea7d60483912bf5123a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 27, 2026.
Transparency log