I have a text file to be sent via e-mail. I used the following code to send e-mail through smtplib. This code prints the attachment as e-mail body. Since my text file is bit larger all the content is not visible in mail body? How to display all the content in e-mail body? Any suggestions?
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
msg = MIMEMultipart()
msg['Subject'] = 'ANALYSIS REPORT'
filename = "report.txt"
f = file(filename)
attachment = MIMEText(f.read())
msg.attach(attachment)
smtpObj = smtplib.SMTP('mail.my-domain.com', 25)
smtpObj.sendmail(sender, receivers, msg.as_string())
print "e-mail Successfully Sent!"
I would try to compress the content body, maybe that would get the message size down enough to get the mail through.
Example:
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.mime.application import MIMEApplication
from email.MIMEImage import MIMEImage
import io
import gzip
msg = MIMEMultipart()
msg['Subject'] = 'ANALYSIS REPORT'
msg.attach(MIMEText('report attached'))
filename = "report.txt"
with open(filename, 'rb') as f, io.BytesIO() as b:
g = gzip.GzipFile(mode='wb', fileobj=b)
g.writelines(f)
g.close()
attachment = MIMEApplication(b.getvalue(), 'x-gzip')
attachment['Content-Disposition'] = 'attachment; filename=report.txt.gz'
msg.attach(attachment)
smtpObj = smtplib.SMTP('mail.my-domain.com', 25)
print smtpObj.sendmail(sender, receivers, msg.as_string())
print "e-mail Successfully Sent!"
Related
I'm trying to send example.mp4 file with mail in below codes. Mail send successfully. But when I download the video in related mail. Video is not working after download from mail. But normally video is working successfully.Where is my fault ?
import smtplib
from email import message, encoders
from email.message import EmailMessage
from email.mime.base import MIMEBase
from os.path import basename
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from_addr = 'FROM_MAIL'
to_addr = 'TO_ADDRESS'
subject = 'I just sent this email from Python!'
content = 'Test'
# Initializing video object
video_file = MIMEBase('application', "octet-stream")
# Importing video file
video_file.set_payload(open('example.mp4', "rb").read())
# Encoding video for attaching to the email
encoders.encode_base64(video_file)
# creating EmailMessage object
msg = MIMEMultipart()
# Loading message information ---------------------------------------------
msg['From'] = "person_sending#gmail.com"
msg['To'] = "person_receiving#gmail.com"
msg['Subject'] = 'text for the subject line'
msg.set_content('text that will be in the email body.')
msg.add_attachment(video_file, filename="example.mp4")
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.login(from_addr, 'APP_PASS')
server.send_message(msg, from_addr=from_addr, to_addrs=[to_addr])
Adding this did it for me:
video_file.add_header('Content-Disposition',
'attachment; filename={}'.format("test.mp4"))
I have written a script that sends individual emails to all contacts in an Excel table. The table looks like this:
Names Emails PDF
Name1 Email1#email.com PDF1.pdf
Name2 Email2#email.com PDF2.pdf
The code I have so far is as follows:
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
from string import Template
import pandas as pd
e = pd.read_excel("Contacts.xlsx")
emails = e['Email'].values
PDF = e['PDF'].values
print(emails, PDF)
server = smtplib.SMTP(host='smtp.outlook.com', port=587)
server.starttls()
server.login('sender_email','sender_password')
msg = ("""
Hi there
Test message
Thankyou
""")
subject = "Send emails with attachment"
body = "Subject: {}\n\n{}".format(subject,msg)
for emails in emails:
server.sendmail('sender_email',emails,body)
print("Emails sent successfully")
server.quit()
Question: How can I look up the correct attachment (column 3) for each e-mail address (column 2) and attach it to the email using Python?
I made a little changes , and make you sure the pdf field has the pdf path
Edit:
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
from string import Template
import pandas as pd
#e = pd.read_csv("Contacts.csv")
e = pd.read_excel("Contacts.xlsx")
server = smtplib.SMTP(host='smtp.outlook.com', port=587)
server.starttls()
server.login('yourmail#mail.com','yourpass')
body = ("""
Hi there
Test message
Thankyou
""")
subject = "Send emails with attachment"
fromaddr='yourmail#mail.com'
#body = "Subject: {}\n\n{}".format(subject,msg)
#Emails,PDF
for index, row in e.iterrows():
print (row["Emails"]+row["PDF"])
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['Subject'] = subject
msg.attach(MIMEText(body, 'plain'))
filename = row["PDF"]
toaddr = row["Emails"]
attachment = open(row["PDF"], "rb")
part = MIMEBase('application', 'octet-stream')
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', "attachment; filename= %s" % filename)
msg.attach(part)
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)
#server.sendmail('sender_email',emails,body)
print("Emails sent successfully")
server.quit()
How can I attach some files to an MIME multipart email using Python3?
I want to send some attachments as "downloadable content" to my HTML-mail (with a plain text fallback). Couldn't find anything so far...
Edit: After a few trys I just made it to send my file. Thanks for the tip #tripleee. But unfortunatly my HTML is now sent as plain text...
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.utils import formatdate
from os.path import basename
import smtplib
login = "*********"
password = "*********"
server = "smail.*********:25"
files = ['Anhang/file.png']
# Create the root message and fill in the from, to, and subject headers
msg = MIMEMultipart('related')
msg['From'] = "*********"
msg['To'] = "*********"
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = "*********"
msg['Reply-To'] = "*********"
msg.preamble = 'This is a multi-part message in MIME format.'
# Encapsulate the plain and HTML versions of the message body in an
# 'alternative' part, so message agents can decide which they want to display.
msgAlternative = MIMEMultipart('alternative')
with open('*********.txt', 'r') as plainTXT:
plain = plainTXT.read()
plainTXT.close()
msgAlternative.attach(MIMEText(plain))
with open('*********.html', 'r') as plainHTML:
html = plainHTML.read()
plainHTML.close()
msgAlternative.attach(MIMEText(html))
msg.attach(msgAlternative)
# Image
for f in files or []:
with open(f, "rb") as fp:
part = MIMEImage(
fp.read(),
Name=basename(f)
)
# closing file
part['Content-Disposition'] = 'attachment; filename="%s"' % basename(f)
msg.attach(part)
# create server
server = smtplib.SMTP(server)
server.starttls()
# Login Credentials for sending the mail
server.login(login, password)
# send the message via the server.
server.sendmail(msg['From'], msg['To'], msg.as_string())
server.quit()
print("successfully sent email to %s:" % (msg['To']));
I just had to use MIMEText(html, 'html') for the attaching part of my HTML.
Working code:
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.utils import formatdate
from os.path import basename
import smtplib
login = "YourLogin"
password = "YourPassword"
server = "SMTP-Server:Port"
files = ['files']
# Create the root message and fill in the from, to, and subject headers
msg = MIMEMultipart('related')
msg['From'] = "FromEmail"
msg['To'] = "ToEmail"
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = "EmailSubject"
msg['Reply-To'] = "EmailReply"
msg.preamble = 'This is a multi-part message in MIME format.'
# Encapsulate the plain and HTML versions of the message body in an
# 'alternative' part, so message agents can decide which they want to display.
msgAlternative = MIMEMultipart('alternative')
with open('YourPlaintext.txt', 'r') as plainTXT:
plain = plainTXT.read()
plainTXT.close()
msgAlternative.attach(MIMEText(plain, 'plain'))
with open('YourHTML.html', 'r') as plainHTML:
html = plainHTML.read()
plainHTML.close()
msgAlternative.attach(MIMEText(html, 'html'))
msg.attach(msgAlternative)
# Image
for f in files or []:
with open(f, "rb") as fp:
part = MIMEImage(
fp.read(),
Name=basename(f)
)
# closing file
part['Content-Disposition'] = 'attachment; filename="%s"' % basename(f)
msg.attach(part)
# create server
server = smtplib.SMTP(server)
server.starttls()
# Login Credentials for sending the mail
server.login(login, password)
# send the message via the server.
server.sendmail(msg['From'], msg['To'], msg.as_string())
server.quit()
print("successfully sent email to %s:" % (msg['To']));
Thanks to #tripleee
I have a django application that would like to attach files from an S3 bucket to an email using smtplib and email.mime libraries.
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 can't open the file because it claims that whatever s3 url I give it is not a valid directory. All of my permissions are correct. I tried using urllib.opener to open the file and attach it however it also threw an error.
Not sure where to go from here and was wondering if anyone has done this before. Thanks!
Have you considered using S3 get_object instead of 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()})
Using urllib works for me, look at the following, I have this Lambda function to send emails with 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
I have the following code to send a html file SeleniumTestReport_part1.html in an email in Python.
I want to send more than 1 file in the email. How do can i do this?
The files I want to send are:
SeleniumTestReport_part1.html
SeleniumTestReport_part2.html
SeleniumTestReport_part3.html
My code to send 1 file is:
def send_selenium_report():
fileToSend = r"G:\test_runners\selenium_regression_test_5_1_1\TestReport\SeleniumTestReport_part1.html"
with open(fileToSend, "rt") as f:
text = f.read()
msg = MIMEText(text, "html")
msg['Subject'] = "Selenium ClearCore_Regression_Test_Report_Result"
msg['to'] = "4_server_dev#company.com"
msg['From'] = "system#company.com"
s = smtplib.SMTP()
s.connect(host=SMTP_SERVER)
s.sendmail(msg['From'], msg['To'], msg.as_string())
s.close()
Thanks,
Riaz
If you want to attach files to the email you can use just iterate over files and attach them to the message. You also may want to add some text to the body.
Here is the code:
import smtplib
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
def send_selenium_report():
dir_path = "G:/test_runners/selenium_regression_test_5_1_1/TestReport"
files = ["SeleniumTestReport_part1.html", "SeleniumTestReport_part2.html", "SeleniumTestReport_part3.html"]
msg = MIMEMultipart()
msg['To'] = "4_server_dev#company.com"
msg['From'] = "system#company.com"
msg['Subject'] = "Selenium ClearCore_Regression_Test_Report_Result"
body = MIMEText('Test results attached.', 'html', 'utf-8')
msg.attach(body) # add message body (text or html)
for f in files: # add files to the message
file_path = os.path.join(dir_path, f)
attachment = MIMEApplication(open(file_path, "rb").read(), _subtype="txt")
attachment.add_header('Content-Disposition','attachment', filename=f)
msg.attach(attachment)
s = smtplib.SMTP()
s.connect(host=SMTP_SERVER)
s.sendmail(msg['From'], msg['To'], msg.as_string())
print 'done!'
s.close()
I have implemented this for sending mail from gmail.
import smtplib
from email.mime.text import MIMEText
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email import Encoders
def send_mail_gmail(username,password,toaddrs_list,msg_text,fromaddr=None,subject="Test mail",attachment_path_list=None):
s = smtplib.SMTP('smtp.gmail.com:587')
s.starttls()
s.login(username, password)
#s.set_debuglevel(1)
msg = MIMEMultipart()
sender = fromaddr
recipients = toaddrs_list
msg['Subject'] = subject
if fromaddr is not None:
msg['From'] = sender
msg['To'] = ", ".join(recipients)
if attachment_path_list is not None:
for each_file_path in attachment_path_list:
try:
file_name=each_file_path.split("/")[-1]
part = MIMEBase('application', "octet-stream")
part.set_payload(open(each_file_path, "rb").read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment' ,filename=file_name)
msg.attach(part)
except:
print "could not attache file"
msg.attach(MIMEText(msg_text,'html'))
s.sendmail(sender, recipients, msg.as_string())
You can pass multiple address as element of toaddrs_list to whom you want to send mail and multiple attachments files names with their path in attachment_path_list.