Public Access
feat: wire SendGridEmailBackend with from_email/reply_to settings
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,12 +8,14 @@ intentionally left to be wired in R3-C.
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Optional, Protocol
|
||||
|
||||
from sendgrid import SendGridAPIClient
|
||||
from sendgrid.helpers.mail import Mail, ReplyTo
|
||||
|
||||
from app.config import settings
|
||||
|
||||
|
||||
@@ -66,11 +68,10 @@ class ConsoleEmailBackend:
|
||||
|
||||
|
||||
class SendGridEmailBackend:
|
||||
"""Stub. Wire in R3-C (real SendGrid client + sandbox mode + retries).
|
||||
|
||||
Deliberately raises so a misconfigured prod env fails loudly instead of
|
||||
silently dropping mail.
|
||||
"""
|
||||
def __init__(self) -> None:
|
||||
self._client = SendGridAPIClient(settings.SENDGRID_API_KEY)
|
||||
self._from_email = settings.SENDGRID_FROM_EMAIL
|
||||
self._reply_to = settings.SENDGRID_REPLY_TO
|
||||
|
||||
def send(
|
||||
self,
|
||||
@@ -78,8 +79,20 @@ class SendGridEmailBackend:
|
||||
subject: str,
|
||||
html: str,
|
||||
text: Optional[str] = None,
|
||||
) -> None: # pragma: no cover - stub
|
||||
raise NotImplementedError("Wire SendGrid in R3-C")
|
||||
) -> None:
|
||||
message = Mail(
|
||||
from_email=self._from_email,
|
||||
to_emails=to,
|
||||
subject=subject,
|
||||
html_content=html,
|
||||
plain_text_content=text,
|
||||
)
|
||||
message.reply_to = ReplyTo(self._reply_to)
|
||||
response = self._client.send(message)
|
||||
if response.status_code >= 400:
|
||||
raise RuntimeError(
|
||||
f"SendGrid error {response.status_code}: {response.body}"
|
||||
)
|
||||
|
||||
|
||||
def get_email_backend() -> EmailBackend:
|
||||
|
||||
Reference in New Issue
Block a user