[Tutor] sending email via SMTP: code review requested

Brian van den Broek brian.van.den.broek at gmail.com
Mon May 5 01:00:24 CEST 2014


Hi all,

I am playing with the smtp and email modules from the standard library
of Python 2.7.3 (I also want it to run on 2.6.6). I've not found the
going easy; the SMTP and RFC 2822 standards are not ones I have worked
with before. I have something that works, but I am not confident I am
doing the right thing. For that matter, I am not very confident that I
am not doing the wrong thing.

I would very much appreciate some more experienced eyes on the code below.
In addition to any outright errors concerning interaction with an SMTP
server and constructing a MIME message, I would of course also welcome
style comments. (Preemptively, I will note it isn't obvious I ought to
have gone OOP with this.)

I should also mention that I am writing this code as part of some
tools to send myself and others reminder emails, the tools to be run
from a cron job. I am storing an actual email account password in
plaintext in my code. But, the account in question is one established
just for the purpose of the reminder project and similar projects; it
is not an account which houses my plans for world domination or the
like. That said, I have removed the account name and password string
below; it will thus require some adjustments to run for testing.

And, as I side note, could anyone explain why changing a first world
of a body line 'From' to '>From' is the preferred standard? I
understand what the problem is that is being solved, but as most email
clients interpret a leading '>' as an indication of quoting, I would
have thought ' From' or something like '-From' would have been better.
If I have my own code deal with the problem in one of these ways, will
I be breaking anything?

Anyway, thanks and best,

Brian vdB

import smtplib

class SMTPSender(object):
    def __init__(self, server, port, sender, password, messages):
        self.server = server
        self.port = port
        self.sender = sender
        self.password = password
        self.messages = messages

        self._connect()
        try:
            self._send()
        finally:
            self._logout()

    def _connect(self):
        self.session = smtplib.SMTP(server, port)
        self.session.ehlo()
        self.session.starttls()
        self.session.ehlo
        self.session.login(sender, password)

    def _send(self):
        for message in self.messages:
            to_addresses = message["To"].split(",")
            self.session.sendmail(sender, to_addresses, message.as_string())

    def _logout(self):
        self.session.quit()

if __name__ == "__main__":
    server = "smtp.gmail.com"
    port = 587
    sender = "myfunnyhandle at gmail.com"
    password = "mysecret"

    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart

    # Quick and dirty test message
    msg = MIMEMultipart("alternative")
    msg["Subject"] = "SMTP Test MIMEText plain"
    msg["From"] = sender # Setting to anything but sender gets removed by gmail.
    msg["To"] = "someone at example.com, someoneelse at example.com"
    msg["Reply-to"] = "answerhere at example.com"
    body = "\n\n".join(["Test msg MIME Text",
       "From is a problem when occuring as the first word of a line."])
    msg.attach(MIMEText(body, "plain"))

    sender = SMTPSender(server, port, sender, password, [msg,])


More information about the Tutor mailing list