Spaces:
Sleeping
Sleeping
File size: 9,050 Bytes
0ff7b30 750c75a 0ff7b30 750c75a 0ff7b30 750c75a 3959ff2 45a55f0 750c75a 45a55f0 750c75a 45a55f0 750c75a 3959ff2 750c75a 0ff7b30 750c75a 3959ff2 750c75a 0ff7b30 3959ff2 750c75a 3959ff2 0ff7b30 3959ff2 750c75a 3959ff2 45a55f0 3959ff2 45a55f0 3959ff2 45a55f0 3959ff2 45a55f0 750c75a 3959ff2 45a55f0 3959ff2 750c75a 3959ff2 750c75a 45a55f0 3959ff2 750c75a 3959ff2 750c75a 45a55f0 3959ff2 45a55f0 3959ff2 45a55f0 3959ff2 45a55f0 750c75a 0ff7b30 45a55f0 3959ff2 45a55f0 3959ff2 0ff7b30 3959ff2 45a55f0 3959ff2 750c75a 3959ff2 45a55f0 3959ff2 45a55f0 3959ff2 45a55f0 3959ff2 45a55f0 3959ff2 0ff7b30 3959ff2 750c75a 3959ff2 750c75a 0ff7b30 750c75a 0ff7b30 |
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 |
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 # Not used in simplified version
# from email import encoders # Not used in simplified version
import base64
import os
import socket
import traceback
# <<<--- FLASK APP INITIALIZATION MUST BE HERE (TOP LEVEL) --->>>
app = Flask(__name__)
CORS(app)
# <<<--------------------------------------------------------->>>
# Environment variables will be set as Secrets in Hugging Face Space settings
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")
SMTP_CONNECTION_TIMEOUT = 30
SMTP_COMMAND_TIMEOUT = 30
@app.route('/send-report-via-email', methods=['POST']) # This decorator now correctly sees 'app'
def handle_send_email():
request_id = base64.b64encode(os.urandom(6)).decode('utf-8')
print(f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - Received request at /send-report-via-email")
if not all([SMTP_SERVER_HOST, SMTP_SERVER_PORT, SMTP_SENDER_EMAIL, SMTP_SENDER_PASSWORD]):
error_msg = "EMAIL_SENDER_API (HF) [{request_id}]: ERROR - SMTP environment variables (Secrets) 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 = f"EMAIL_SENDER_API (HF) [{request_id}]: ERROR - Invalid SMTP_SERVER_PORT: '{SMTP_SERVER_PORT}'."
print(error_msg)
return jsonify({"status": "error", "message": "Invalid email server port configured on the API."}), 500
data = request.json
if not data:
print(f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - 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') # Not using these in simplified test
# pdf_filename = data.get('pdf_filename') # Not using these in simplified test
print(f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - Attempting to send to: {recipient_email}")
if not recipient_email:
print(f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - Missing recipient_email in JSON payload.")
return jsonify({"status": "error", "message": "Missing required data: recipient_email."}), 400
try:
# Create a simple plain text message
simple_msg = MIMEMultipart()
simple_msg['From'] = SMTP_SENDER_EMAIL
simple_msg['To'] = recipient_email
simple_msg['Subject'] = "EPIC-AMP - Simple Connectivity Test"
simple_body = f"Hello {recipient_email},\n\nThis is a simple plain text email to test SMTP connectivity from the EPIC-AMP Hugging Face Space.\n\nIf you receive this, basic SMTP connection, authentication, and sending are working.\n\nRegards,\nThe EPIC-AMP Test System"
simple_msg.attach(MIMEText(simple_body, 'plain'))
print(f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - Preparing to connect to SMTP server {SMTP_SERVER_HOST}:{SMTP_PORT_INT} with timeout {SMTP_CONNECTION_TIMEOUT}s")
server = None
try:
if SMTP_PORT_INT == 465: # SSL
print(f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - Using SMTP_SSL for port 465.")
server = smtplib.SMTP_SSL(SMTP_SERVER_HOST, SMTP_PORT_INT, timeout=SMTP_CONNECTION_TIMEOUT)
else: # Standard port, try STARTTLS (e.g., for 587)
print(f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - Using standard SMTP for port {SMTP_PORT_INT}.")
server = smtplib.SMTP(SMTP_SERVER_HOST, SMTP_PORT_INT, timeout=SMTP_CONNECTION_TIMEOUT)
server.set_debuglevel(1)
print(f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - Connected. Sending EHLO/HELO...")
server.ehlo()
if SMTP_PORT_INT == 587:
print(f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - Port is 587, attempting STARTTLS...")
server.starttls()
print(f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - STARTTLS successful. Re-sending EHLO...")
server.ehlo()
print(f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - Attempting login with user: {SMTP_SENDER_EMAIL}...")
server.login(SMTP_SENDER_EMAIL, SMTP_SENDER_PASSWORD)
print(f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - Login successful. Sending mail to {recipient_email}...")
server.sendmail(SMTP_SENDER_EMAIL, recipient_email, simple_msg.as_string())
print(f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - Mail sent successfully.")
finally:
if server:
try:
print(f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - Quitting SMTP server connection.")
server.quit()
except Exception as e_quit:
print(f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - Error during server.quit(): {e_quit}")
success_msg = f"SIMPLE TEST: Email successfully sent to {recipient_email}."
print(f"EMAIL_SENDER_API (HF) [{request_id}]: {success_msg}")
return jsonify({"status": "success", "message": success_msg}), 200
# Keep all the specific exception handling blocks
except smtplib.SMTPConnectError as e:
error_msg = f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - SMTP Connect Error. {e}"
print(error_msg); traceback.print_exc()
return jsonify({"status": "error", "message": f"SIMPLIFIED TEST - Could not connect: {e.strerror if hasattr(e, 'strerror') else e}"}), 503
except smtplib.SMTPHeloError as e:
error_msg = f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - SMTP Helo/Ehlo Error. {e}"
print(error_msg); traceback.print_exc()
return jsonify({"status": "error", "message": "SIMPLIFIED TEST - Server HELO/EHLO error."}), 502
except smtplib.SMTPAuthenticationError as e:
error_msg = f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - SMTP Authentication Error. {e}"
print(error_msg); traceback.print_exc()
return jsonify({"status": "error", "message": "SIMPLIFIED TEST - Email server authentication failed."}), 500
except socket.timeout as e:
error_msg = f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - Socket Timeout. {e}"
print(error_msg); traceback.print_exc()
return jsonify({"status": "error", "message": "SIMPLIFIED TEST - Connection timed out."}), 504
except socket.gaierror as e:
error_msg = f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - Address-related error. {e}"
print(error_msg); traceback.print_exc()
return jsonify({"status": "error", "message": "SIMPLIFIED TEST - Could not resolve hostname."}), 503
except OSError as e:
if e.errno == 101:
error_msg = f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - OSError [Errno 101] Network is unreachable. {e}"
print(error_msg); traceback.print_exc()
return jsonify({"status": "error", "message": "SIMPLIFIED TEST - Network is unreachable from API server."}), 503
else:
error_msg = f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - An OS error occurred: {e}"
print(error_msg); traceback.print_exc()
return jsonify({"status": "error", "message": f"SIMPLIFIED TEST - OS Error: {type(e).__name__}"}), 500
except Exception as e:
error_msg = f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - An unexpected error: {e}"
print(error_msg)
traceback.print_exc()
return jsonify({"status": "error", "message": f"SIMPLIFIED TEST - Unexpected API error: {type(e).__name__}"}), 500
# The if __name__ == '__main__': block for local testing:
# On Hugging Face Spaces with Gunicorn, Gunicorn directly imports and runs the 'app' object,
# so this block isn't strictly executed by Gunicorn.
# It's useful if you want to run this script directly with `python email_sender_api.py` for local testing.
# if __name__ == '__main__':
# # For local testing, set your ENV VARS in this terminal session before running
# api_port = int(os.environ.get("PORT", 5002)) # Default to 5002 for local test
# print(f"Starting Email Sender API Service locally on port {api_port}...")
# # ... (rest of the local startup print messages and app.run) ...
# app.run(host='0.0.0.0', port=api_port, debug=True) |