DEV Community

Cover image for Fake SMTP Server
Nazanin Ashrafi
Nazanin Ashrafi

Posted on

Fake SMTP Server

Step 1: Install aiosmtpd library

pip install aiosmtpd
Enter fullscreen mode Exit fullscreen mode

Step 2: The Modern Fake SMTP Server Script (aioserver.py)

import asyncio
from aiosmtpd.controller import Controller
from aiosmtpd.smtp import SMTP

# --- Define the Handler Class ---
# This class defines what happens when the server receives a message.
class DebuggingHandler:
    """
    A modern asynchronous handler that processes and prints received emails.
    """

    async def handle_DATA(self, server, session, envelope):
        """
        Called when the server receives the full email data.
        """
        print("\n=======================================================")
        print("  !!! EMAIL SUCCESSFULLY RECEIVED by FAKE SERVER !!!  ")
        print("=======================================================")
        print(f"  - Client connected from: {session.peer}")
        print(f"  - MAIL FROM: {envelope.mail_from}")
        print(f"  - RCPT TO: {envelope.rcpt_tos}")
        print("--- MESSAGE CONTENT START ---")

        # 'envelope.content' contains the raw email message bytes.
        # We decode it for display.
        print(envelope.content.decode('utf8', errors='replace'))

        print("--- MESSAGE CONTENT END ---")
        print("=======================================================\n")
        # Returning '250 OK' tells the client the message was accepted
        return '250 OK'


# --- Startup Code ---

SERVER_IP = 'localhost'
SERVER_PORT = 1025

async def run_server():
    """
    Starts the asynchronous SMTP server.
    """
    handler = DebuggingHandler()

    # The Controller handles starting and stopping the asyncio event loop.
    controller = Controller(handler, hostname=SERVER_IP, port=SERVER_PORT)

    # Start the server (it runs in the background)
    controller.start()

    print("Starting modern fake SMTP server...")
    print(f"Listening on {SERVER_IP}:{SERVER_PORT}...")
    print("Leave this window open.")
    print("Press Ctrl+C to stop the server and exit.")

    # Keep the main thread alive so the server can run
    while True:
        await asyncio.sleep(1)

if __name__ == "__main__":
    try:
        # Start the asyncio event loop
        asyncio.run(run_server())
    except KeyboardInterrupt:
        print("\nModern fake server stopped.")
Enter fullscreen mode Exit fullscreen mode

Step 3: The Client Script (client_script.py)

import smtplib
from email.mime.text import MIMEText

# Use the same IP and PORT as your fake_server.py
FAKE_SERVER_IP = 'localhost'
FAKE_SERVER_PORT = 1025

# --- Email Details ---
SENDER_EMAIL = 'my_modern_test_address@fake.com'
RECIPIENT_EMAIL = 'recipient_for_learning@test.org'
EMAIL_SUBJECT = 'Modern Test Email from Python smtplib'
EMAIL_BODY = (
    "This message confirms my smtplib script is working against the modern aiosmtpd server.\n"
    "No real email account was used!"
)

# --- Construct the Message ---
# MIMEText is used to properly format the email content and headers.
message = MIMEText(EMAIL_BODY, 'plain', 'utf-8')
message['Subject'] = EMAIL_SUBJECT
message['From'] = SENDER_EMAIL
message['To'] = RECIPIENT_EMAIL


# --- Send the Email using smtplib ---
try:
    print(f"Attempting to connect to modern fake server at {FAKE_SERVER_IP}:{FAKE_SERVER_PORT}...")

    # We use smtplib.SMTP for the simple, local connection
    with smtplib.SMTP(FAKE_SERVER_IP, FAKE_SERVER_PORT) as server:

        # Send the message data
        server.send_message(message)

    print("\n--- SUCCESS ---")
    print("The email was successfully handed off to the modern fake server.")
    print("Check your 'aioserver.py' terminal window for the full message content!")

except Exception as e:
    print("\n--- ERROR ---")
    print(f"An error occurred: {e}")
    print("Ensure 'aioserver.py' is running in a separate terminal window and you ran 'pip install aiosmtpd'.")
Enter fullscreen mode Exit fullscreen mode

Instructions:

  1. Save the new server script as aioserver.py.

  2. Save the client script as client_script.py.

  3. Run the server in one terminal: python aioserver.py

  4. Run the client in a second terminal: python client_script.py


Another script

fake_smtp.py

import asyncio
from aiosmtpd.controller import Controller


class DebugHandler:
    async def handle_DATA(self, server, session, envelope):
        print("\n===== NEW EMAIL RECEIVED =====")
        print(f"From: {envelope.mail_from}")
        print(f"To: {envelope.rcpt_tos}")
        print("----- MESSAGE BODY -----")
        print(envelope.content.decode("utf-8", errors="replace"))
        print("===== END EMAIL =====\n")
        return "250 Message accepted for delivery"


async def main():
    handler = DebugHandler()
    controller = Controller(handler, hostname="localhost", port=1025)
    controller.start()
    print("Fake SMTP server running on localhost:1025")
    try:
        await asyncio.Future()  # Run the event loop forever
    except KeyboardInterrupt:
        controller.stop()


if __name__ == "__main__":
    asyncio.run(main())
Enter fullscreen mode Exit fullscreen mode

test_client.py

import smtplib
from email.mime.text import MIMEText

msg = MIMEText("Hello! This is a test email to the fake SMTP server.")
msg["Subject"] = "Test Email"
msg["From"] = "me@example.com"
msg["To"] = "you@example.com"

with smtplib.SMTP("localhost", 1025) as server:
    server.send_message(msg)

print("Email sent!")
Enter fullscreen mode Exit fullscreen mode

  • Fake server doesn't support it
  • Fake server doesn't require auth
  • localhost:1025
# No TLS, no login (fake server doesn't support it)
# connection.starttls()  <-- remove
# connection.login(user=my_email, password=password)  <-- remove
Enter fullscreen mode Exit fullscreen mode

Note: This is AI generated and its only purpose is to help me and maybe someone else will find this useful as well.

Top comments (1)

Collapse
 
shahrouzlogs profile image
Shahrouz Nikseresht

Nazanin joon you’re absolutely killing it with this fake SMTP server! 🔥❤️ So proud of my genius friend! 🥹✨️