Ready for first real test
This commit is contained in:
1 parent
acddf9135f
commit
b91c81ebdf
46 files changed
+34903
-26
No files matched your search
@@ -0,0 +1,47 @@
|
||||
"""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
|
||||
Reference in new issue
Block a user