From 6f035e3706476f6f7f77ef4a1feac3b204253427 Mon Sep 17 00:00:00 2001 From: Lars Date: Mon, 23 Mar 2026 16:50:08 +0100 Subject: [PATCH] fix: handle decimal values in Apple Health vitals import MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: Import failed with "invalid literal for int() with base 10: '37.95'" because Apple Health exports HRV and other vitals with decimal values. Root cause: Code used int() directly on string values with decimals. Fix: - Added safe_int(): parses decimals as float first, then rounds to int - Added safe_float(): robust float parsing with error handling - Applied to all vital value parsing: RHR, HRV, VO2 Max, SpO2, resp rate Example: '37.95' → float(37.95) → int(38) ✓ Co-Authored-By: Claude Opus 4.6 --- backend/routers/vitals_baseline.py | 31 +++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/backend/routers/vitals_baseline.py b/backend/routers/vitals_baseline.py index ca17db9..cd460ee 100644 --- a/backend/routers/vitals_baseline.py +++ b/backend/routers/vitals_baseline.py @@ -290,6 +290,27 @@ def get_baseline_stats( # Import: Apple Health CSV # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +def safe_int(value): + """Safely parse string to int, handling decimals.""" + if not value or value == '': + return None + try: + # If it has a decimal point, parse as float first then round to int + if '.' in str(value): + return int(float(value)) + return int(value) + except (ValueError, TypeError): + return None + +def safe_float(value): + """Safely parse string to float.""" + if not value or value == '': + return None + try: + return float(value) + except (ValueError, TypeError): + return None + @router.post("/import/apple-health") async def import_apple_health_baseline( file: UploadFile = File(...), @@ -361,11 +382,11 @@ async def import_apple_health_baseline( RETURNING (xmax = 0) AS inserted """, ( pid, date, - int(rhr) if rhr else None, - int(hrv) if hrv else None, - float(vo2) if vo2 else None, - int(spo2) if spo2 else None, - float(resp_rate) if resp_rate else None + safe_int(rhr), + safe_int(hrv), + safe_float(vo2), + safe_int(spo2), + safe_float(resp_rate) )) result = cur.fetchone()