epic-amp-email-sender / email_sender_api.py
nonzeroexit's picture
Update email_sender_api.py
3959ff2 verified
raw
history blame
8.22 kB
# ... (keep existing imports and Flask app setup, SMTP config variables) ...
SMTP_CONNECTION_TIMEOUT = 30 # Increased slightly for good measure
SMTP_COMMAND_TIMEOUT = 30 # Increased slightly for good measure
@app.route('/send-report-via-email', methods=['POST']) # Keep the same endpoint
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]):
# ... (same error handling for missing SMTP config as before) ...
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:
# ... (same error handling for invalid port) ...
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:
# ... (same error handling for no 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')
# We are not using pdf_base64_data or pdf_filename in this simplified test
print(f"EMAIL_SENDER_API (HF) [{request_id}]: SIMPLIFIED TEST - Attempting to send to: {recipient_email}")
if not recipient_email: # Only recipient email is strictly needed for this test
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() # Still use MIMEMultipart for proper headers
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 as they were
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: # Keep other specific exceptions
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
# ... include ALL other smtplib exceptions and socket exceptions from the previous version of email_sender_api.py ...
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: # Specifically catch OSError for "Network is unreachable"
if e.errno == 101: # Network is unreachable
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 can remain commented out or as is
# if __name__ == '__main__':
# # ... local testing startup ...