RespireX-Prototype / api /email_utils.py
CineDev's picture
All files added
718f018
import os
import base64
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import (
Mail, Attachment, FileContent, FileName, FileType, Disposition
)
from django.conf import settings
from datetime import datetime
# --- CONFIGURATION ---
# 1. HARDCODE YOUR KEY HERE FOR TESTING (Remove before deploying to GitHub)
SENDGRID_API_KEY = os.environ.get('SENDGRID_API_KEY') # <--- PASTE YOUR KEY HERE inside quotes
SENDER_EMAIL = "gamingyash54@gmail.com" # <--- MUST match the Single Sender you verified
# ---------------------
def send_html_email(subject, recipient_list, html_content, pdf_buffer=None, filename="Report.pdf"):
"""
Sends an email using SendGrid API (Bypasses Gmail SMTP).
"""
# 1. Create the email object
message = Mail(
from_email=SENDER_EMAIL,
to_emails=recipient_list,
subject=subject,
html_content=html_content
)
# 2. Attach the PDF if it exists
if pdf_buffer:
# SendGrid requires the file to be encoded in Base64 string
encoded_file = base64.b64encode(pdf_buffer.getvalue()).decode()
attachment = Attachment(
FileContent(encoded_file),
FileName(filename),
FileType('application/pdf'),
Disposition('attachment')
)
message.attachment = attachment
# 3. Send via API
try:
print(f"πŸš€ Sending email via SendGrid to {recipient_list}...")
sg = SendGridAPIClient(SENDGRID_API_KEY)
response = sg.send(message)
print(f"βœ… SendGrid Status: {response.status_code}")
if response.status_code in [200, 201, 202]:
print("SUCCESS: Email sent!")
else:
print(f"WARNING: Unexpected status code {response.status_code}")
except Exception as e:
print(f"❌ SendGrid Failed: {str(e)}")
if hasattr(e, 'body'):
print(f"Error Body: {e.body}")
raise e # Re-raise to alert the frontend
def get_medical_email_template(patient_name, test_date, risk_level, confidence):
"""
Returns the HTML email body.
"""
# Define colors
if risk_level in ["High", "Medium"]:
color = "#e11d48" # Red
icon = "⚠️"
else:
color = "#059669" # Green
icon = "βœ…"
dashboard_link = "https://respirex.vercel.app" # Change to your Vercel URL later
return f"""
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #eee; border-radius: 8px;">
<div style="background-color: #0f172a; color: white; padding: 20px; text-align: center;">
<h2 style="margin:0;">RespireX Report</h2>
</div>
<div style="padding: 30px;">
<h3>Hello {patient_name},</h3>
<p>Your analysis from {test_date} is complete.</p>
<div style="background: #f8fafc; padding: 15px; border-radius: 6px; margin: 20px 0;">
<p><strong>Result:</strong> <span style="color: {color}; font-weight: bold;">{icon} {risk_level} Risk</span></p>
<p><strong>AI Confidence:</strong> {confidence}%</p>
</div>
<p>Please find the detailed PDF report attached.</p>
<div style="text-align: center; margin-top: 30px;">
<a href="{dashboard_link}" style="background-color: #2563eb; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px; font-weight: bold;">Login to Dashboard</a>
</div>
</div>
</div>
"""
def send_test_result_email(user_email, prediction):
"""
Orchestrates sending the test result email.
Handles both dict (future) and tuple (current ml_engine) formats.
"""
# 1. Extract data safely
if isinstance(prediction, dict):
label = prediction.get('label', 'Analysis Complete')
confidence = prediction.get('confidence', 0)
# Estimate risk if missing
risk_level = "High" if label == "Positive" else "Low"
elif isinstance(prediction, (tuple, list)) and len(prediction) >= 3:
# Handle tuple from ml_engine.py: (result, confidence, risk_level)
label = prediction[0]
confidence = prediction[1]
risk_level = prediction[2]
else:
label = "Unknown"
confidence = 0
risk_level = "Low"
# 2. Prepare Email
subject = f"RespireX Result: {label}"
date_str = datetime.now().strftime("%B %d, %Y")
html_content = get_medical_email_template(
patient_name="Valued Patient",
test_date=date_str,
risk_level=risk_level,
confidence=confidence
)
# 3. Send
send_html_email(subject, [user_email], html_content)