Amazon SES SMTP Python Usage
Solution 1
I don't think SMTP_SSL works anymore with SES. One must use starttls()
smtp = smtplib.SMTP("email-smtp.us-east-1.amazonaws.com")
smtp.starttls()
smtp.login(SESSMTPUSERNAME, SESSMTPPASSWORD)
smtp.sendmail(me, you, msg)
Solution 2
A full example:
import smtplib
user = ''
pw = ''
host = 'email-smtp.us-east-1.amazonaws.com'
port = 465
me = u'[email protected]'
you = ('[email protected]',)
body = 'Test'
msg = ("From: %s\r\nTo: %s\r\n\r\n"
% (me, ", ".join(you)))
msg = msg + body
s = smtplib.SMTP_SSL(host, port, 'yourdomain')
s.set_debuglevel(1)
s.login(user, pw)
s.sendmail(me, you, msg)
Solution 3
I have determined this problem to be caused by the timing. Because I was executing that code from the command line, the server would timeout. If I put it into a python file and run it, it executes fast enough to ensure the message is sent.
Solution 4
It looks like, AWS SES expects a full cycle with data and all the necessary information and closes the connection in case something is missing.
I just created an example based on the officially AWS SES documentation, reformatted to remove some code smells and switched to SMTP_SLL:
from email.utils import formataddr
from smtplib import SMTP_SSL, SMTPException
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# Replace [email protected] with your "From" address.
# This address must be verified.
SENDER = '[email protected]'
SENDERNAME = 'Sender Name'
# Replace [email protected] with a "To" address. If your account
# is still in the sandbox, this address must be verified.
RECIPIENT = '[email protected]'
# Replace smtp_username with your Amazon SES SMTP user name.
USERNAME_SMTP = "AWS_SES_SMTP_USER"
# Replace smtp_password with your Amazon SES SMTP password.
PASSWORD_SMTP = "AWS_SES_SMTP_PWD"
# (Optional) the name of a configuration set to use for this message.
# If you comment out this line, you also need to remove or comment out
# the "X-SES-CONFIGURATION-SET:" header below.
# CONFIGURATION_SET = "ConfigSet"
# If you're using Amazon SES in an AWS Region other than US West (Oregon),
# replace email-smtp.us-west-2.amazonaws.com with the Amazon SES SMTP
# endpoint in the appropriate region.
HOST = "email-smtp.us-west-2.amazonaws.com"
PORT = 465
# The subject line of the email.
SUBJECT = 'Amazon SES Test (Python smtplib)'
# The email body for recipients with non-HTML email clients.
BODY_TEXT = ("Amazon SES Test - SSL\r\n"
"This email was sent through the Amazon SES SMTP "
"Interface using the Python smtplib package.")
# The HTML body of the email.
BODY_HTML = """<html>
<head></head>
<body>
<h1>Amazon SES SMTP Email Test - SSL</h1>
<p>This email was sent with Amazon SES using the
<a href='https://www.python.org/'>Python</a>
<a href='https://docs.python.org/3/library/smtplib.html'>
smtplib</a> library.</p>
</body>
</html>"""
# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = SUBJECT
msg['From'] = formataddr((SENDERNAME, SENDER))
msg['To'] = RECIPIENT
# Comment or delete the next line if you are not using a configuration set
# msg.add_header('X-SES-CONFIGURATION-SET',CONFIGURATION_SET)
# Record the MIME types of both parts - text/plain and text/html.
part1 = MIMEText(BODY_TEXT, 'plain')
part2 = MIMEText(BODY_HTML, 'html')
# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
msg.attach(part1)
msg.attach(part2)
# Try to send the message.
try:
with SMTP_SSL(HOST, PORT) as server:
server.login(USERNAME_SMTP, PASSWORD_SMTP)
server.sendmail(SENDER, RECIPIENT, msg.as_string())
server.close()
print("Email sent!")
except SMTPException as e:
print("Error: ", e)
The YouTuber Codegnan created a nice walkthrough to set up SES and IAM to be able to run the code above.
Kevin Dolan
Updated on June 04, 2022Comments
-
Kevin Dolan almost 2 years
I am trying to diagnose why sending email through Amazon SES is not working via python.
The following example demonstrates the problem, where
user
andpass
are set to the appropriate credentials.>>> import smtplib >>> s = smtplib.SMTP_SSL("email-smtp.us-east-1.amazonaws.com", 465) >>> s.login(user, pw) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.6/smtplib.py", line 549, in login self.ehlo_or_helo_if_needed() File "/usr/lib/python2.6/smtplib.py", line 510, in ehlo_or_helo_if_needed (code, resp) = self.helo() File "/usr/lib/python2.6/smtplib.py", line 372, in helo (code,msg)=self.getreply() File "/usr/lib/python2.6/smtplib.py", line 340, in getreply raise SMTPServerDisconnected("Connection unexpectedly closed") smtplib.SMTPServerDisconnected: Connection unexpectedly closed
This message is not particularly useful, and have tried other vraiations, but can't seem to get it to work.
I can send email using my thunderbird email client with these settings, so my assumption is that I am mission something TLS-related.
-
GoYun.Info over 4 yearsIs there a better one? This one has to use you and me twice.
-
andreas over 2 yearsThis is plain wrong. SMTP_SSL is still working, but needs to be treated differently. I will show in my answer.
-
jrwren over 2 yearsThis answer is 13 yrs old. It is quite likely that it was correct 13yrs ago and is not any longer.
-
Berk about 2 yearsHow can we set it up to attach a file to the email? I tried to email from aws with an attached file - but it does not work? Shall I need to change somethings in my aws account for attaching file to email?