86 lines
2.7 KiB
Python
86 lines
2.7 KiB
Python
|
|
"""Email provider interfaces and factory."""
|
||
|
|
import logging
|
||
|
|
import os
|
||
|
|
from abc import ABC, abstractmethod
|
||
|
|
from dataclasses import dataclass
|
||
|
|
from typing import Optional
|
||
|
|
|
||
|
|
logger = logging.getLogger(__name__)
|
||
|
|
|
||
|
|
|
||
|
|
@dataclass
|
||
|
|
class EmailMessage:
|
||
|
|
"""Email message data structure."""
|
||
|
|
to: str
|
||
|
|
subject: str
|
||
|
|
body: str
|
||
|
|
html_body: Optional[str] = None
|
||
|
|
from_address: Optional[str] = None
|
||
|
|
|
||
|
|
|
||
|
|
class EmailProvider(ABC):
|
||
|
|
"""Abstract base class for email providers."""
|
||
|
|
|
||
|
|
@abstractmethod
|
||
|
|
def send(self, message: EmailMessage) -> bool:
|
||
|
|
"""
|
||
|
|
Send an email message.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
message: EmailMessage instance containing email details
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
bool: True if email was sent successfully, False otherwise
|
||
|
|
"""
|
||
|
|
pass
|
||
|
|
|
||
|
|
|
||
|
|
class NoOpEmailProvider(EmailProvider):
|
||
|
|
"""No-op email provider that logs and returns False."""
|
||
|
|
|
||
|
|
def send(self, message: EmailMessage) -> bool:
|
||
|
|
"""Log that emails are disabled and return False."""
|
||
|
|
logger.info(f"Email disabled - would send to={message.to} subject={message.subject}")
|
||
|
|
return False
|
||
|
|
|
||
|
|
|
||
|
|
class EmailProviderFactory:
|
||
|
|
"""Factory for creating email provider instances."""
|
||
|
|
|
||
|
|
@staticmethod
|
||
|
|
def get_provider() -> EmailProvider:
|
||
|
|
"""
|
||
|
|
Create an email provider based on EMAIL_PROVIDER config.
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
EmailProvider: An instance of the appropriate email provider
|
||
|
|
"""
|
||
|
|
provider_name = os.getenv("EMAIL_PROVIDER", "smtp").lower()
|
||
|
|
|
||
|
|
if provider_name == "smtp":
|
||
|
|
try:
|
||
|
|
from gatehouse_app.services.providers.smtp_provider import SmtpEmailProvider
|
||
|
|
return SmtpEmailProvider()
|
||
|
|
except ImportError:
|
||
|
|
logger.warning("SMTP provider not implemented, using no-op provider")
|
||
|
|
return NoOpEmailProvider()
|
||
|
|
|
||
|
|
if provider_name == "mailgun":
|
||
|
|
try:
|
||
|
|
from gatehouse_app.services.providers.mailgun_provider import MailgunEmailProvider
|
||
|
|
return MailgunEmailProvider()
|
||
|
|
except ImportError:
|
||
|
|
logger.warning("Mailgun provider not implemented, using no-op provider")
|
||
|
|
return NoOpEmailProvider()
|
||
|
|
|
||
|
|
if provider_name == "sendgrid":
|
||
|
|
try:
|
||
|
|
from gatehouse_app.services.providers.sendgrid_provider import SendGridEmailProvider
|
||
|
|
return SendGridEmailProvider()
|
||
|
|
except ImportError:
|
||
|
|
logger.warning("SendGrid provider not implemented, using no-op provider")
|
||
|
|
return NoOpEmailProvider()
|
||
|
|
|
||
|
|
logger.error(f"Invalid EMAIL_PROVIDER value: {provider_name}, defaulting to no-op provider")
|
||
|
|
return NoOpEmailProvider()
|