Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI, HTTPException | |
| from pydantic import BaseModel | |
| import numpy as np | |
| import onnxruntime as ort | |
| app = FastAPI( | |
| title="Spandan ONNX API", | |
| version="1.0.0", | |
| description="REST API for Stress, Physical Activity, Focus and Cognitive Engagement prediction using ONNX models." | |
| ) | |
| # ========================================================== | |
| # Load Models | |
| # ========================================================== | |
| wearable_model = ort.InferenceSession("full_dataset_model_filewearable_model.onnx") | |
| distraction_model = ort.InferenceSession("distraction_model.onnx") | |
| wearable_input = wearable_model.get_inputs()[0].name | |
| distraction_input = distraction_model.get_inputs()[0].name | |
| CLASS_NAMES = [ | |
| "Stress", | |
| "Physical Activity", | |
| "Normal" | |
| ] | |
| # ========================================================== | |
| # Request Schemas | |
| # ========================================================== | |
| class WearableInput(BaseModel): | |
| sensor_values: list[float] | |
| class DistractionInput(BaseModel): | |
| sensor_values: list[float] | |
| # ========================================================== | |
| # Health Check | |
| # ========================================================== | |
| def root(): | |
| return { | |
| "message": "Spandan API Running", | |
| "status": "healthy", | |
| "version": "1.0.0" | |
| } | |
| # ========================================================== | |
| # Model 1 - Stress / Physical Activity / Focus | |
| # ========================================================== | |
| def predict_state(data: WearableInput): | |
| if len(data.sensor_values) != 13: | |
| raise HTTPException( | |
| status_code=400, | |
| detail=f"Expected exactly 13 sensor values, got {len(data.sensor_values)}" | |
| ) | |
| x = np.array([data.sensor_values], dtype=np.float32) | |
| try: | |
| logits = wearable_model.run( | |
| None, | |
| { | |
| wearable_input: x | |
| } | |
| )[0][0] | |
| prediction = int(np.argmax(logits)) | |
| # Stable Softmax | |
| exp = np.exp(logits - np.max(logits)) | |
| probabilities = exp / np.sum(exp) | |
| return { | |
| "prediction": CLASS_NAMES[prediction], | |
| "confidence": round(float(probabilities[prediction]), 4), | |
| "scores": { | |
| CLASS_NAMES[i]: round(float(probabilities[i]), 4) | |
| for i in range(len(CLASS_NAMES)) | |
| } | |
| } | |
| except Exception as e: | |
| raise HTTPException( | |
| status_code=500, | |
| detail=f"Model inference failed: {str(e)}" | |
| ) | |
| # ========================================================== | |
| # Model 2 - Cognitive Engagement | |
| # ========================================================== | |
| def predict_engagement(data: DistractionInput): | |
| if len(data.sensor_values) != 7: | |
| raise HTTPException( | |
| status_code=400, | |
| detail=f"Expected exactly 7 sensor values, got {len(data.sensor_values)}" | |
| ) | |
| x = np.array([data.sensor_values], dtype=np.float32) | |
| try: | |
| prediction = int( | |
| distraction_model.run( | |
| None, | |
| { | |
| distraction_input: x | |
| } | |
| )[0][0] | |
| ) | |
| status = "Neutral" if prediction == 1 else "Distracted" | |
| return { | |
| "prediction": prediction, | |
| "status": status | |
| } | |
| except Exception as e: | |
| raise HTTPException( | |
| status_code=500, | |
| detail=f"Model inference failed: {str(e)}" | |
| ) |