Initial commit: CI Agent competitive-intelligence monitoring app
FastAPI + Celery + Next.js + Postgres/Redis app with company monitoring, source collection, LLM-based change analysis, enrichment, and account security (Turnstile, escalating lockout, email verification).
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
"""SMTP email provider. Points at Mailpit in local dev (see docker-compose.yml)
|
||||
and any real SMTP server in production - same code path either way. Uses
|
||||
stdlib `smtplib` off the event loop via `asyncio.to_thread` rather than
|
||||
adding an async SMTP dependency.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import smtplib
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
|
||||
from app.core.config import Settings
|
||||
from app.core.logging import get_logger
|
||||
from app.notifications.base import DeliveryResult, NotificationMessage
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class SmtpEmailProvider:
|
||||
provider_name = "smtp"
|
||||
|
||||
def __init__(self, settings: Settings) -> None:
|
||||
self._settings = settings
|
||||
|
||||
async def send(self, message: NotificationMessage) -> DeliveryResult:
|
||||
try:
|
||||
await asyncio.to_thread(self._send_sync, message)
|
||||
return DeliveryResult(success=True)
|
||||
except Exception as exc: # pragma: no cover - network/SMTP failure path
|
||||
logger.error("smtp_send_failed", error=str(exc))
|
||||
return DeliveryResult(success=False, error=str(exc))
|
||||
|
||||
def _send_sync(self, message: NotificationMessage) -> None:
|
||||
mime_message = MIMEMultipart("alternative")
|
||||
mime_message["Subject"] = message.subject
|
||||
mime_message["From"] = self._settings.smtp_from_email
|
||||
mime_message["To"] = message.destination_value
|
||||
mime_message.attach(MIMEText(message.body_text, "plain"))
|
||||
if message.body_html:
|
||||
mime_message.attach(MIMEText(message.body_html, "html"))
|
||||
|
||||
with smtplib.SMTP(self._settings.smtp_host, self._settings.smtp_port, timeout=10) as server:
|
||||
if self._settings.smtp_use_tls:
|
||||
server.starttls()
|
||||
if self._settings.smtp_username:
|
||||
server.login(self._settings.smtp_username, self._settings.smtp_password)
|
||||
server.sendmail(
|
||||
self._settings.smtp_from_email,
|
||||
[message.destination_value],
|
||||
mime_message.as_string(),
|
||||
)
|
||||
Reference in New Issue
Block a user