Email Agent ========== The EmailAgent class is the main component of pymailai that handles email processing and AI-powered responses. .. autoclass:: pymailai.agent.EmailAgent :members: :special-members: __aenter__, __aexit__ :show-inheritance: The EmailAgent can work with either an EmailConfig for IMAP/SMTP or a BaseEmailClient for custom implementations: Example with EmailConfig: .. code-block:: python from pymailai import EmailAgent, EmailConfig # Configure IMAP/SMTP config = EmailConfig( imap_server="imap.gmail.com", smtp_server="smtp.gmail.com", email="your-email@gmail.com", password="your-password" ) # Create agent with config agent = EmailAgent(config, message_handler=handler) Example with Gmail API: .. code-block:: python from pymailai import EmailAgent from pymailai.gmail import ServiceAccountCredentials from pymailai.gmail_client import GmailClient # Set up service account creds = ServiceAccountCredentials( credentials_path="credentials.json", delegated_email="user@yourdomain.com", scopes=["https://www.googleapis.com/auth/gmail.modify"] ) # Create Gmail client client = GmailClient(creds.get_gmail_service()) # Create agent with client agent = EmailAgent(client, message_handler=handler) Example with custom client: .. code-block:: python from pymailai import EmailAgent from pymailai.base_client import BaseEmailClient class MyCustomClient(BaseEmailClient): async def connect(self) -> None: # Connect to service pass async def disconnect(self) -> None: # Disconnect from service pass async def fetch_new_messages(self) -> AsyncGenerator[EmailData, None]: # Fetch new messages pass async def send_message(self, message: EmailData) -> None: # Send a message pass async def mark_as_read(self, message_id: str) -> None: # Mark message as read pass # Create agent with custom client agent = EmailAgent(MyCustomClient(), message_handler=handler) Type Definitions -------------- .. py:data:: pymailai.agent.MessageHandler :type: Callable[[EmailData], Coroutine[Any, Any, Optional[EmailData]]] Type alias for message handler functions that process incoming emails. The handler should be an async function that takes an :class:`EmailData` object and returns an optional response :class:`EmailData`. Example handler: .. code-block:: python async def echo_handler(message: EmailData) -> Optional[EmailData]: """Echo back any received email.""" return EmailData( message_id="", # Will be generated by email service subject=f"Re: {message.subject}", from_address="", # Will be set by email service to_addresses=[message.from_address], cc_addresses=[], body_text=f"Received: {message.body_text}", body_html=f"

Received:

{message.body_html}
", timestamp=datetime.now(), in_reply_to=message.message_id ) Client Architecture ---------------- The EmailAgent supports different email clients through a common interface: 1. BaseEmailClient - Abstract base class defining the email client interface - Methods for connecting, sending, receiving, and managing emails - Used by all concrete client implementations 2. EmailClient - Standard IMAP/SMTP implementation - Works with any email service supporting these protocols - Configured through EmailConfig 3. GmailClient - Direct Gmail API implementation - Supports service account authentication - Better performance and reliability for Gmail 4. Custom Clients - Implement BaseEmailClient for custom email services - Full control over email operations - Can integrate with any email API or protocol