IDKHowToCodeFr/tinyml-backend
1
1import aiosqlite2import os3import time4import asyncio5from datetime import datetime6from typing import List, Dict, Any7from huggingface_hub import HfApi, hf_hub_download8from config import settings9 10DB_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), settings.db_name)11api = HfApi()12last_sync = 013sync_lock = asyncio.Lock()14 15async def sync_from_hub():16 global last_sync17 if not settings.hf_token:18 print("No HF_TOKEN found. Skipping sync.")19 return20 21 try:22 user_info = api.whoami(token=settings.hf_token)23 username = user_info.get("name")24 if username and "IDKHowToCodeFr" in settings.repo_id:25 settings.repo_id = f"{username}/tinyml-logs"26 except Exception as e:27 print(f"Failed to fetch user info from token: {e}")28 29 30 async with sync_lock:31 if time.time() - last_sync < 60:32 return33 try:34 try:35 api.create_repo(repo_id=settings.repo_id, repo_type="dataset", exist_ok=True, token=settings.hf_token)36 except Exception as e:37 print(f"Failed to create repo: {e}")38 39 print(f"Downloading {settings.db_name} from Hub...")40 def _download():41 path = hf_hub_download(42 repo_id=settings.repo_id, 43 filename=settings.db_name, 44 repo_type="dataset", 45 token=settings.hf_token,46 force_download=True47 )48 import shutil49 shutil.copy(path, DB_PATH)50 51 await asyncio.to_thread(_download)52 last_sync = time.time()53 print("Sync from Hub complete.")54 except Exception as e:55 print(f"Sync from Hub failed: {e}")56 57async def sync_to_hub():58 if not settings.hf_token:59 return60 try:61 def _upload():62 api.upload_file(63 path_or_fileobj=DB_PATH,64 path_in_repo=settings.db_name,65 repo_id=settings.repo_id,66 repo_type="dataset",67 token=settings.hf_token68 )69 await asyncio.to_thread(_upload)70 except Exception as e:71 print(f"Sync to Hub failed: {e}")72 73async def init_db() -> None:74 await sync_from_hub()75 async with aiosqlite.connect(DB_PATH) as db:76 await db.execute('''77 CREATE TABLE IF NOT EXISTS predictions (78 id INTEGER PRIMARY KEY AUTOINCREMENT,79 timestamp DATETIME,80 heart_rate REAL,81 spo2 REAL,82 sys_bp REAL,83 dia_bp REAL,84 temp REAL,85 fall_detection TEXT,86 prediction_label TEXT,87 confidence REAL88 )89 ''')90 await db.commit()91 92async def log_prediction(data: Any, prediction_label: str, confidence: float) -> None:93 async with aiosqlite.connect(DB_PATH) as db:94 from datetime import datetime95 import zoneinfo96 ist = zoneinfo.ZoneInfo("Asia/Kolkata")97 await db.execute('''98 INSERT INTO predictions (timestamp, heart_rate, spo2, sys_bp, dia_bp, temp, fall_detection, prediction_label, confidence)99 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)100 ''', (101 datetime.now(ist).strftime("%Y-%m-%d %H:%M:%S"),102 data.Heart_Rate,103 data.SpO2_Level,104 data.Systolic_BP,105 data.Diastolic_BP,106 data.Body_Temp,107 "N/A",108 prediction_label,109 confidence110 ))111 await db.commit()112 113async def get_history() -> List[Dict[str, Any]]:114 if not os.path.exists(DB_PATH):115 return []116 117 async with aiosqlite.connect(DB_PATH) as db:118 db.row_factory = aiosqlite.Row119 async with db.execute('SELECT * FROM predictions ORDER BY timestamp DESC LIMIT 100') as cursor:120 rows = await cursor.fetchall()121 return [dict(row) for row in rows]122 