【问题标题】:Attaching an s3 file to an smtplib lib email using MIMEApplication使用 MIMEApplication 将 s3 文件附加到 smtplib lib 电子邮件
【发布时间】:2016-08-25 18:22:11
【问题描述】:

我有一个 django 应用程序,它想使用 smtplib 和 email.mime 库将文件从 S3 存储桶附加到电子邮件。

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication

# This takes the files and attaches each one within the bucket to the email. The server keeps erroring on the "with open(path,'rb') as fil" .

def attach_files(path_to_aws_bucket,msg,files=[]):

    for f in files or []:
        path = path_to_aws_bucket + f
        with open(path,'rb') as fil:
            msg.attach(MIMEApplication(
                fil.read(),
                Content_Disposition='attachment; filename="{}"' .format(os.path.basename(f)),
                Name=os.path.basename(f)
            ))

    return msg

def build_message(toaddress,fromaddress,subject,body):

    msg = MIMEMultipart('alternative')
    msg['To'] = toaddress
    msg['From'] = fromaddress
    msg['Subject'] = subject
    b = u"{}" .format(body)
    content = MIMEText(b.encode('utf-8') ,'html','UTF-8')

    msg.attach(content)

    return msg


def send_gmail(msg,username,password,fromaddress,toaddress):

    server = smtplib.SMTP('smtp.gmail.com:587')
    server.ehlo()
    server.starttls()
    server.login(username,password)
    server.sendmail(fromaddress, toaddress , msg.as_string())
    server.quit()

Python 无法打开该文件,因为它声称我给它的任何 s3 url 都不是有效目录。我所有的权限都是正确的。我尝试使用 urllib.opener 打开文件并附加它,但它也引发了错误。

不知道从哪里开始,想知道以前是否有人这样做过。谢谢!

【问题讨论】:

  • 您是如何在 django/python 环境中连接到 s3 的?您是否将本地目录映射到 s3 存储桶? python open 函数期望读取本地文件系统,而不是 s3。

标签: python django amazon-s3 mime


【解决方案1】:

您是否考虑过使用 S3 get_object 代替 smtplib?

from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
import boto3

msg = MIMEMultipart()
new_body = "asdf"
text_part = MIMEText(new_body, _subtype="html")
msg.attach(text_part)

filename='abc.pdf'
msg["To"] = "amal@gmail.com"
msg["From"] = "amal@gmail.com"
s3_object = boto3.client('s3', 'us-west-2')
s3_object = s3_object.get_object(Bucket=‘bucket-name’, Key=filename)
body = s3_object['Body'].read()

part = MIMEApplication(body, filename)
part.add_header("Content-Disposition", 'attachment', filename=filename)
msg.attach(part)
ses_aws_client = boto3.client('ses', 'us-west-2')
ses_aws_client.send_raw_email(RawMessage={"Data" : msg.as_bytes()})

【讨论】:

    【解决方案2】:

    使用 urllib 对我有用,看下面,我有这个 Lambda 函数可以用 smtplib 发送电子邮件:

    import smtplib
    from email.mime.application import MIMEApplication
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    from email.header import Header
    from email.utils import formataddr
    import urllib
    # ['subject','from', 'from_name','to','cc','body','smtp_server','smtp_user','smtp_password']
    
    def lambda_handler(event, context):
        msg = MIMEMultipart('alternative')
        msg['Subject'] = event['subject']
        msg['From'] = formataddr((str(Header(event['from_name'], 'utf-8')), event['from']))
        msg['To'] = event['to']
        msg['Cc'] = event['cc'] # this is comma separated field 
    
        # Create the body of the message (a plain-text and an HTML version).
        text = "Look in a browser or on a mobile device this HTML msg"
        html = event['body']
    
        # Record the MIME types of both parts - text/plain and text/html.
        part1 = MIMEText(text, 'plain')
        part2 = MIMEText(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)
    
        # Attach files from S3
        opener = urllib.URLopener()
        myurl = "https://s3.amazonaws.com/bucket_name/file_name.pdf"
        fp = opener.open(myurl)
    
        filename = 'file_name.pdf'
        att = MIMEApplication(fp.read(),_subtype="pdf")
        fp.close()
        att.add_header('Content-Disposition','attachment',filename=filename)
        msg.attach(att)
    
        # Create de SMTP Object to Send
        s = smtplib.SMTP(event['smtp_server'], 587)
        s.login(event['smtp_user'], event['smtp_password'])
        s.sendmail(msg['From'], [msg['To']], msg.as_string())
    
        return True
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-04
      • 2014-06-25
      • 2010-12-07
      • 2017-08-21
      • 2012-12-14
      • 1970-01-01
      • 1970-01-01
      • 2015-02-21
      相关资源
      最近更新 更多