"""Lambda send_email entry point. This lambda sends an email using the AWS SES service. It offers an abstraction over the SES API, allowing for a simpler, pythonic interface. Email attachments are supported. They may be either be provided as Base64 strings, or as valid AWS S3 object URIs (their retrieval is handled automatically under the hood). """ from typing import Optional from pydantic import BaseModel, EmailStr, Field, ValidationError from .email_composer.composer import EmailComposer, BaseAttachment from .aws import send_raw_email from .constants import Response from . import config # noinspection PyDataclass class EmailEvent(BaseModel): """Email event model. This is the data format expected by the lambda function.""" subject: str = Field(..., description="The email subject") text: str = Field(..., description="The email body as plain text") html: Optional[str] = Field( None, description="The email body in HTML format, defaults to text if not provided", ) to: list[EmailStr] = Field(..., description="List of recipient email addresses") cc: Optional[list[EmailStr]] = Field( default_factory=list, description="List of CC email addresses" ) bcc: Optional[list[EmailStr]] = Field( default_factory=list, description="List of BCC email addresses" ) reply_to: Optional[list[EmailStr]] = Field( default_factory=list, description="List of reply-to email addresses" ) attachments: Optional[BaseAttachment] = Field( default_factory=list, description="""Attachment(s) to be included in the email. They must be instances of BaseAttachment subclasses; see implementation for more details. """, ) def handler(event, *_): """Lambda entry point.""" try: email_event = EmailEvent(**event) except ValidationError as e: return {Response.STATUS_CODE: 422, Response.BODY: f"Validation error: {e}"} email_composer = EmailComposer( source=config.EMAIL_FROM, to=email_event.to, subject=email_event.subject, text=email_event.text, html=email_event.html, cc=email_event.cc, bcc=email_event.bcc, reply_to=email_event.reply_to, attachments=email_event.attachments, ) try: response = send_raw_email( destinations=email_composer.recipients, raw_message=email_composer.compose(), ) except Exception as e: return {Response.STATUS_CODE: 500, Response.BODY: f"Error sending email: {e}"} return response