I'm using flask for deploying website, I've made app.py that uses flask to handle traffic, the traffic is an image that is inserted by the user, the model must take that image which is supposedly an ECG, convert it to numerical format using PlotDigitizer and return a prediction, the function predict() worked perfectly alone, the issue is with the integration, the webpage that is deployed using HTML, CSS, and Javascript appears to flag an error that was coded by me. The error is: Error uploading image: Failed to upload image.
My app.py is:
from flask import Flask, render_template, request, jsonifyimport osimport pandas as pdfrom sklearn.preprocessing import RobustScalerimport numpy as npfrom tensorflow.keras.models import load_modelfrom werkzeug.utils import secure_filenameapp = Flask(__name__)model = Nonedef load_model_on_startup(): # Use a raw string for the Windows path model_path = r"C:\Users\USER\Desktop\h5\ecggrad (1).h5" return load_model(model_path)@app.before_first_requestdef initialize_model(): global model model = load_model_on_startup()@app.route('/')def index(): return render_template('index.html') # Make sure 'index.html' exists in the 'templates' directory@app.route('/upload', methods=['POST'])def upload_file(): if 'img' not in request.files: return jsonify({'error': 'No file part'}), 400 file = request.files['img'] if file.filename == '': return jsonify({'error': 'No selected file'}), 400 if file and allowed_file(file.filename): filename = secure_filename(file.filename) file_path = os.path.join('uploads', filename) if not os.path.exists('uploads'): os.makedirs('uploads') file.save(file_path) try: prediction = predict(file_path) os.remove(file_path) # Remove the file after prediction return jsonify({'prediction': prediction}) except Exception as e: return jsonify({'error': str(e)}), 500def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in {'jpg', 'jpeg', 'png', 'bmp'}def predict(image_path): command = f'plotdigitizer "{image_path}" -p 0,0 -p 2,0 -p 0,1 -l 2,29 -l 4,5 -l 22,5' output = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) print("STDOUT:", output.stdout) print("STDERR:", output.stderr) if output.returncode != 0: raise RuntimeError("plotdigitizer failed to run correctly") image_path2 = os.path.splitext(image_path)[0] +".jpg.traj.csv" if not os.path.exists(image_path2): raise FileNotFoundError(f"Expected file not found: {image_path2}") df = pd.read_csv(image_path2, sep='', header=None) scaler = RobustScaler() df = pd.DataFrame(scaler.fit_transform(df), columns=df.columns) df = df.iloc[:, 1:2] df = df.head(10).T.reset_index(drop=True) df.columns = ['0_pre-RR', '0_pPeak', '0_rPeak', '0_sPeak', '0_qt_interval','1_pre-RR', '1_qPeak', '1_qt_interval', '1_qrs_morph0', '1_qrs_morph1'] df = df.apply(pd.to_numeric, errors='coerce') # Make predictions using the loaded model predictions = model.predict(df.values) # Parse predictions predicted_label_index = np.argmax(predictions) class_labels = ["N", "VEB", "SVEB", "Fusion"] predicted_label = class_labels[predicted_label_index] print(f"The predicted label is: {predicted_label}")if __name__ == '__main__': app.run(host='127.0.0.1', port=5000, debug=True)My HTML, CSS, Javascript code is:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Arrhythmia Detector</title><style> body { background-image: url("https://thumbs.dreamstime.com/b/hd-electrocardiogram-ecg-paper-background-square-160410630.jpg"); background-position: bottom; background-size: 99% auto; font-family: Arial, sans-serif; margin: 0; } h1 { text-align: center; text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); } #container { text-align: center; margin-top: 50px; position: relative; } .navigation-button, #choose-image-label, #file-info, #img, #privacy-box, #about-box, #contact-box { color: black; } /* Red text style */ .red-text { color: red; font-weight: bold; /* Optional: Make the red words bold */ } .navigation-button { font-size: 24px; padding: 10px 20px; text-decoration: none; background-color: transparent; border: none; margin: 0 10px; font-weight: bold; display: inline-block; } .navigation-button:hover { color: #ff0000; /* Change color on hover */ transition: color 0.5s ease; /* Smooth transition */ } #choose-image-label:hover { color: black; /* Change color to black on hover */ cursor: pointer; transition: color 0.3s ease; /* Smooth transition */ } #choose-image-label { color: red; display: block; text-align: center; font-size: 24px; margin-bottom: 10px; cursor: pointer; } #file-info { color: black; font-size: 20px; margin-bottom: 10px; } #privacy-button, #about-button, #contact-button { position: relative; top: 10px; } #image-container { margin: 20px auto; text-align: center; } #img { display: none; } #logo { position: absolute; top: 17px; right: 18px; width: 180px; height: 190px; } /* About and Privacy Box Styles */ .info-box { display: none; background-color: rgba(255, 255, 255, 0.9); padding: 20px; border-radius: 10px; position: absolute; top: 80px; left: 50%; transform: translateX(-50%); width: 300px; text-align: center; box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); color: black !important; /* Change text color to black with !important */ } .close-info-box { position: absolute; top: 10px; right: 10px; cursor: pointer; font-size: 20px; color: black; }</style></head><body><div id="container"><a href="#" id="privacy-button" class="navigation-button">Privacy</a><a href="#" id="about-button" class="navigation-button">About</a><a href="#" id="contact-button" class="navigation-button">Contact</a><h1>Welcome to the Arrhythmia Detector <span style="color: red;">iHeartDetect</span></h1><img id="logo" src="https://erc-jordan.org/wp-content/uploads/2023/02/PSUT.png" alt="PSUT Logo"><div id="image-container"><img src="https://www.emkatech.com/wp-content/uploads/2021/11/Arrhythmia.png" alt="Image Description" width="100" height="100"><br><br><p id="file-info">The image must be in JPEG, JPG, PNG, or BMP format.</p><form id="upload-form" enctype="multipart/form-data"><label for="img" id="choose-image-label" onclick="triggerPostman()">Choose Image</label><input type="file" id="img" name="img" accept=".jpeg, .jpg, .png, .bmp" style="display: none;"></form></div><!-- About Box --><div id="about-box" class="info-box"><span class="close-info-box" onclick="toggleInfoBox('about-box')">×</span><p>iHeartDetect is a machine learning-based model designed to analyze, detect, and report arrhythmia in ECG tests. The model is based on <span class="red-text">AWS</span>, providing excellent scalability, reliability, and response time. It was trained on the <span class="red-text">MIT-BIH</span> dataset and uses the <span class="red-text">CNN-GRU</span> hybrid network, achieving excellent performance in all metrics.</p></div><!-- Privacy Box --><div id="privacy-box" class="info-box"><span class="close-info-box" onclick="toggleInfoBox('privacy-box')">×</span><p>We collect ECG data solely for the purpose of providing you with accurate and personalized health insights, implementing stringent security measures to protect your information from unauthorized access. The <span class="red-text">ECG</span> data is handled with utmost care and privacy.</p></div><!-- Contact Box --><div id="contact-box" class="info-box"><span class="close-info-box" onclick="toggleInfoBox('contact-box')">×</span><p>This webpage connected to the deep learning model delivered by AWS services has been fully deployed by <span class="red-text">PSUT</span> students. You can contact us at: naserusa200199@gmail.com</p></div></div><script> document.getElementById('privacy-button').addEventListener('click', function () { toggleInfoBox('privacy-box'); }); document.getElementById('about-button').addEventListener('click', function () { toggleInfoBox('about-box'); }); document.getElementById('contact-button').addEventListener('click', function () { toggleInfoBox('contact-box'); }); document.getElementById('choose-image-label').addEventListener('click', function () { document.getElementById('img').click(); }); document.getElementById('img').addEventListener('change', function () { uploadImage(); // Call the uploadImage function when an image is selected }); async function uploadImage() { const fileInput = document.getElementById('img'); const file = fileInput.files[0]; if (!file) { alert('Please choose a file.'); return; } const formData = new FormData(); formData.append('img', file); try { const response = await fetch('http://127.0.0.1:5000/upload', { method: 'POST', body: formData, }); if (!response.ok) { throw new Error('Failed to upload image.'); } const result = await response.json(); // Update the UI with the result alert('Prediction Result: '+ result.prediction); } catch (error) { console.error('Error uploading image:', error); alert('Error uploading image: '+ error.message); } } function toggleInfoBox(boxId) { var infoBoxes = document.querySelectorAll('.info-box'); infoBoxes.forEach(function (box) { if (box.id === boxId) { // Toggle the selected box box.style.display = (box.style.display === 'none' || box.style.display === '') ? 'block' : 'none'; } else { // Hide other boxes box.style.display = 'none'; } }); }</script></body></html>I've tried looking for the distribution of the directory as it appears to be correct, I've tried changing the host, nothing appears to help. The error is flagged by the code:
try { const response = await fetch('http://127.0.0.1:5000/upload', { method: 'POST', body: formData, }); if (!response.ok) { throw new Error('Failed to upload image.'); } const result = await response.json();