Skip to content

Instantly share code, notes, and snippets.

@bityob
Last active July 18, 2023 08:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bityob/9aecc098b26daf1e21050f43d5435642 to your computer and use it in GitHub Desktop.
Save bityob/9aecc098b26daf1e21050f43d5435642 to your computer and use it in GitHub Desktop.
SMTP Debugging/QA/Testing Server, Simulate easily SMTP errors
from aiosmtpd.controller import Controller
import asyncio
class ExampleHandler:
async def handle_RCPT(self, server, session, envelope, address, rcpt_options):
print(f"handle_RCPT: {address}")
if address.endswith('@error.com'):
user_part = address.split("@")[0]
try:
# Send recipient like this: 550-the-email-account-that-you-tried-to-reach-is-disabled.@error.com and get error:
# SMTPRecipientsRefused
# {'550-the-email-account-that-you-tried-to-reach-is-disabled.@error.com': (550, b'The Email Account That You Tried To Reach Is Disabled.')}
msg = " ".join(user_part.split('-')).title()
print(msg)
return msg
except:
print("Failed to parse error email")
msg = '550 not relaying to that domain'
print(msg)
return msg
envelope.rcpt_tos.append(address)
msg = '250 OK'
print(msg)
return msg
async def handle_DATA(self, server, session, envelope):
print('Message from %s' % envelope.mail_from)
print('Message for %s' % envelope.rcpt_tos)
print('Message data:\n')
for ln in envelope.content.decode('utf8', errors='replace').splitlines():
print(f'> {ln}'.strip())
print()
print('End of message')
return '250 Message accepted for delivery'
controller = Controller(ExampleHandler(), port=1025)
controller.start()
input("Server started. Press Return to quit.\n")
controller.stop()
# Output:
# Server started. Press Return to quit.
# handle_RCPT: 550-the-email-account-that-you-tried-to-reach-is-disabled.@error.com
# 550 The Email Account That You Tried To Reach Is Disabled.
# handle_RCPT: 550-temporary-server-error@error.com
# 550 Temporary Server Error
# handle_RCPT: normal@example.com
# 250 OK
# Message from a@a.com
# Message for ['normal@example.com']
# Message data:
# > From: A <a@a.com>
# > To: B <b@b.com>
# > Subject: SMTP e-mail test
# >
# > Hello World!
# End of message
import smtplib
import time
sender = 'a@a.com'
recipients = [
"550-the-email-account-that-you-tried-to-reach-is-disabled.@error.com",
"550-temporary-server-error@error.com",
"normal@example.com",
]
message = """From: A <a@a.com>
To: B <b@b.com>
Subject: SMTP e-mail test
Hello World!
"""
for r in recipients:
try:
smtp = smtplib.SMTP('localhost', 1025)
smtp.sendmail(sender, [r], message)
print("Successfully sent email")
except smtplib.SMTPException as ex:
print(ex.__class__.__name__, str(ex))
time.sleep(0.1)
# Output:
# SMTPRecipientsRefused {'550-the-email-account-that-you-tried-to-reach-is-disabled.@error.com': (550, b'The Email Account That You Tried To Reach Is Disabled.')}
# SMTPRecipientsRefused {'550-temporary-server-error@error.com': (550, b'Temporary Server Error')}
# Successfully sent email
def text_to_username(text):
return f'550-{"-".join(text.lower().split())}@error.com'
text_to_username("Temporary server error")
# Output:
# '550-temporary-server-error@error.com'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment