Appearance
Apple Health Extraction
owner: jimmy-neutron + zoro
first_touched: 2026-05-26
last_touched: 2026-05-26
Phase 1 Shipped — Export.xml Python ETL to Per-Category CSVs
source: documentation/activities/apple-health-phase1.md
Task #840054. Phase 1 (export.xml to Python ETL to per-category CSVs) is live. Phase 2 (Shortcut daily delta sync) and Phase 3 (Parquet + jimmy-vps webhook) deferred.
Files landed (Sandpit commit 877cc21)
~/Sandpit/hinata/scripts/parse-apple-health.py— stdlib-only ElementTree.iterparse over export.xml. Streaming = memory-bounded; safe on 1-10GB exports. Per-HKType cursor in state.json = idempotent.~/Library/LaunchAgents/com.hinata.health-normaliser.plist— 03:15 daily. Not loaded yet.
Storage shape
~/Sandpit/hinata/data/health/
├── inbox/ drop export.zip or export.xml here
├── processed/ timestamped archive of consumed inputs
├── csv/
│ ├── activity/ steps, distance, active_energy, exercise_min, stand_hr, flights
│ ├── vitals/ heart_rate, resting_hr, hrv, spo2, respiratory_rate, vo2max, bp_*, body_temp
│ ├── sleep/ sleep_stages
│ ├── body/ weight, bmi, body_fat, lean_mass, height, waist
│ ├── mobility/ walking_asymmetry, double_support, step_length, walking_speed, stair_*
│ ├── nutrition/ calories, protein, carbs, fat, water, caffeine, sugar, fiber, sodium
│ ├── mindfulness/ meditation
│ ├── cardiac/ afib_events, high_hr_events, low_hr_events
│ ├── environmental/ headphone_exposure, noise_exposure
│ ├── workouts/ workouts (with totalEnergyBurned + totalDistance)
│ └── other/ any unmapped HKType (safety net)
├── state.json cursor: {HKType: lastSeenStartDate}
└── parse-apple-health.logWhy stdlib-only
pandas + lxml would be cleaner code but add dependency installs to every Mac that runs the LaunchAgent. stdlib xml.etree.ElementTree.iterparse is sufficient and runs everywhere.
Verification path (Michael)
iPhone Health profile picture → Export All Health Data → AirDrop export.zip to Mac
Save to
~/Sandpit/hinata/data/health/inbox/python3 ~/Sandpit/hinata/scripts/parse-apple-health.pyls ~/Sandpit/hinata/data/health/csv/→ confirm categorieslaunchctl load ~/Library/LaunchAgents/com.hinata.health-normaliser.plist
What this closes
* #840054 closure trigger met when verification step 5 runs without error
* #200009 (Zoro body-weight query) auto-resolves once csv/body/weight.csv exists
◆ hinata · apple-health-extraction · folded from documentation/activities/ phase-19