48 lines
1.5 KiB
Python
48 lines
1.5 KiB
Python
"""Email the daily report via SMTP (Gmail app password). No-op if EMAIL_* is unconfigured,
|
|
so the pipeline never fails just because email isn't set up.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import smtplib
|
|
import ssl
|
|
from email.message import EmailMessage
|
|
from pathlib import Path
|
|
|
|
from loguru import logger
|
|
|
|
from config.settings import get_settings
|
|
|
|
|
|
def send_daily(trade_date: str, pdf_path: Path | None, summary: str = "") -> bool:
|
|
s = get_settings()
|
|
if not (s.email_app_password and s.email_to and s.email_from):
|
|
logger.info("email skipped (EMAIL_TO/FROM/APP_PASSWORD not set in .env)")
|
|
return False
|
|
|
|
msg = EmailMessage()
|
|
msg["Subject"] = f"Trading Agent — Daily Report {trade_date}"
|
|
msg["From"] = s.email_from
|
|
msg["To"] = s.email_to
|
|
msg.set_content(summary or f"Daily research + execution report for {trade_date} attached.")
|
|
|
|
if pdf_path and Path(pdf_path).exists():
|
|
msg.add_attachment(
|
|
Path(pdf_path).read_bytes(),
|
|
maintype="application",
|
|
subtype="pdf",
|
|
filename=Path(pdf_path).name,
|
|
)
|
|
|
|
try:
|
|
ctx = ssl.create_default_context()
|
|
with smtplib.SMTP(s.smtp_host, s.smtp_port, timeout=30) as server:
|
|
server.starttls(context=ctx)
|
|
server.login(s.email_from, s.email_app_password)
|
|
server.send_message(msg)
|
|
logger.info("emailed daily report to {}", s.email_to)
|
|
return True
|
|
except Exception as e:
|
|
logger.warning("email failed: {}", e)
|
|
return False
|