Yash goyal commited on
Commit
1559a37
·
verified ·
1 Parent(s): eedbea1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -37
app.py CHANGED
@@ -3,6 +3,7 @@ os.environ['MPLCONFIGDIR'] = '/tmp/matplotlib'
3
  from flask import Flask, render_template, request, redirect, url_for, session, send_file, jsonify
4
  from flask_sqlalchemy import SQLAlchemy
5
  from flask_migrate import Migrate
 
6
  import tensorflow as tf
7
  import numpy as np
8
  from PIL import Image
@@ -151,6 +152,25 @@ def preprocess_image(image_bytes):
151
  image_array = tf.keras.utils.img_to_array(image)
152
  return np.expand_dims(image_array, axis=0) / 255.0
153
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  def generate_pdf(report, filepath):
155
  c = canvas.Canvas(filepath, pagesize=A4)
156
  width, height = A4
@@ -236,6 +256,7 @@ def form():
236
  def training_plot():
237
  return send_file(PLOT_PATH, mimetype="image/png") if os.path.exists(PLOT_PATH) else ("", 404)
238
 
 
239
  @app.route("/uploads/<filename>")
240
  def uploaded_file(filename):
241
  upload_folder = "/tmp/uploads"
@@ -244,23 +265,18 @@ def uploaded_file(filename):
244
  @app.route("/predict", methods=["POST"])
245
  def predict():
246
  try:
247
- if model_load_error or not model:
248
- raise ValueError(f"Model not loaded: {model_load_error}")
249
- if "image" not in request.files or not request.files["image"].filename:
250
- raise ValueError("No image uploaded.")
251
-
252
  image_file = request.files["image"]
253
  image_bytes = image_file.read()
254
 
255
- # Preprocess and Predict
256
  img_array = preprocess_image(image_bytes)
257
  prediction = model.predict(img_array)[0]
258
  predicted_index = int(np.argmax(prediction))
259
  confidence = float(prediction[predicted_index])
260
  label = label_map.get(predicted_index, "Unknown") if confidence >= CONFIDENCE_THRESHOLD else "Low confidence"
261
- msg = "This image is not confidently recognized. Please upload a clearer image." if confidence < CONFIDENCE_THRESHOLD else ""
262
 
263
- # Database operations
264
  email = request.form.get("email")
265
  user = User.query.filter_by(email=email).first()
266
  if not user:
@@ -268,6 +284,7 @@ def predict():
268
  db.session.add(user)
269
  db.session.commit()
270
 
 
271
  timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
272
  image_filename = f"scan_{user.id}_{timestamp}.jpg"
273
  upload_folder = "/tmp/uploads"
@@ -276,6 +293,7 @@ def predict():
276
  with open(image_path, "wb") as f:
277
  f.write(image_bytes)
278
 
 
279
  scan = Scan(
280
  user_id=user.id, patient_name=request.form.get("name"),
281
  patient_gender=request.form.get("gender"), patient_age=int(request.form.get("age")),
@@ -284,44 +302,25 @@ def predict():
284
  db.session.add(scan)
285
  db.session.commit()
286
 
287
- # Prepare report for session and email
288
  report = {
289
  "name": request.form.get("name"), "email": email, "gender": request.form.get("gender"),
290
  "age": request.form.get("age"), "prediction": label, "confidence": f"{confidence * 100:.2f}%",
291
- "message": msg, "scan_id": scan.id
 
292
  }
293
 
294
- # Email sending logic
295
- try:
296
- if not app.config['MAIL_USERNAME'] or not app.config['MAIL_PASSWORD']:
297
- raise ValueError("Mail server credentials are not configured.")
298
-
299
- pdf_path = f"/tmp/report_{scan.id}.pdf"
300
- generate_pdf(report, pdf_path)
301
-
302
- email_msg = Message('Your SnapSkin Diagnostic Report', sender=app.config['MAIL_USERNAME'], recipients=[email])
303
- email_msg.body = f"Dear {report['name']},\n\nPlease find your diagnostic report attached.\n\nThank you for using SnapSkin."
304
- with app.open_resource(pdf_path) as fp:
305
- email_msg.attach(f"SnapSkin_Report_{scan.id}.pdf", "application/pdf", fp.read())
306
- mail.send(email_msg)
307
-
308
- os.remove(pdf_path)
309
- report["email_status"] = "Success! The report has been sent to your email."
310
- logger.info(f"Report sent to {email} for scan ID {scan.id}")
311
-
312
- except Exception as e:
313
- logger.error(f"Failed to send email for scan ID {scan.id}: {e}")
314
- report["email_status"] = "Failed to send the report to your email. You can download it directly."
315
 
316
  session["report"] = report
317
  return redirect(url_for("result"))
318
 
319
  except Exception as e:
320
  logger.error(f"Prediction error: {e}")
321
- return render_template(FORM_TEMPLATE, history_plot="/training_plot.png", result={
322
- "prediction": "Error", "confidence": "N/A",
323
- "message": f"An error occurred during prediction: {e}",
324
- "email_status": "N/A"
325
  })
326
 
327
  @app.route("/result")
@@ -329,8 +328,6 @@ def result():
329
  report = session.get("report")
330
  if not report:
331
  return redirect(url_for("form"))
332
- # Change this line to render your result.html page
333
- # The **report unpacks the dictionary into template variables
334
  return render_template("result.html", **report)
335
 
336
  @app.route("/download-report")
 
3
  from flask import Flask, render_template, request, redirect, url_for, session, send_file, jsonify
4
  from flask_sqlalchemy import SQLAlchemy
5
  from flask_migrate import Migrate
6
+ import threading
7
  import tensorflow as tf
8
  import numpy as np
9
  from PIL import Image
 
152
  image_array = tf.keras.utils.img_to_array(image)
153
  return np.expand_dims(image_array, axis=0) / 255.0
154
 
155
+ # NEW: Function to send email in a background thread
156
+ def send_email_async(app_context, report_data):
157
+ with app_context:
158
+ try:
159
+ pdf_path = f"/tmp/report_{report_data['scan_id']}.pdf"
160
+ generate_pdf(report_data, pdf_path)
161
+
162
+ msg = Message('Your SnapSkin Diagnostic Report', sender=app.config['MAIL_USERNAME'], recipients=[report_data['email']])
163
+ msg.body = f"Dear {report_data['name']},\n\nPlease find your diagnostic report attached."
164
+
165
+ with app.open_resource(pdf_path) as fp:
166
+ msg.attach(f"SnapSkin_Report_{report_data['scan_id']}.pdf", "application/pdf", fp.read())
167
+
168
+ mail.send(msg)
169
+ os.remove(pdf_path)
170
+ logger.info(f"Report sent successfully to {report_data['email']}")
171
+ except Exception as e:
172
+ logger.error(f"Failed to send email in background: {e}")
173
+
174
  def generate_pdf(report, filepath):
175
  c = canvas.Canvas(filepath, pagesize=A4)
176
  width, height = A4
 
256
  def training_plot():
257
  return send_file(PLOT_PATH, mimetype="image/png") if os.path.exists(PLOT_PATH) else ("", 404)
258
 
259
+
260
  @app.route("/uploads/<filename>")
261
  def uploaded_file(filename):
262
  upload_folder = "/tmp/uploads"
 
265
  @app.route("/predict", methods=["POST"])
266
  def predict():
267
  try:
 
 
 
 
 
268
  image_file = request.files["image"]
269
  image_bytes = image_file.read()
270
 
271
+ # --- Prediction Logic ---
272
  img_array = preprocess_image(image_bytes)
273
  prediction = model.predict(img_array)[0]
274
  predicted_index = int(np.argmax(prediction))
275
  confidence = float(prediction[predicted_index])
276
  label = label_map.get(predicted_index, "Unknown") if confidence >= CONFIDENCE_THRESHOLD else "Low confidence"
277
+ msg = "This image is not confidently recognized." if confidence < CONFIDENCE_THRESHOLD else ""
278
 
279
+ # --- Database Operations ---
280
  email = request.form.get("email")
281
  user = User.query.filter_by(email=email).first()
282
  if not user:
 
284
  db.session.add(user)
285
  db.session.commit()
286
 
287
+ # --- Save image to /tmp to fix permission error ---
288
  timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
289
  image_filename = f"scan_{user.id}_{timestamp}.jpg"
290
  upload_folder = "/tmp/uploads"
 
293
  with open(image_path, "wb") as f:
294
  f.write(image_bytes)
295
 
296
+ # --- Save Scan to DB ---
297
  scan = Scan(
298
  user_id=user.id, patient_name=request.form.get("name"),
299
  patient_gender=request.form.get("gender"), patient_age=int(request.form.get("age")),
 
302
  db.session.add(scan)
303
  db.session.commit()
304
 
305
+ # --- Prepare Report ---
306
  report = {
307
  "name": request.form.get("name"), "email": email, "gender": request.form.get("gender"),
308
  "age": request.form.get("age"), "prediction": label, "confidence": f"{confidence * 100:.2f}%",
309
+ "message": msg, "scan_id": scan.id,
310
+ "email_status": "Your report will be sent to your email shortly." # Neutral message
311
  }
312
 
313
+ # --- Send email in background to prevent loading freeze ---
314
+ thread = threading.Thread(target=send_email_async, args=(app.app_context(), report))
315
+ thread.start()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
 
317
  session["report"] = report
318
  return redirect(url_for("result"))
319
 
320
  except Exception as e:
321
  logger.error(f"Prediction error: {e}")
322
+ return render_template("form.html", result={
323
+ "prediction": "Error", "message": f"An error occurred: {e}"
 
 
324
  })
325
 
326
  @app.route("/result")
 
328
  report = session.get("report")
329
  if not report:
330
  return redirect(url_for("form"))
 
 
331
  return render_template("result.html", **report)
332
 
333
  @app.route("/download-report")