🔍 Code Extractor

class EmailForwardingHandler

Maturity: 50

SMTP message handler class that processes incoming email messages and forwards them using an EmailHandler instance while tracking server statistics.

File:
/tf/active/vicechatdev/email-forwarder/src/forwarder/smtp_server.py
Lines:
24 - 63
Complexity:
moderate

Purpose

EmailForwardingHandler serves as an SMTP protocol handler for the aiosmtpd library. It implements the necessary callback methods (handle_RCPT and handle_DATA) to receive and process incoming SMTP messages. The class maintains server statistics including connection counts and message counts, and delegates actual email processing to an EmailHandler instance. It's designed to be used with aiosmtpd.controller.Controller to create an SMTP server that receives emails and forwards them to configured destinations.

Source Code

class EmailForwardingHandler:
    """Handler for incoming SMTP messages."""
    
    def __init__(self):
        """Initialize the handler."""
        self.email_handler = EmailHandler()
        self.server_stats = {
            'connections': 0,
            'messages_received': 0,
            'start_time': None
        }
        
    async def handle_RCPT(self, server, session, envelope, address, rcpt_options):
        """Handle RCPT TO command."""
        logger.debug(f"RCPT TO: {address}")
        if not envelope.rcpt_tos:
            envelope.rcpt_tos = []
        envelope.rcpt_tos.append(address)
        return '250 OK'
        
    async def handle_DATA(self, server, session, envelope):
        """Handle email message data."""
        try:
            self.server_stats['messages_received'] += 1
            
            logger.info(f"Received email from {envelope.mail_from} to {envelope.rcpt_tos}")
            
            # Process the email in a separate thread to avoid blocking
            success = self.email_handler.process_email(envelope, envelope.content)
            
            if success:
                logger.info("Email forwarded successfully")
                return '250 Message accepted for delivery'
            else:
                logger.error("Failed to forward email")
                return '451 Temporary failure in forwarding'
                
        except Exception as e:
            logger.error(f"Error handling email data: {e}")
            return '451 Temporary failure'

Parameters

Name Type Default Kind
bases - -

Parameter Details

__init__: The constructor takes no parameters. It initializes an EmailHandler instance for processing emails and sets up a server_stats dictionary to track connections, messages received, and start time.

Return Value

Instantiation returns an EmailForwardingHandler object. The handle_RCPT method returns a string SMTP response code ('250 OK'). The handle_DATA method returns string SMTP response codes: '250 Message accepted for delivery' on success, '451 Temporary failure in forwarding' on forwarding failure, or '451 Temporary failure' on exception.

Class Interface

Methods

__init__(self) -> None

Purpose: Initialize the EmailForwardingHandler with an EmailHandler instance and empty server statistics

Returns: None

async handle_RCPT(self, server, session, envelope, address, rcpt_options) -> str

Purpose: Handle the SMTP RCPT TO command by adding recipient addresses to the envelope

Parameters:

  • server: The aiosmtpd server instance
  • session: The SMTP session object containing connection information
  • envelope: The email envelope object that accumulates message metadata
  • address: The recipient email address from the RCPT TO command
  • rcpt_options: Additional RCPT command options from the SMTP protocol

Returns: SMTP response code string '250 OK' indicating successful recipient acceptance

async handle_DATA(self, server, session, envelope) -> str

Purpose: Handle the SMTP DATA command by processing the complete email message and forwarding it

Parameters:

  • server: The aiosmtpd server instance
  • session: The SMTP session object containing connection information
  • envelope: The email envelope object containing mail_from, rcpt_tos, and content (message data)

Returns: SMTP response code string: '250 Message accepted for delivery' on success, '451 Temporary failure in forwarding' if forwarding fails, or '451 Temporary failure' on exception

Attributes

Name Type Description Scope
email_handler EmailHandler Instance of EmailHandler used to process and forward incoming email messages instance
server_stats dict Dictionary tracking server statistics with keys: 'connections' (int), 'messages_received' (int), and 'start_time' (float or None) instance

Dependencies

  • asyncio
  • logging
  • aiosmtpd
  • email
  • typing
  • email_handler
  • config
  • sys
  • os
  • forwarder
  • signal

Required Imports

import asyncio
import logging
from aiosmtpd.controller import Controller
from email.message import EmailMessage
from typing import Optional
from email_handler import EmailHandler
from config import settings
import sys
import os
from forwarder.email_handler import EmailHandler
import signal

Usage Example

import asyncio
import logging
from aiosmtpd.controller import Controller
from email_handler import EmailHandler
from config import settings

# Setup logging
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)

# Instantiate the handler
handler = EmailForwardingHandler()

# Initialize server stats
handler.server_stats['start_time'] = asyncio.get_event_loop().time()

# Use with aiosmtpd Controller
controller = Controller(handler, hostname='localhost', port=8025)
controller.start()

# The handler will now process incoming SMTP messages
# handle_RCPT is called for each recipient
# handle_DATA is called when message data is received

# Access statistics
print(f"Messages received: {handler.server_stats['messages_received']}")
print(f"Connections: {handler.server_stats['connections']}")

# Stop the controller when done
controller.stop()

Best Practices

  • This class is designed to be used with aiosmtpd.controller.Controller as the handler parameter
  • The server_stats['start_time'] should be set after instantiation to track server uptime
  • Methods handle_RCPT and handle_DATA are async and should not be called directly; they are invoked by the aiosmtpd framework
  • The class maintains state through server_stats, so a single instance should be used per SMTP server
  • Error handling returns temporary failure codes (451) to allow clients to retry
  • The email_handler.process_email call is synchronous and may block; consider running in executor for production use
  • Ensure logger is configured at module level before instantiating this class
  • The envelope object is provided by aiosmtpd and contains mail_from, rcpt_tos, and content attributes
  • Server statistics are incremented automatically; access them via the server_stats attribute
  • The class does not implement connection tracking; increment server_stats['connections'] externally if needed

Similar Components

AI-powered semantic similarity - components with related functionality:

  • class EmailHandler 75.8% similar

    EmailHandler is a comprehensive email processing class that parses incoming email data, extracts content and attachments, enforces rate limits, and forwards emails via Office 365 using the O365Client.

    From: /tf/active/vicechatdev/email-forwarder/src/forwarder/email_handler.py
  • class SMTPServer 73.9% similar

    SMTPServer is a class that manages an SMTP server for receiving emails, handling their forwarding, and providing server statistics.

    From: /tf/active/vicechatdev/email-forwarder/src/forwarder/smtp_server.py
  • class TestEmailHandler 59.0% similar

    A unit test class that validates the functionality of the EmailHandler class, specifically testing email forwarding success and failure scenarios using mocked O365Client dependencies.

    From: /tf/active/vicechatdev/email-forwarder/tests/test_email_handler.py
  • function main_v9 56.3% similar

    Asynchronous main entry point function that initializes and runs an email forwarding SMTP server with logging, configuration validation, and graceful shutdown handling.

    From: /tf/active/vicechatdev/email-forwarder/src/main.py
  • class TestSmtpServer 56.2% similar

    A test class for validating the functionality of the SmtpServer class, including server startup, email handling, email forwarding, and error handling for invalid inputs.

    From: /tf/active/vicechatdev/email-forwarder/tests/test_smtp_server.py
← Back to Browse