Migrating from smtpd to aiosmtpd
aiosmtpd is designed to make it easy to migrate an existing application based
on smtpd
to aiosmtpd.
Consider the following subclass of smtpd.SMTPServer
:
import smtpd
import asyncore
class CustomSMTPServer(smtpd.SMTPServer):
def process_message(self, peer, mail_from, rcpt_tos, data):
# Process message data...
if error_occurred:
return '500 Could not process your message'
if __name__ == '__main__':
server = CustomSMTPServer(('127.0.0.1', 10025), None)
# Run the event loop in the current thread.
asyncore.loop()
To switch this application to using aiosmtpd
, implement a handler with
the handle_DATA()
method:
import asyncio
from aiosmtpd.controller import Controller
class CustomHandler:
async def handle_DATA(self, server, session, envelope):
peer = session.peer
mail_from = envelope.mail_from
rcpt_tos = envelope.rcpt_tos
data = envelope.content # type: bytes
# Process message data...
if error_occurred:
return '500 Could not process your message'
return '250 OK'
if __name__ == '__main__':
handler = CustomHandler()
controller = Controller(handler, hostname='127.0.0.1', port=10025)
# Run the event loop in a separate thread.
controller.start()
# Wait for the user to press Return.
input('SMTP server running. Press Return to stop server and exit.')
controller.stop()
Important differences to note:
Unlike
process_message()
in smtpd,handle_DATA()
must return an SMTP response code for the sender such as"250 OK"
.handle_DATA()
must be a coroutine function, which means it must be declared withasync def
.Controller.start()
runs the SMTP server in a separate thread and can be stopped again by callingController.stop()