diff --git a/infrastructure/email/ses_smtp_email_sender.py b/infrastructure/email/ses_smtp_email_sender.py index 9318f100d..ba53d23bc 100644 --- a/infrastructure/email/ses_smtp_email_sender.py +++ b/infrastructure/email/ses_smtp_email_sender.py @@ -11,7 +11,7 @@ from __future__ import annotations import smtplib from email.message import EmailMessage from types import TracebackType -from typing import Any, Callable, Optional, Protocol, Type +from typing import Any, Callable, Optional, Protocol, Type, cast class SmtpTransport(Protocol): @@ -35,7 +35,10 @@ class SmtpTransport(Protocol): def _default_smtp(host: str, port: int) -> SmtpTransport: - return smtplib.SMTP(host, port) + # `smtplib.SMTP` satisfies SmtpTransport structurally; its stdlib stubs + # declare wider signatures (extra optional args, an SMTP-typed context + # manager), so the cast bridges the real transport to the port's surface. + return cast(SmtpTransport, smtplib.SMTP(host, port)) class SesSmtpEmailSender: @@ -57,4 +60,12 @@ class SesSmtpEmailSender: self._smtp_factory = smtp_factory def send(self, *, to: str, subject: str, body: str) -> None: - raise NotImplementedError + message = EmailMessage() + message["From"] = self._from_address + message["To"] = to + message["Subject"] = subject + message.set_content(body) + with self._smtp_factory(self._host, self._port) as smtp: + smtp.starttls() + smtp.login(self._username, self._password) + smtp.send_message(message)