Spaces:
Sleeping
Sleeping
File size: 9,771 Bytes
48378a2 e84de77 48378a2 bc672d9 48378a2 5677c6b 48378a2 dbe5e9c 48378a2 dbe5e9c 48378a2 dbe5e9c 48378a2 dbe5e9c 48378a2 e84de77 48378a2 b31a381 dbe5e9c 48378a2 5677c6b b31a381 e84de77 78b4eda e84de77 dbe5e9c 5677c6b e84de77 5677c6b b31a381 dbe5e9c e84de77 dbe5e9c a896d78 dbe5e9c a896d78 dbe5e9c a896d78 dbe5e9c 78b4eda dbe5e9c 78b4eda dbe5e9c 9f6e37f dbe5e9c 78b4eda dbe5e9c a896d78 dbe5e9c a896d78 dbe5e9c a896d78 dbe5e9c e84de77 dbe5e9c a896d78 dbe5e9c a896d78 dbe5e9c a896d78 dbe5e9c e84de77 dbe5e9c a896d78 78b4eda dbe5e9c a896d78 dbe5e9c a896d78 9f6e37f dbe5e9c e84de77 dbe5e9c 78b4eda e84de77 78b4eda e84de77 78b4eda e84de77 dbe5e9c b31a381 dbe5e9c 78b4eda dbe5e9c 48378a2 dbe5e9c 6227d2d |
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 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
from flask import Flask, request, jsonify, render_template, send_file
import pandas as pd
import numpy as np
import joblib
import sqlite3
import io
from datetime import datetime
import xlsxwriter
from flask_httpauth import HTTPBasicAuth
import os
app = Flask(__name__, template_folder='templates')
app.config['WTF_CSRF_ENABLED'] = False # Disable CSRF for testing
auth = HTTPBasicAuth()
# Global variable to hold the model (lazy-loaded)
model = None
# Admin credentials for report access
users = {
"admin": "your_secure_password" # Replace with a strong password
}
@auth.verify_password
def verify_password(username, password):
if username in users and users[username] == password:
return username
return None
# Initialize SQLite database
def init_db():
db_path = '/tmp/submissions.db'
print(f"Initializing database at {db_path}")
try:
conn = sqlite3.connect(db_path)
c = conn.cursor()
c.execute('''
CREATE TABLE IF NOT EXISTS submissions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp TEXT,
age REAL,
gender TEXT,
ever_married TEXT,
residence_type TEXT,
work_type TEXT,
hypertension INTEGER,
heart_disease INTEGER,
avg_glucose_level REAL,
bmi REAL,
smoking_status TEXT,
probability INTEGER,
risk_level TEXT
)
''')
conn.commit()
print("Database initialized successfully")
except Exception as e:
print(f"Error initializing database: {str(e)}")
finally:
conn.close()
init_db()
@app.route('/')
def home():
print("Serving home page")
return render_template('index.html')
@app.route('/predict', methods=['POST'])
def predict():
global model
print("Received predict request at /predict endpoint")
# Check and resolve model file path
model_path = os.path.join(os.getcwd(), 'stroke_prediction_model.pkl')
print(f"Checking model file at: {model_path}")
if not os.path.exists(model_path):
print(f"Model file not found at {model_path}")
return jsonify({'success': False, 'error': f'Model file not found at {model_path}'}), 500
# Load model if not already loaded
if model is None:
try:
model = joblib.load(model_path)
print("Model loaded successfully")
except Exception as e:
print(f"Error loading model: {str(e)}")
return jsonify({'success': False, 'error': f'Model failed to load: {str(e)}'}), 500
try:
# Parse incoming data
data = request.json
print(f"Received JSON data: {data}")
if not data or 'input' not in data:
print("Invalid input data format")
return jsonify({'success': False, 'error': 'Invalid input data'}), 400
input_data = data['input']
print(f"Processed input data: {input_data}")
# Validate and convert input data with fallback
features = {
'age': float(input_data.get('age', 0)) if input_data.get('age') else 0,
'gender': input_data.get('gender', 'Unknown'),
'ever_married': input_data.get('ever_married', 'No'),
'residence_type': input_data.get('residence_type', 'Unknown'),
'work_type': input_data.get('work_type', 'Unknown'),
'hypertension': int(input_data.get('hypertension', 0)) if input_data.get('hypertension') else 0,
'heart_disease': int(input_data.get('heart_disease', 0)) if input_data.get('heart_disease') else 0,
'avg_glucose_level': float(input_data.get('avg_glucose_level', 0)) if input_data.get('avg_glucose_level') else 0,
'bmi': float(input_data.get('bmi', 0)) if input_data.get('bmi') else 0,
'smoking_status': input_data.get('smoking_status', 'Unknown')
}
print(f"Converted features: {features}")
# Create DataFrame and handle categorical variables
df = pd.DataFrame([features])
categorical_cols = ['gender', 'ever_married', 'residence_type', 'work_type', 'smoking_status']
df = pd.get_dummies(df, columns=categorical_cols, drop_first=True)
print(f"DataFrame after get_dummies: {df.columns.tolist()}")
# Define expected columns based on model training
expected_columns = model.feature_names_in_ if hasattr(model, 'feature_names_in_') else [
'age', 'hypertension', 'heart_disease', 'avg_glucose_level', 'bmi',
'gender_Male', 'gender_Other', 'ever_married_Yes', 'residence_type_Urban',
'work_type_Govt_job', 'work_type_Never_worked', 'work_type_Private',
'work_type_Self-employed',
'smoking_status_formerly smoked', 'smoking_status_never smoked',
'smoking_status_smokes'
]
print(f"Expected columns: {expected_columns}")
# Align DataFrame columns
for col in expected_columns:
if col not in df.columns:
df[col] = 0
df = df[expected_columns]
print(f"Aligned DataFrame columns: {df.columns.tolist()}")
# Make prediction
try:
probability = model.predict_proba(df)[0][1] * 100
risk_prediction = "Stroke Risk" if probability > 50 else "No Stroke Risk"
print(f"Prediction result: probability={probability}%, prediction={risk_prediction}")
except Exception as pred_error:
print(f"Prediction error: {str(pred_error)}")
return jsonify({'success': False, 'error': f'Prediction failed: {str(pred_error)}'}), 500
# Determine contributing factors
contributing_factors = {
'glucose': features['avg_glucose_level'] > 140,
'hypertension': features['hypertension'] == 1,
'heartDisease': features['heart_disease'] == 1,
'smoking': features['smoking_status'] in ['smokes', 'formerly smoked']
}
print(f"Contributing factors: {contributing_factors}")
# Attempt to store in database with fallback
try:
conn = sqlite3.connect('/tmp/submissions.db')
c = conn.cursor()
c.execute('''
INSERT INTO submissions (
timestamp, age, gender, ever_married, residence_type, work_type,
hypertension, heart_disease, avg_glucose_level, bmi, smoking_status,
probability, risk_level
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
''', (
datetime.now().isoformat(),
features['age'],
features['gender'],
features['ever_married'],
features['residence_type'],
features['work_type'],
features['hypertension'],
features['heart_disease'],
features['avg_glucose_level'],
features['bmi'],
features['smoking_status'],
round(probability),
risk_prediction
))
conn.commit()
print("Data successfully written to database")
except Exception as db_error:
print(f"Database write error (non-critical): {str(db_error)}")
finally:
conn.close()
# Return prediction result
return jsonify({
'success': True,
'prediction': risk_prediction,
'probability': round(probability),
'contributingFactors': contributing_factors
})
except Exception as e:
print(f"Unexpected error during prediction: {str(e)}")
return jsonify({'success': False, 'error': str(e)}), 500
@app.route('/admin/report', methods=['GET'])
@auth.login_required
def admin_report():
try:
today = datetime.now().strftime('%Y-%m-%d')
conn = sqlite3.connect('/tmp/submissions.db')
df = pd.read_sql_query('SELECT * FROM submissions WHERE DATE(timestamp) = ?', conn, params=[today])
conn.close()
if df.empty:
return "No submissions for today.", 200
df['hypertension'] = df['hypertension'].apply(lambda x: 'Yes' if x == 1 else 'No')
df['heart_disease'] = df['heart_disease'].apply(lambda x: 'Yes' if x == 1 else 'No')
df = df[[
'timestamp', 'age', 'gender', 'ever_married', 'residence_type', 'work_type',
'hypertension', 'heart_disease', 'avg_glucose_level', 'bmi', 'smoking_status',
'probability', 'risk_level'
]]
df.columns = [
'Timestamp', 'Age', 'Gender', 'Ever Married', 'Residence Type', 'Work Type',
'Hypertension', 'Heart Disease', 'Avg Glucose Level', 'BMI', 'Smoking Status',
'Probability (%)', 'Risk Level'
]
output = io.BytesIO()
with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
df.to_excel(writer, sheet_name='Daily Report', index=False)
worksheet = writer.sheets['Daily Report']
for idx, col in enumerate(df.columns):
max_len = max(df[col].astype(str).map(len).max(), len(col)) + 2
worksheet.set_column(idx, idx, max_len)
output.seek(0)
return send_file(
output,
download_name=f'report_{today}.xlsx',
as_attachment=True,
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)
except Exception as e:
print(f"Error generating report: {str(e)}")
return f"Error generating report: {str(e)}", 500 |