Step 1: Install aiosmtpd library
pip install aiosmtpd
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.")
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'.")
Instructions:
Save the new server script as
aioserver.py.Save the client script as
client_script.py.Run the server in one terminal:
python aioserver.pyRun 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())
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!")
- 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
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)
Nazanin joon you’re absolutely killing it with this fake SMTP server! 🔥❤️ So proud of my genius friend! 🥹✨️