A simple SMTP server (in Python)

前端 未结 9 2583
小鲜肉
小鲜肉 2020-12-12 17:09

Could you please suggest a simple SMTP server with the very basic APIs (by very basic I mean, to read, write, delete email), that could be run on a linux box? I just need to

相关标签:
9条回答
  • 2020-12-12 17:45

    These are nice examples for a start.

    smtpd – Sample SMTP Servers

    http://pymotw.com/2/smtpd/index.html

    smtplib – Simple Mail Transfer Protocol client

    http://pymotw.com/2/smtplib/index.html

    0 讨论(0)
  • 2020-12-12 17:46

    Two python smtp servers I've used with success are:

    1. Twisted's Mail - A very flexible mail library for SMTP, IMAP, ...
    2. python-slimta - A complete MTA (smtp relay/forwarding server)

    Twisted's example is shown below

    # Copyright (c) Twisted Matrix Laboratories.
    # See LICENSE for details.
    
    # You can run this module directly with:
    #    twistd -ny emailserver.tac
    
    """
    A toy email server.
    """
    from __future__ import print_function
    
    from zope.interface import implementer
    
    from twisted.internet import defer
    from twisted.mail import smtp
    from twisted.mail.imap4 import LOGINCredentials, PLAINCredentials
    
    from twisted.cred.checkers import InMemoryUsernamePasswordDatabaseDontUse
    from twisted.cred.portal import IRealm
    from twisted.cred.portal import Portal
    
    
    
    @implementer(smtp.IMessageDelivery)
    class ConsoleMessageDelivery:
        def receivedHeader(self, helo, origin, recipients):
            return "Received: ConsoleMessageDelivery"
    
    
        def validateFrom(self, helo, origin):
            # All addresses are accepted
            return origin
    
    
        def validateTo(self, user):
            # Only messages directed to the "console" user are accepted.
            if user.dest.local == "console":
                return lambda: ConsoleMessage()
            raise smtp.SMTPBadRcpt(user)
    
    
    
    @implementer(smtp.IMessage)
    class ConsoleMessage:
        def __init__(self):
            self.lines = []
    
    
        def lineReceived(self, line):
            self.lines.append(line)
    
    
        def eomReceived(self):
            print("New message received:")
            print("\n".join(self.lines))
            self.lines = None
            return defer.succeed(None)
    
    
        def connectionLost(self):
            # There was an error, throw away the stored lines
            self.lines = None
    
    
    
    class ConsoleSMTPFactory(smtp.SMTPFactory):
        protocol = smtp.ESMTP
    
        def __init__(self, *a, **kw):
            smtp.SMTPFactory.__init__(self, *a, **kw)
            self.delivery = ConsoleMessageDelivery()
    
    
        def buildProtocol(self, addr):
            p = smtp.SMTPFactory.buildProtocol(self, addr)
            p.delivery = self.delivery
            p.challengers = {"LOGIN": LOGINCredentials, "PLAIN": PLAINCredentials}
            return p
    
    
    
    @implementer(IRealm)
    class SimpleRealm:
        def requestAvatar(self, avatarId, mind, *interfaces):
            if smtp.IMessageDelivery in interfaces:
                return smtp.IMessageDelivery, ConsoleMessageDelivery(), lambda: None
            raise NotImplementedError()
    
    
    
    def main():
        from twisted.application import internet
        from twisted.application import service    
    
        portal = Portal(SimpleRealm())
        checker = InMemoryUsernamePasswordDatabaseDontUse()
        checker.addUser("guest", "password")
        portal.registerChecker(checker)
    
        a = service.Application("Console SMTP Server")
        internet.TCPServer(2500, ConsoleSMTPFactory(portal)).setServiceParent(a)
    
        return a
    
    application = main()
    
    0 讨论(0)
  • 2020-12-12 17:50

    Take a look at this SMTP sink server:

    from __future__ import print_function
    from datetime import datetime
    import asyncore
    from smtpd import SMTPServer
    
    class EmlServer(SMTPServer):
        no = 0
        def process_message(self, peer, mailfrom, rcpttos, data):
            filename = '%s-%d.eml' % (datetime.now().strftime('%Y%m%d%H%M%S'),
                    self.no)
            f = open(filename, 'w')
            f.write(data)
            f.close
            print('%s saved.' % filename)
            self.no += 1
    
    
    def run():
        # start the smtp server on localhost:1025
        foo = EmlServer(('localhost', 1025), None)
        try:
            asyncore.loop()
        except KeyboardInterrupt:
            pass
    
    
    if __name__ == '__main__':
        run()
    

    It uses smtpd.SMTPServer to dump emails to files.

    0 讨论(0)
  • 2020-12-12 17:50

    A more modern approach is to use the aiosmtpd library (documentation available here).

    You can find a good example here: https://aiosmtpd.readthedocs.io/en/latest/aiosmtpd/docs/controller.html.

    0 讨论(0)
  • 2020-12-12 17:53

    There is Python SMTP server.

    This module offers several classes to implement SMTP servers. One is a generic do-nothing implementation, which can be overridden, while the other two offer specific mail-sending strategies.

    0 讨论(0)
  • 2020-12-12 17:55

    If you want to quickly test Django's send_mail with hasen's answer above:

    # Skip lines 3 and 4 if not using virtualenv.
    # At command prompt
    
    mkdir django1
    cd django1
    virtualenv venv
    source venv/bin/activate
    pip install django==1.11
    django-admin startproject django1 .
    
    # run the Django shell
    
    python manage.py shell
    
    # paste into shell following:
    
    from django.core.mail import send_mail
    
    send_mail(
        'Subject here',
        'Here is the message.',
        'from@example.com',
        ['to@example.com'],
        fail_silently=False,
    )
    # This should write an email like the following:
    
    Content-Type: text/plain; charset="utf-8"
    MIME-Version: 1.0
    Content-Transfer-Encoding: 7bit
    Subject: Subject here
    From: from@example.com
    To: to@example.com
    Date: Wed, 02 May 2018 02:12:09 -0000
    Message-ID: <20180502021209.32641.51865@i1022>
    
    Here is the message.
    

    Not necessary to have valid values in send_mail function. Above values will work just fine with hasen's example.

    0 讨论(0)
提交回复
热议问题