omaralaa2004 commited on
Commit
48378a2
·
verified ·
1 Parent(s): 957dc78

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +216 -0
app.py ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, jsonify, render_template, send_file
2
+ import pandas as pd
3
+ import numpy as np
4
+ import joblib
5
+ import sqlite3
6
+ import io
7
+ from datetime import datetime
8
+ import xlsxwriter
9
+ from flask_httpauth import HTTPBasicAuth
10
+
11
+ app = Flask(__name__, template_folder='templates')
12
+
13
+ auth = HTTPBasicAuth()
14
+
15
+ # Load the trained model
16
+ try:
17
+ model = joblib.load('stroke_prediction_model.pkl')
18
+ print("Model loaded successfully.")
19
+ except Exception as e:
20
+ print(f"Error loading model: {str(e)}")
21
+ model = None
22
+
23
+ # Admin credentials for report access
24
+ users = {
25
+ "admin": "your_secure_password" # Replace with a strong password
26
+ }
27
+
28
+ @auth.verify_password
29
+ def verify_password(username, password):
30
+ if username in users and users[username] == password:
31
+ return username
32
+ return None
33
+
34
+ # Initialize SQLite database
35
+ def init_db():
36
+ conn = sqlite3.connect('submissions.db')
37
+ c = conn.cursor()
38
+ c.execute('''
39
+ CREATE TABLE IF NOT EXISTS submissions (
40
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
41
+ timestamp TEXT,
42
+ age REAL,
43
+ gender TEXT,
44
+ ever_married TEXT,
45
+ residence_type TEXT,
46
+ work_type TEXT,
47
+ hypertension INTEGER,
48
+ heart_disease INTEGER,
49
+ avg_glucose_level REAL,
50
+ bmi REAL,
51
+ smoking_status TEXT,
52
+ probability INTEGER,
53
+ risk_level TEXT
54
+ )
55
+ ''')
56
+ conn.commit()
57
+ conn.close()
58
+
59
+ init_db()
60
+
61
+ @app.route('/')
62
+ def home():
63
+ return render_template('index.html')
64
+
65
+ @app.route('/predict', methods=['POST'])
66
+ def predict():
67
+ if model is None:
68
+ return jsonify({'success': False, 'error': 'Model failed to load'}), 500
69
+
70
+ try:
71
+ # Get form data
72
+ data = request.json
73
+ if not data or 'input' not in data:
74
+ return jsonify({'success': False, 'error': 'Invalid input data'}), 400
75
+ input_data = data['input']
76
+ print(f"Received input data: {input_data}")
77
+
78
+ # Prepare data for model
79
+ features = {
80
+ 'age': float(input_data.get('age', 0)),
81
+ 'gender': input_data.get('gender', 'Unknown'),
82
+ 'ever_married': input_data.get('ever_married', 'No'),
83
+ 'Residence_type': input_data.get('residence_type', 'Unknown'),
84
+ 'work_type': input_data.get('work_type', 'Unknown'),
85
+ 'hypertension': int(input_data.get('hypertension', 0)),
86
+ 'heart_disease': int(input_data.get('heart_disease', 0)),
87
+ 'avg_glucose_level': float(input_data.get('avg_glucose_level', 0)),
88
+ 'bmi': float(input_data.get('bmi', 0)),
89
+ 'smoking_status': input_data.get('smoking_status', 'Unknown')
90
+ }
91
+ print(f"Processed features: {features}")
92
+
93
+ # Convert to DataFrame
94
+ df = pd.DataFrame([features])
95
+
96
+ # One-hot encode categorical variables
97
+ categorical_cols = ['gender', 'ever_married', 'Residence_type', 'work_type', 'smoking_status']
98
+ df = pd.get_dummies(df, columns=categorical_cols, drop_first=True)
99
+
100
+ # Get expected columns from the model
101
+ expected_columns = model.feature_names_in_ if hasattr(model, 'feature_names_in_') else [
102
+ 'age', 'hypertension', 'heart_disease', 'avg_glucose_level', 'bmi',
103
+ 'gender_Male', 'gender_Other', 'ever_married_Yes', 'Residence_type_Urban',
104
+ 'work_type_Govt_job', 'work_type_Never_worked', 'work_type_Private',
105
+ 'work_type_Self-employed',
106
+ 'smoking_status_formerly smoked', 'smoking_status_never smoked',
107
+ 'smoking_status_smokes'
108
+ ]
109
+ print(f"Expected columns: {expected_columns}")
110
+
111
+ # Align DataFrame with expected columns
112
+ for col in expected_columns:
113
+ if col not in df.columns:
114
+ df[col] = 0
115
+ df = df[expected_columns]
116
+
117
+ # Make prediction
118
+ probability = model.predict_proba(df)[0][1] * 100 # Probability of stroke
119
+ risk_level = 'High' if probability > 50 else 'Moderate' if probability > 25 else 'Low'
120
+
121
+ # Determine contributing factors
122
+ contributing_factors = {
123
+ 'age': features['age'] > 45,
124
+ 'hypertension': features['hypertension'] == 1,
125
+ 'heart_disease': features['heart_disease'] == 1,
126
+ 'glucose': features['avg_glucose_level'] > 140,
127
+ 'smoking': features['smoking_status'] in ['smokes', 'formerly smoked']
128
+ }
129
+
130
+ # Log submission to database
131
+ conn = sqlite3.connect('submissions.db')
132
+ c = conn.cursor()
133
+ c.execute('''
134
+ INSERT INTO submissions (
135
+ timestamp, age, gender, ever_married, residence_type, work_type,
136
+ hypertension, heart_disease, avg_glucose_level, bmi, smoking_status,
137
+ probability, risk_level
138
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
139
+ ''', (
140
+ datetime.now().isoformat(),
141
+ features['age'],
142
+ features['gender'],
143
+ features['ever_married'],
144
+ features['Residence_type'],
145
+ features['work_type'],
146
+ features['hypertension'],
147
+ features['heart_disease'],
148
+ features['avg_glucose_level'],
149
+ features['bmi'],
150
+ features['smoking_status'],
151
+ round(probability),
152
+ risk_level
153
+ ))
154
+ conn.commit()
155
+ conn.close()
156
+
157
+ # Return prediction result
158
+ return jsonify({
159
+ 'success': True,
160
+ 'probability': round(probability),
161
+ 'riskLevel': risk_level,
162
+ 'contributingFactors': contributing_factors
163
+ })
164
+ except Exception as e:
165
+ print(f"Error during prediction: {str(e)}")
166
+ return jsonify({'success': False, 'error': str(e)}), 500
167
+
168
+ @app.route('/admin/report', methods=['GET'])
169
+ @auth.login_required
170
+ def admin_report():
171
+ try:
172
+ today = datetime.now().strftime('%Y-%m-%d')
173
+ conn = sqlite3.connect('submissions.db')
174
+ df = pd.read_sql_query('SELECT * FROM submissions WHERE DATE(timestamp) = ?', conn, params=[today])
175
+ conn.close()
176
+
177
+ if df.empty:
178
+ return "No submissions for today.", 200
179
+
180
+ # Prepare data for Excel
181
+ df['hypertension'] = df['hypertension'].apply(lambda x: 'Yes' if x == 1 else 'No')
182
+ df['heart_disease'] = df['heart_disease'].apply(lambda x: 'Yes' if x == 1 else 'No')
183
+ df = df[[
184
+ 'timestamp', 'age', 'gender', 'ever_married', 'residence_type', 'work_type',
185
+ 'hypertension', 'heart_disease', 'avg_glucose_level', 'bmi', 'smoking_status',
186
+ 'probability', 'risk_level'
187
+ ]]
188
+ df.columns = [
189
+ 'Timestamp', 'Age', 'Gender', 'Ever Married', 'Residence Type', 'Work Type',
190
+ 'Hypertension', 'Heart Disease', 'Avg Glucose Level', 'BMI', 'Smoking Status',
191
+ 'Probability (%)', 'Risk Level'
192
+ ]
193
+
194
+ # Create Excel file in memory
195
+ output = io.BytesIO()
196
+ with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
197
+ df.to_excel(writer, sheet_name='Daily Report', index=False)
198
+ worksheet = writer.sheets['Daily Report']
199
+ for idx, col in enumerate(df.columns):
200
+ max_len = max(df[col].astype(str).map(len).max(), len(col)) + 2
201
+ worksheet.set_column(idx, idx, max_len)
202
+ output.seek(0)
203
+
204
+ # Send file
205
+ return send_file(
206
+ output,
207
+ download_name=f'report_{today}.xlsx',
208
+ as_attachment=True,
209
+ mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
210
+ )
211
+ except Exception as e:
212
+ print(f"Error generating report: {str(e)}")
213
+ return f"Error generating report: {str(e)}", 500
214
+
215
+ if __name__ == '__main__':
216
+ app.run(debug=True, host='0.0.0.0', port=5000)