web-dev-qa-db-fra.com

Un simple serveur SMTP (en Python)

Pourriez-vous s'il vous plaît suggérer un serveur SMTP simple avec les API très basiques (je veux dire très basique, lire, écrire, supprimer des emails), qui pourrait être exécuté sur une boîte Linux? envoyer un courriel au format XML et le transférer vers un autre ordinateur.

19
fixxxer

Jetez un oeil à ce serveur évier SMTP :

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():
    foo = EmlServer(('localhost', 25), None)
    try:
        asyncore.loop()
    except KeyboardInterrupt:
        pass


if __== '__main__':
    run()

Il utilise smtpd.SMTPServer pour dump des emails en fichiers.

36
hasen

Il y a vraiment 2 choses requises pour envoyer un email:

  • Un serveur SMTP - Il peut s'agir du serveur SMTP Python ou vous pouvez utiliser GMail ou le serveur de votre fournisseur de services Internet. Les chances sont que vous n'avez pas besoin de courir le vôtre.
  • Une bibliothèque SMTP - Quelque chose qui enverra une demande par courrier électronique au serveur SMTP. Python est livré avec une bibliothèque appelée smtplib qui peut le faire pour vous. Il existe une foule d'informations sur son utilisation ici: http://docs.python.org/library/smtplib.html

Pour la lecture, il existe deux options selon le serveur à partir duquel vous lisez le courrier électronique.

21
Chris Dail

Deux serveurs smtp python que j'ai utilisés avec succès sont:

  1. Twisted's Mail - Une bibliothèque de courrier très flexible pour SMTP, IMAP, ... 
  2. python-slimta - Un MTA complet (serveur de transfert/relais smtp)

L'exemple de Twisted est présenté ci-dessous

# 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()
4
frmdstryr

Ce sont de bons exemples pour commencer.

smtpd - Exemples de serveurs SMTP

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

smtplib - Client Simple Mail Transfer Protocol

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

2
The Demz

Une approche plus moderne consiste à utiliser la bibliothèque aiosmtpd (documentation disponible ici ).

Vous pouvez trouver un bon exemple ici: https://aiosmtpd.readthedocs.io/en/latest/aiosmtpd/docs/controller.html .

1
Floyd

Il y a serveur SMTP Python .

Ce module propose plusieurs classes pour implémenter des serveurs SMTP. L'un est un implémentation générique ne rien faire, qui peut être remplacée, tandis que le. deux autres proposent des stratégies d’envoi de courrier spécifiques.

1
zoli2k

Pour que le script de Hasen fonctionne dans Python 3, je devais le modifier légèrement:

from datetime import datetime
import asyncore
from smtpd import SMTPServer

class EmlServer(SMTPServer):
    no = 0
    def process_message(self, peer, mailfrom, rcpttos, data, **kwargs):
        filename = '%s-%d.eml' % (datetime.now().strftime('%Y%m%d%H%M%S'),
            self.no)
        print(filename)
        f = open(filename, 'wb')
        f.write(data)
        f.close
        print('%s saved.' % filename)
        self.no += 1

def run():
    EmlServer(('localhost', 25), None)
    try:
        asyncore.loop()
    except KeyboardInterrupt:
        pass

if __== '__main__':
    run()
0
Protector one

Si vous voulez rapidement tester send_mail de Django avec la réponse de hasen ci-dessus:

# 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.',
    '[email protected]',
    ['[email protected]'],
    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: [email protected]
To: [email protected]
Date: Wed, 02 May 2018 02:12:09 -0000
Message-ID: <20180502021209.32641.51865@i1022>

Here is the message.

Il n'est pas nécessaire d'avoir des valeurs valides dans la fonction send_mail. Les valeurs ci-dessus fonctionneront parfaitement avec l'exemple de hasen.

0
small mammal