File size: 5,473 Bytes
0ff7b30
 
 
 
 
750c75a
1a54e21
 
 
 
0ff7b30
 
 
1a54e21
 
 
 
0ff7b30
1a54e21
 
3959ff2
1a54e21
45a55f0
1a54e21
 
750c75a
1a54e21
750c75a
1a54e21
 
750c75a
1a54e21
750c75a
 
 
1a54e21
750c75a
 
 
1a54e21
 
 
750c75a
1a54e21
 
 
750c75a
1a54e21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
750c75a
3959ff2
1a54e21
 
 
 
 
 
 
 
 
 
 
 
45a55f0
1a54e21
 
 
 
 
 
750c75a
1a54e21
 
 
 
3959ff2
1a54e21
 
 
 
 
 
750c75a
3959ff2
1a54e21
750c75a
 
1a54e21
 
 
 
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
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)