-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
404 lines (293 loc) · 13.6 KB
/
app.py
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
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
from flask import Flask, render_template, request, redirect, url_for, flash, jsonify
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
from datetime import datetime
import json
import os
from keras.models import load_model
import pandas as pd
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite3'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
login_manager = LoginManager()
login_manager.login_view = 'login'
login_manager.init_app(app)
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(100), unique=True)
password_hash = db.Column(db.String(100))
is_admin = db.Column(db.Boolean, default=False)
cognitive_tests = db.relationship('CognitiveTestData', backref='user', lazy=True)
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
# Load your trained model (replace 'best_model.h5' with your model's file path)
model_path = os.path.join(os.path.dirname(__file__), 'models', 'tuned_model.h5')
model_pred = load_model(model_path)
import numpy as np
@app.route('/predict', methods=['POST'])
@login_required # Add appropriate authentication/authorization checks
def predict():
if request.method == 'POST':
# Extract data from the request
data = request.get_json()
# Create a DataFrame from the received data
user_input_df = pd.DataFrame(data, index=[0])
# Make predictions on the user input data
predictions_prob = model_pred.predict(user_input_df)
# Assuming the model is for binary classification
probability = predictions_prob[0] # Probability of the positive class
prediction = 1 if probability > 0.5 else 0 # Convert probability to binary prediction
# Convert probability from ndarray to Python list
probability = probability.tolist()
# Return the prediction result and probability as JSON
return jsonify({'prediction': prediction, 'probability': probability})
return jsonify({'error': 'Invalid request method'})
from flask import Flask, request, jsonify, redirect, url_for, flash
from flask_login import login_required, current_user
from keras.models import load_model
from keras.preprocessing import image
import numpy as np
import os
import tempfile
import boto3
from werkzeug.utils import secure_filename
# Assuming you're using Boto3 to access S3
s3 = boto3.client(
's3',
aws_access_key_id=os.getenv('AWS_ACCESS_KEY_ID'),
aws_secret_access_key=os.getenv('AWS_SECRET_ACCESS_KEY')
)
def load_model_from_s3(bucket_name, object_key):
with tempfile.NamedTemporaryFile() as tmp:
s3.download_file(Bucket=bucket_name, Key=object_key, Filename=tmp.name)
model = load_model(tmp.name)
return model
# Usage
bucket_name = 'mrianalysis' # Your bucket name
object_key = 'pre_tuned_mri.h5' # Your object key
model = load_model_from_s3(bucket_name, object_key)
# Setup for the upload folder
UPLOAD_FOLDER = os.path.join(os.path.dirname(__file__), 'uploads')
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'}
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
image_size = (150, 150) # Adjust based on your model's expected input
class_labels = ["No Impairment", "Very Mild Impairment", "Mild Impairment", "Moderate Impairment"]
@app.route('/predict_mri', methods=['GET', 'POST'])
@login_required
def predict_mri():
if request.method == 'POST':
if 'mriImage' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['mriImage']
if file.filename == '':
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(file_path)
# Image preprocessing and prediction
img = image.load_img(file_path, target_size=image_size)
img_array = image.img_to_array(img)
img_array = np.expand_dims(img_array, axis=0) / 255.0
predictions = model.predict(img_array)
predicted_class = class_labels[np.argmax(predictions)]
probability = np.max(predictions) * 100 # Convert to percentage
# Cleanup the uploaded file if necessary
os.remove(file_path)
# Render the template with prediction results
return render_template('admin/mri_analysis.html', predicted_class=predicted_class, probability=f"{probability:.2f}%")
# GET request or initial page load
return render_template('admin/mri_analysis.html')
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
@app.route('/')
def index():
return render_template('index.html')
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
is_admin = 'is_admin' in request.form
existing_user = User.query.filter_by(username=username).first()
if existing_user:
flash('Username already exists.', 'alert') # Use 'alert' for errors or warnings
return redirect(url_for('register'))
new_user = User(username=username, is_admin=is_admin)
new_user.set_password(password)
db.session.add(new_user)
db.session.commit()
flash('Registration successful.', 'success')
flash('An error occurred.', 'error') # Example for an error message
return redirect(url_for('login'))
return render_template('register.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
remember = True if request.form.get('remember') else False
user = User.query.filter_by(username=username).first()
if not user or not user.check_password(password):
flash('Please check your login details and try again.')
return redirect(url_for('login'))
login_user(user, remember=remember)
return redirect(url_for('user_dashboard' if not user.is_admin else 'admin_dashboard'))
return render_template('login.html')
# FOR USER
@app.route('/dashboard/user')
@login_required
def user_dashboard():
return render_template('user/user_dashboard.html') # Updated path
# Define the CognitiveTestData model
class CognitiveTestData(db.Model):
__tablename__ = 'cognitive_test_data'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(100), db.ForeignKey('user.username'), nullable=False)
test_name = db.Column(db.String(255), nullable=False)
test_date = db.Column(db.Date, default=datetime.utcnow, nullable=False)
drawing_data = db.Column(db.JSON, nullable=False)
# FOR USER
# Update the user_reports route to fetch user-specific cognitive test data
@app.route('/user_reports')
@login_required
def user_reports():
cognitive_tests = CognitiveTestData.query.filter_by(username=current_user.username).all()
return render_template('/user/user_reports.html', cognitive_tests=cognitive_tests)
@app.route('/save_cognitive_test', methods=['POST'])
@login_required
def save_cognitive_test():
try:
# Extract data from the request
data = request.get_json()
# Create a new CognitiveTestData entry
new_test = CognitiveTestData(
username=data['user'],
test_name=data['test_name'],
test_date=datetime.strptime(data['date'], "%Y-%m-%d"),
drawing_data=json.dumps(data['drawing_data'])
)
db.session.add(new_test)
db.session.commit()
return jsonify({'message': 'Cognitive test saved successfully'})
except Exception as e:
return jsonify({'error': str(e)})
@app.route('/dashboard/user/settings', methods=['GET', 'POST'])
@login_required
def settings():
if request.method == 'POST':
# Handle form submission to update the user's name and password in the database
new_name = request.form.get('name')
new_password = request.form.get('password')
# Check if the new username is already taken
existing_user = User.query.filter(User.username == new_name).first()
if existing_user and existing_user != current_user:
flash('Username taken. Please choose a different username.', 'danger')
else:
# Update the user's name and password (if provided)
current_user.username = new_name
if new_password:
current_user.set_password(new_password)
db.session.commit()
flash('Settings updated successfully.', 'success')
return render_template('settings.html')
# FOR ADMIN
@app.route('/patients')
def patients():
# Fetch data from the database (e.g., user information)
# You'll need to implement this logic
patients_data = User.query.all() # Fetch all patients from the "user" table
return render_template('admin/patients.html', patients=patients_data)
@app.route('/create_patient', methods=['POST'])
def create_patient():
if request.method == 'POST':
# Handle form submission to create a new patient and insert it into the database
# Retrieve the data from the form
name = request.form.get('name')
# Add more fields as needed
# Create a new user/patient in the "user" table
new_patient = User(username=name, is_admin=False) # Assuming "is_admin" is False for patients
new_patient.set_password('password') # Set a default password for the patient (you should change this)
db.session.add(new_patient)
db.session.commit()
flash('Patient created successfully.', 'success')
return redirect(url_for('patients')) # Redirect to the patients list page
return render_template('admin/patients.html') # Render the patients list page
@app.route('/edit_patient/<int:patient_id>', methods=['GET', 'POST'])
def edit_patient(patient_id):
# Display a form to edit the patient's information and handle form submission
patient = User.query.get(patient_id)
if not patient:
flash('Patient not found.')
return redirect(url_for('patients')) # Redirect to the patients list page if patient not found
if request.method == 'POST':
# Handle form submission to update the patient's information in the database
# Retrieve the data from the form
name = request.form.get('name')
# Add more fields as needed
# Update the patient's information
patient.username = name
# Update other fields as needed
db.session.commit()
flash('Patient updated successfully.')
return render_template('admin/patients.html', patients=User.query.all()) # Render the patients list page with updated data
@app.route('/delete_patient/<int:patient_id>')
def delete_patient(patient_id):
# Handle deletion of a patient from the database based on patient_id
patient = User.query.get(patient_id)
if not patient:
flash('Patient not found.')
else:
db.session.delete(patient)
db.session.commit()
flash('Patient deleted successfully.', 'error')
return redirect(url_for('patients')) # Redirect back to the patients list page
@app.route('/mri_analysis')
def mri_analysis():
# Your logic for MRI analysis goes here
return render_template('admin/mri_analysis.html')
@app.route('/cognitive_test')
def cognitive_test():
# Query the users from the database (replace this with your actual query)
users = User.query.all()
return render_template('admin/cognitive_test.html', users=users)
@app.route('/admin_reports')
@login_required # Ensure that the user is logged in
def admin_reports():
# Check if the user has admin privileges
if not current_user.is_admin:
flash('Access denied. You do not have admin privileges.', 'danger')
return redirect(url_for('index')) # Redirect to the homepage or another page
# Your logic for admin reports goes here
return render_template('admin/admin_reports.html')
@app.route('/dashboard/admin')
@login_required
def admin_dashboard():
if not current_user.is_admin:
return redirect(url_for('user_dashboard'))
return render_template('admin/admin_dashboard.html') # Updated path
@app.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('index'))
with app.app_context():
try:
db.create_all()
print("Database tables created")
except Exception as e:
print("Error creating database tables:", e)
if __name__ == '__main__':
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port)