epic-amp-email-sender / email_sender_api.py
nonzeroexit's picture
Update email_sender_api.py
1a54e21 verified
from flask import Flask, request, jsonify
from flask_cors import CORS
import base64
import os
import traceback
# For SendGrid
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import (Mail, Attachment, FileContent, FileName, FileType, Disposition)
app = Flask(__name__)
CORS(app)
# Environment variable for the Email API Key (set as a Secret in HF Space)
SENDGRID_API_KEY = os.environ.get("SENDGRID_API_KEY")
# Your sender email address - should be verified with SendGrid for best results
SENDER_EMAIL_ADDRESS = os.environ.get("SENDER_EMAIL_ADDRESS") # e.g., [email protected] or a domain email
@app.route('/send-report-via-email', methods=['POST'])
def handle_send_email_http_api():
request_id = base64.b64encode(os.urandom(6)).decode('utf-8')
print(f"EMAIL_SENDER_API (HTTP - SendGrid) [{request_id}]: Received request")
if not SENDGRID_API_KEY:
error_msg = f"EMAIL_SENDER_API (HTTP - SendGrid) [{request_id}]: ERROR - SENDGRID_API_KEY (Secret) not set."
print(error_msg)
return jsonify({"status": "error", "message": "Email API key configuration incomplete."}), 500
if not SENDER_EMAIL_ADDRESS:
error_msg = f"EMAIL_SENDER_API (HTTP - SendGrid) [{request_id}]: ERROR - SENDER_EMAIL_ADDRESS (Secret) not set."
print(error_msg)
return jsonify({"status": "error", "message": "Sender email address configuration incomplete."}), 500
data = request.json
if not data:
print(f"EMAIL_SENDER_API (HTTP - SendGrid) [{request_id}]: 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 (HTTP - SendGrid) [{request_id}]: Attempting to send to: {recipient_email}, Filename: {pdf_filename}")
if not all([recipient_email, pdf_base64_data, pdf_filename]):
print(f"EMAIL_SENDER_API (HTTP - SendGrid) [{request_id}]: Missing required data.")
return jsonify({"status": "error", "message": "Missing required data in payload."}), 400
message = Mail(
from_email=SENDER_EMAIL_ADDRESS,
to_emails=recipient_email,
subject=f"EPIC-AMP Analysis Report: {pdf_filename}",
html_content=f"""
<p>Dear User,</p>
<p>Please find your EPIC-AMP analysis report attached.</p>
<p>Filename: {pdf_filename}</p>
<p>This report includes details on your sequence analysis.</p>
<p>Thank you for using EPIC-AMP!</p>
<p>Best regards,<br>The EPIC-AMP Team<br>
Bioinformatics and Computational Biology Unit, Zewail City<br>
For inquiries: [email protected]</p>
"""
)
try:
# The PDF data is already base64 encoded from the frontend
attachment = Attachment()
attachment.file_content = FileContent(pdf_base64_data) # SendGrid library expects base64 string
attachment.file_name = FileName(pdf_filename)
attachment.file_type = FileType('application/pdf')
attachment.disposition = Disposition('attachment')
# attachment.content_id = ContentId('MyId') # Optional
message.attachment = attachment
except Exception as e:
error_msg = f"EMAIL_SENDER_API (HTTP - SendGrid) [{request_id}]: Error preparing attachment: {e}"
print(error_msg); traceback.print_exc()
return jsonify({"status": "error", "message": "Error preparing PDF attachment."}), 500
try:
sg = SendGridAPIClient(SENDGRID_API_KEY)
response = sg.send(message)
print(f"EMAIL_SENDER_API (HTTP - SendGrid) [{request_id}]: SendGrid Response Status Code: {response.status_code}")
# print(f"EMAIL_SENDER_API (HTTP - SendGrid) [{request_id}]: SendGrid Response Body: {response.body}")
# print(f"EMAIL_SENDER_API (HTTP - SendGrid) [{request_id}]: SendGrid Response Headers: {response.headers}")
if 200 <= response.status_code < 300: # Check for successful status codes
success_msg = f"Report successfully sent to {recipient_email} via SendGrid."
print(f"EMAIL_SENDER_API (HTTP - SendGrid) [{request_id}]: {success_msg}")
return jsonify({"status": "success", "message": success_msg}), 200
else:
error_msg = f"EMAIL_SENDER_API (HTTP - SendGrid) [{request_id}]: SendGrid API Error (Status {response.status_code}): {response.body}"
print(error_msg)
return jsonify({"status": "error", "message": f"Email service provider API error (Status {response.status_code})."}), 502 # Bad Gateway / Upstream error
except Exception as e:
error_msg = f"EMAIL_SENDER_API (HTTP - SendGrid) [{request_id}]: An unexpected error occurred while sending email via SendGrid: {e}"
print(error_msg)
traceback.print_exc()
return jsonify({"status": "error", "message": f"An unexpected error occurred on the email API: {type(e).__name__}"}), 500
# if __name__ == '__main__':
# # For local testing, set ENV VARS for SENDGRID_API_KEY and SENDER_EMAIL_ADDRESS
# api_port = int(os.environ.get("PORT", 5003)) # Different port for this version locally
# print(f"Starting HTTP Email Sender API Service (SendGrid) locally on port {api_port}...")
# # ... local startup messages ...
# app.run(host='0.0.0.0', port=api_port, debug=True)