from flask import Flask, request, jsonify from flask_cors import CORS import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.base import MIMEBase from email import encoders import base64 import os app = Flask(__name__) CORS(app) # Allows requests from your frontend # Environment variables for SMTP configuration (MUST BE SET before running) SMTP_SERVER_HOST = os.environ.get("SMTP_SERVER_HOST") SMTP_SERVER_PORT = os.environ.get("SMTP_SERVER_PORT") SMTP_SENDER_EMAIL = os.environ.get("SMTP_SENDER_EMAIL") SMTP_SENDER_PASSWORD = os.environ.get("SMTP_SENDER_PASSWORD") @app.route('/send-report-via-email', methods=['POST']) # Changed endpoint name for clarity def handle_send_email(): print("EMAIL_SENDER_API: Received request at /send-report-via-email") # Log request if not all([SMTP_SERVER_HOST, SMTP_SERVER_PORT, SMTP_SENDER_EMAIL, SMTP_SENDER_PASSWORD]): error_msg = "EMAIL_SENDER_API: ERROR - SMTP environment variables not fully set." print(error_msg) return jsonify({"status": "error", "message": "Email server configuration incomplete on the API."}), 500 try: SMTP_PORT_INT = int(SMTP_SERVER_PORT) except ValueError: error_msg = "EMAIL_SENDER_API: ERROR - Invalid SMTP_SERVER_PORT configured." print(error_msg) return jsonify({"status": "error", "message": "Invalid email server port configured on the API."}), 500 data = request.json if not data: print("EMAIL_SENDER_API: No JSON data received.") return jsonify({"status": "error", "message": "No data received by email API."}), 400 recipient_email = data.get('recipient_email') pdf_base64_data = data.get('pdf_base64_data') pdf_filename = data.get('pdf_filename') print(f"EMAIL_SENDER_API: Attempting to send to: {recipient_email}, Filename: {pdf_filename}") if not all([recipient_email, pdf_base64_data, pdf_filename]): print("EMAIL_SENDER_API: Missing required data in JSON payload.") return jsonify({"status": "error", "message": "Missing required data: recipient_email, pdf_base64_data, or pdf_filename."}), 400 try: msg = MIMEMultipart() msg['From'] = SMTP_SENDER_EMAIL msg['To'] = recipient_email msg['Subject'] = f"EPIC-AMP Analysis Report: {pdf_filename}" # Updated subject body = f"""Dear User,\n\nPlease find your EPIC-AMP analysis report attached.\n\nFilename: {pdf_filename}\n\nThis report includes details on your sequence analysis.\n\nThank you for using EPIC-AMP!\n\nBest regards,\nThe EPIC-AMP Team\nBioinformatics and Computational Biology Unit, Zewail City\nFor inquiries: epicamp.sup@gmail.com""" msg.attach(MIMEText(body, 'plain')) pdf_data_bytes = base64.b64decode(pdf_base64_data) part = MIMEBase('application', 'octet-stream') part.set_payload(pdf_data_bytes) encoders.encode_base64(part) part.add_header('Content-Disposition', f"attachment; filename=\"{pdf_filename}\"") msg.attach(part) print(f"EMAIL_SENDER_API: Connecting to SMTP server {SMTP_SERVER_HOST}:{SMTP_PORT_INT}") with smtplib.SMTP(SMTP_SERVER_HOST, SMTP_PORT_INT) as server: server.set_debuglevel(1) # More verbose SMTP logs server.ehlo() if SMTP_PORT_INT == 587: # TLS print("EMAIL_SENDER_API: Starting TLS...") server.starttls() server.ehlo() print("EMAIL_SENDER_API: Logging in...") server.login(SMTP_SENDER_EMAIL, SMTP_SENDER_PASSWORD) print("EMAIL_SENDER_API: Sending mail...") server.sendmail(SMTP_SENDER_EMAIL, recipient_email, msg.as_string()) print("EMAIL_SENDER_API: Mail sent.") success_msg = f"Report successfully sent to {recipient_email}." print(f"EMAIL_SENDER_API: {success_msg}") return jsonify({"status": "success", "message": success_msg}), 200 except smtplib.SMTPAuthenticationError as e: error_msg = f"EMAIL_SENDER_API: SMTP Authentication Error - {e}" print(error_msg) return jsonify({"status": "error", "message": "Email server authentication failed on the API."}), 500 except Exception as e: import traceback error_msg = f"EMAIL_SENDER_API: Error sending email to {recipient_email} - {e}" print(error_msg) print(traceback.format_exc()) return jsonify({"status": "error", "message": f"Failed to send email via API: {e}"}), 500 if __name__ == '__main__': # IMPORTANT: Run this on a DIFFERENT port than your main Gradio app (usually 7860) api_port = 5002 # Using port 5002 here for the email API print(f"Starting Email Sender API Service on port {api_port}...") print(f"SMTP Config Loaded: Server={SMTP_SERVER_HOST}, Port={SMTP_SERVER_PORT}, User Email Set={SMTP_SENDER_EMAIL is not None}") if not all([SMTP_SERVER_HOST, SMTP_SERVER_PORT, SMTP_SENDER_EMAIL, SMTP_SENDER_PASSWORD]): print("WARNING: EMAIL_SENDER_API - SMTP environment variables are not fully set. Email sending will likely fail.") app.run(host='0.0.0.0', port=api_port, debug=True) # debug=True for development feedback