使用 MIMEApplication 将 s3 文件附加到 smtplib lib 电子邮件
Posted
技术标签:
【中文标题】使用 MIMEApplication 将 s3 文件附加到 smtplib lib 电子邮件【英文标题】:Attaching an s3 file to an smtplib lib email using MIMEApplication 【发布时间】: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。 【参考方案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
【讨论】:
以上是关于使用 MIMEApplication 将 s3 文件附加到 smtplib lib 电子邮件的主要内容,如果未能解决你的问题,请参考以下文章
将多个文件上传到 Terraform 中的多个 S3 存储桶