I am trying to create a little script that will email multiple attachments using gmail. The code below sends the email but not the attachments. The intended use is to cron a couple db queries and email the results. There will always be 2 files and the file names will be different each day as the date
for the report is in the file name. Otherwise I would have just used:
part.add_header('Content-Disposition',
'attachment; filename="absolute Path for the file/s"')
Any help greatly appreciated.
import os
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
from email.MIMEBase import MIMEBase
from email import Encoders
#Set up crap for the attachments
files = "/tmp/test/dbfiles"
filenames = [os.path.join(files, f) for f in os.listdir(files)]
#print filenames
#Set up users for email
gmail_user = "[email protected]"
gmail_pwd = "somepasswd"
recipients = ['recipient1','recipient2']
#Create Module
def mail(to, subject, text, attach):
msg = MIMEMultipart()
msg['From'] = gmail_user
msg['To'] = ", ".join(recipients)
msg['Subject'] = subject
msg.attach(MIMEText(text))
mailServer = smtplib.SMTP("smtp.gmail.com", 587)
mailServer.ehlo()
mailServer.starttls()
mailServer.ehlo()
mailServer.login(gmail_user, gmail_pwd)
mailServer.sendmail(gmail_user, to, msg.as_string())
# Should be mailServer.quit(), but that crashes...
mailServer.close()
#get all the attachments
for file in filenames:
part = MIMEBase('application', 'octet-stream')
part.set_payload(open(file, 'rb').read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="%s"'
% os.path.basename(file))
msg.attach(part)
#send it
mail(recipients,
"Todays report",
"Test email",
filenames)
In very brief, just create an EmailMessage and add_attachment as many times as you like.
You can create one folder with all of the files that you want to email. Right-click on the selected folder. Choose Send to > Compressed (zipped) folder. By the way, the latest Windows versions let you drag and drop other files into the ZIP file, which gets them copied to it.
Should have waited another hour before posting. Made 2 changes:
1.) moved the attachment loop up
2.) swapped out part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file))
for part.add_header('Content-Disposition', 'attachment; filename="%s"' % file)
Works like a champ. Gmail with multiple recipients and multiple attachments.
import os
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
from email.MIMEBase import MIMEBase
from email import Encoders
#Set up crap for the attachments
files = "/tmp/test/dbfiles"
filenames = [os.path.join(files, f) for f in os.listdir(files)]
#print filenames
#Set up users for email
gmail_user = "[email protected]"
gmail_pwd = "somepasswd"
recipients = ['recipient1','recipient2']
#Create Module
def mail(to, subject, text, attach):
msg = MIMEMultipart()
msg['From'] = gmail_user
msg['To'] = ", ".join(recipients)
msg['Subject'] = subject
msg.attach(MIMEText(text))
#get all the attachments
for file in filenames:
part = MIMEBase('application', 'octet-stream')
part.set_payload(open(file, 'rb').read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="%s"' % file)
msg.attach(part)
mailServer = smtplib.SMTP("smtp.gmail.com", 587)
mailServer.ehlo()
mailServer.starttls()
mailServer.ehlo()
mailServer.login(gmail_user, gmail_pwd)
mailServer.sendmail(gmail_user, to, msg.as_string())
# Should be mailServer.quit(), but that crashes...
mailServer.close()
#send it
mail(recipients,
"Todays report",
"Test email",
filenames)
Thanks @marc! I can't comment on your answer, so here are few fixes (misnamed variables) and small improvements:
import os
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email import MIMEImage
from email.mime.base import MIMEBase
from email import Encoders
def mail(to, subject, text, attach):
# allow either one recipient as string, or multiple as list
if not isinstance(to,list):
to = [to]
# allow either one attachment as string, or multiple as list
if not isinstance(attach,list):
attach = [attach]
gmail_user='[email protected]'
gmail_pwd = "password"
msg = MIMEMultipart()
msg['From'] = gmail_user
msg['To'] = ", ".join(to)
msg['Subject'] = subject
msg.attach(MIMEText(text))
#get all the attachments
for file in attach:
print file
part = MIMEBase('application', 'octet-stream')
part.set_payload(open(file, 'rb').read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file))
msg.attach(part)
mailServer = smtplib.SMTP("smtp.gmail.com", 587)
mailServer.ehlo()
mailServer.starttls()
mailServer.ehlo()
mailServer.login(gmail_user, gmail_pwd)
mailServer.sendmail(gmail_user, to, msg.as_string())
# Should be mailServer.quit(), but that crashes...
mailServer.close()
if __name__ == '__main__':
mail(['recipient1', 'recipient2'], 'subject', 'body text',
['attachment1', 'attachment2'])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With