File size: 4,919 Bytes
a86336f
 
11e9a40
a86336f
11e9a40
a86336f
 
 
11e9a40
 
a86336f
 
11e9a40
 
314b374
11e9a40
314b374
11e9a40
314b374
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
---
title: Cardiac Monitor API
emoji: ❤️
colorFrom: red
colorTo: blue
sdk: docker
pinned: false
license: mit
app_port: 7860
short_description: Cardiac monitoring API with ML risk prediction
---

# Cardiac Monitor API

FastAPI backend for the ESP32 cardiac monitoring system. Handles user authentication, device management, vitals storage, and ML-based cardiac risk prediction.

## Live Deployment

**URL**: `https://sanuka0523-cardiac-monitor-api.hf.space`

Hosted on Hugging Face Spaces (Docker SDK). The API docs are available at `/docs` (Swagger UI).

## Tech Stack

- **Framework**: FastAPI 0.115
- **Database**: MongoDB Atlas via Motor (async)
- **Auth**: JWT (python-jose) + bcrypt password hashing
- **ML**: PyTorch (ECGFounder) + XGBoost ensemble
- **Signal Processing**: NeuroKit2, SciPy

## API Reference

### Authentication

| Method | Path | Body | Response |
|--------|------|------|----------|
| POST | `/api/v1/auth/register` | `{email, password, name}` | `{access_token, token_type}` |
| POST | `/api/v1/auth/login` | Form: `username, password` | `{access_token, token_type}` |
| GET | `/api/v1/auth/me` | — | User object |
| PUT | `/api/v1/auth/profile` | `{health_profile: {...}}` | Updated user |

### Devices

| Method | Path | Body | Response |
|--------|------|------|----------|
| POST | `/api/v1/devices/register` | `{device_id}` | Device object |
| GET | `/api/v1/devices` | — | List of devices |

### Vitals (ESP32 uploads)

| Method | Path | Auth | Body |
|--------|------|------|------|
| POST | `/api/v1/vitals` | API Key | `{device_id, timestamp, ecg_samples, heart_rate_bpm, spo2_percent, ...}` |
| GET | `/api/v1/vitals/{device_id}` | JWT | Vitals history (paginated) |
| GET | `/api/v1/vitals/{device_id}/latest` | JWT | Latest vitals reading |

### Predictions

| Method | Path | Auth | Response |
|--------|------|------|----------|
| GET | `/api/v1/predictions/{device_id}/latest` | JWT | Latest risk prediction |
| GET | `/api/v1/predictions/{device_id}` | JWT | Prediction history |

## Environment Variables

| Variable | Description | Required |
|----------|-------------|----------|
| `MONGODB_URI` | MongoDB Atlas connection string | Yes |
| `DATABASE_NAME` | Database name (default: `cardiac_monitor`) | No |
| `JWT_SECRET` | Secret key for JWT signing | Yes |
| `API_KEY` | API key for ESP32 device auth | Yes |

## Database Collections

| Collection | Purpose | Key Fields |
|------------|---------|------------|
| `users` | User accounts + health profiles | email, password_hash, health_profile |
| `devices` | Registered ESP32 devices | device_id, owner_user_id |
| `vitals` | Raw vitals readings | device_id, timestamp, ecg_samples, heart_rate_bpm |
| `predictions` | ML risk predictions | vitals_id, risk_score, risk_label, confidence |

## ML Pipeline

On each vitals upload, the backend runs an ensemble prediction:

1. **ECGFounder** (PyTorch): Deep learning model extracts features from raw ECG waveform
2. **Feature Engineering**: 14 clinical features (HRV, QRS duration, signal quality, etc.)
3. **XGBoost**: Gradient-boosted classifier on combined features
4. **Ensemble**: Weighted combination produces final risk score (0.0-1.0) and label

Risk labels: `normal`, `low`, `moderate`, `elevated`, `high`

## Local Development

```bash
cd backend
pip install -r requirements.txt

# Set environment variables
export MONGODB_URI="mongodb+srv://..."
export JWT_SECRET="your-secret"
export API_KEY="your-api-key"

# Run
uvicorn app.main:app --reload --port 8000
```

## Docker Deployment

```bash
docker build -t cardiac-api .
docker run -p 7860:7860 \
  -e MONGODB_URI="..." \
  -e JWT_SECRET="..." \
  -e API_KEY="..." \
  cardiac-api
```

## Project Structure

```
backend/
├── app/
│   ├── main.py              # FastAPI app, CORS, router mounting
│   ├── config.py            # Pydantic settings (env vars)
│   ├── database.py          # Motor client, index creation
│   ├── middleware/
│   │   └── auth.py          # JWT + API key verification
│   ├── models/              # Pydantic request/response models
│   │   ├── user.py
│   │   ├── device.py
│   │   ├── vitals.py
│   │   └── prediction.py
│   ├── routes/              # API endpoint handlers
│   │   ├── auth.py
│   │   ├── devices.py
│   │   ├── health.py
│   │   ├── vitals.py
│   │   └── predictions.py
│   └── services/
│       └── ml_service.py    # ML model loading + prediction
├── ml_src/
│   ├── ecg_foundation.py    # ECGFounder model definition
│   └── feature_engineer.py  # Clinical feature extraction
├── ml_models/               # Trained model files (LFS)
│   ├── ecgfounder_best.pt
│   └── xgboost_cardiac.joblib
├── Dockerfile
└── requirements.txt
```