【问题标题】:Amazon SES SMTP Python UsageAmazon SES SMTP Python 使用
【发布时间】:2012-02-23 14:55:14
【问题描述】:

我正在尝试诊断为什么通过 Amazon SES 发送电子邮件无法通过 python 工作。

以下示例演示了该问题,其中userpass 设置为适当的凭据。

>>> 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

此消息不是特别有用,并且尝试了其他变体,但似乎无法使其正常工作。

我可以使用带有这些设置的雷鸟电子邮件客户端发送电子邮件,所以我的假设是我的任务与 TLS 相关。

【问题讨论】:

    标签: python smtp amazon-web-services amazon-ses


    【解决方案1】:

    我已经确定这个问题是由时间引起的。因为我是从命令行执行该代码,所以服务器会超时。如果我将它放入 python 文件并运行它,它的执行速度足以确保发送消息。

    【讨论】:

      【解决方案2】:

      一个完整的例子:

      import smtplib
      
      user = ''
      pw   = ''
      host = 'email-smtp.us-east-1.amazonaws.com'
      port = 465
      me   = u'me@me.com'
      you  = ('you@you.com',)
      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)
      

      【讨论】:

      • 还有更好的吗?这个必须用你和我两次。
      【解决方案3】:

      我认为 SMTP_SSL 不再适用于 SES。必须使用 starttls()

      smtp = smtplib.SMTP("email-smtp.us-east-1.amazonaws.com")
      smtp.starttls()
      smtp.login(SESSMTPUSERNAME, SESSMTPPASSWORD)
      smtp.sendmail(me, you, msg)
      

      【讨论】:

      • 这是完全错误的。 SMTP_SSL 仍然有效,但需要区别对待。我会在我的答案中显示。
      • 这个答案是 13 岁。很可能 13 年前它是正确的,现在不再正确了。
      【解决方案4】:

      看起来,AWS SES 需要一个包含数据和所有必要信息的完整周期,并在缺少某些内容时关闭连接。

      我刚刚创建了一个基于 the officially AWS SES documentation 的示例,重新格式化以消除一些代码异味并切换到 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 sender@example.com with your "From" address.
      # This address must be verified.
      SENDER = 'sender@example.com'
      SENDERNAME = 'Sender Name'
      
      # Replace recipient@example.com with a "To" address. If your account
      # is still in the sandbox, this address must be verified.
      RECIPIENT = 'recipient@example.com'
      
      # 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)
      

      YouTuber Codegnan created a nice walkthrough 设置 SES 和 IAM 以便能够运行上述代码。

      【讨论】:

        猜你喜欢
        • 2012-06-26
        • 1970-01-01
        • 1970-01-01
        • 2014-05-05
        • 2012-01-21
        • 1970-01-01
        • 2017-08-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多