pythonaiosmtpd

Basic aiosmtpd SMTP server example


How do I convert the following basic SMTP server that uses smtpd to one that uses aiosmtpd instead?

import smtpd

class CustomSMTPServer(smtpd.SMTPServer):

    def process_message(self, peer, mailfrom, rcpttos, data):
        myqueue.queue.put(data)

self.server = CustomSMTPServer(('127.0.0.1', 10025), None)

Solution

  • To translate your CustomSMTPServer into something that uses aiosmtpd, you have to define a handler class with a handle_DATA() method that does the same thing as your process_message() method:

    import aiosmtpd.controller
    
    class CustomSMTPHandler:
        async def handle_DATA(self, server, session, envelope):
            myqueue.queue.put(envelope.content)
            return '250 OK'
    
    handler = CustomSMTPHandler()
    self.server = aiosmtpd.controller.Controller(handler)
    self.server.start()
    input("Server started. Press Return to quit.")
    self.server.stop()
    

    Note that handle_DATA() returns "250 OK" which tells the SMTP client that the message was received and handled successfully. Unlike smtpd, with aiosmtpd you are required to return an SMTP response code in handle_DATA().

    Note that handle_DATA() must be a coroutine function, that is, defined using async def. If you need compatibility with Python 3.4, use an @asyncio.coroutine decorator on handle_DATA() instead.

    Also note that self.server.start() runs the SMTP server in a separate thread, unlike asyncore.loop() which takes over the current thread.

    If you need access to peer, mailfrom or rcpttos, they are available as session.peer, envelope.mail_from and envelope.rcpt_tos, respectively.