Tutorial :How to send email attachments?



Question:

I am having problems understanding how to email an attachment using Python. I have successfully emailed simple messages with the smtplib. Could someone please explain how to send an attachment in an email. I know there are other posts online but as a Python beginner I find them hard to understand.


Solution:1

Here's another:

import smtplib  from os.path import basename  from email.mime.application import MIMEApplication  from email.mime.multipart import MIMEMultipart  from email.mime.text import MIMEText  from email.utils import COMMASPACE, formatdate      def send_mail(send_from, send_to, subject, text, files=None,                server="127.0.0.1"):      assert isinstance(send_to, list)        msg = MIMEMultipart()      msg['From'] = send_from      msg['To'] = COMMASPACE.join(send_to)      msg['Date'] = formatdate(localtime=True)      msg['Subject'] = subject        msg.attach(MIMEText(text))        for f in files or []:          with open(f, "rb") as fil:              part = MIMEApplication(                  fil.read(),                  Name=basename(f)              )          # After the file is closed          part['Content-Disposition'] = 'attachment; filename="%s"' % basename(f)          msg.attach(part)          smtp = smtplib.SMTP(server)      smtp.sendmail(send_from, send_to, msg.as_string())      smtp.close()  

It's much the same as the first example... But it should be easier to drop in.


Solution:2

this is the code I ended up using:

import smtplib  from email.MIMEMultipart import MIMEMultipart  from email.MIMEBase import MIMEBase  from email import Encoders      SUBJECT = "Email Data"    msg = MIMEMultipart()  msg['Subject'] = SUBJECT   msg['From'] = self.EMAIL_FROM  msg['To'] = ', '.join(self.EMAIL_TO)    part = MIMEBase('application', "octet-stream")  part.set_payload(open("text.txt", "rb").read())  Encoders.encode_base64(part)    part.add_header('Content-Disposition', 'attachment; filename="text.txt"')    msg.attach(part)    server = smtplib.SMTP(self.EMAIL_SERVER)  server.sendmail(self.EMAIL_FROM, self.EMAIL_TO, msg.as_string())  

Code is much the same as Oli's post. Thanks all

Code based from Binary file email attachment problem post.


Solution:3

Here is the modified version from Oli for python 3

import smtplib  import os.path as op  from email.mime.multipart import MIMEMultipart  from email.mime.base import MIMEBase  from email.mime.text import MIMEText  from email.utils import COMMASPACE, formatdate  from email import encoders      def send_mail(send_from, send_to, subject, message, files=[],                server="localhost", port=587, username='', password='',                use_tls=True):      """Compose and send email with provided info and attachments.        Args:          send_from (str): from name          send_to (str): to name          subject (str): message title          message (str): message body          files (list[str]): list of file paths to be attached to email          server (str): mail server host name          port (int): port number          username (str): server auth username          password (str): server auth password          use_tls (bool): use TLS mode      """      msg = MIMEMultipart()      msg['From'] = send_from      msg['To'] = COMMASPACE.join(send_to)      msg['Date'] = formatdate(localtime=True)      msg['Subject'] = subject        msg.attach(MIMEText(message))        for path in files:          part = MIMEBase('application', "octet-stream")          with open(path, 'rb') as file:              part.set_payload(file.read())          encoders.encode_base64(part)          part.add_header('Content-Disposition',                          'attachment; filename="{}"'.format(op.basename(path)))          msg.attach(part)        smtp = smtplib.SMTP(server, port)      if use_tls:          smtp.starttls()      smtp.login(username, password)      smtp.sendmail(send_from, send_to, msg.as_string())      smtp.quit()  


Solution:4

from email.MIMEMultipart import MIMEMultipart  from email.MIMEText import MIMEText  from email.MIMEImage import MIMEImage  import smtplib    msg = MIMEMultipart()  msg.attach(MIMEText(file("text.txt").read()))  msg.attach(MIMEImage(file("image.png").read()))    # to send  mailer = smtplib.SMTP()  mailer.connect()  mailer.sendmail(from_, to, msg.as_string())  mailer.close()  

Adapted from here.


Solution:5

Gmail version, working with Python 3.6 (note that you will need to change your Gmail settings to be able to send email via smtp from it:

import smtplib  from email.mime.text import MIMEText  from email.mime.multipart import MIMEMultipart  from email.mime.application import MIMEApplication  from os.path import basename      def send_mail(send_from: str, subject: str, text: str,   send_to: list, files= None):        send_to= default_address if not send_to else send_to        msg = MIMEMultipart()      msg['From'] = send_from      msg['To'] = ', '.join(send_to)        msg['Subject'] = subject        msg.attach(MIMEText(text))        for f in files or []:          with open(f, "rb") as fil:               ext = f.split('.')[-1:]              attachedfile = MIMEApplication(fil.read(), _subtype = ext)              attachedfile.add_header(                  'content-disposition', 'attachment', filename=basename(f) )          msg.attach(attachedfile)          smtp = smtplib.SMTP(host="smtp.gmail.com", port= 587)       smtp.starttls()      smtp.login(username,password)      smtp.sendmail(send_from, send_to, msg.as_string())      smtp.close()  

Usage:

username = 'my-address@gmail.com'  password = 'top-secret'  default_address = ['my-address2@gmail.com']     send_mail(send_from= username,  subject="test",  text="text",  send_to= None,  files= # pass a list with the full filepaths here...  )  

To use with any other email provider, just change the smtp configurations.


Solution:6

Another way with python 3 (If someone is searching):

import smtplib  from email.mime.multipart import MIMEMultipart  from email.mime.text import MIMEText  from email.mime.base import MIMEBase  from email import encoders    fromaddr = "sender mail address"  toaddr = "receiver mail address"    msg = MIMEMultipart()    msg['From'] = fromaddr  msg['To'] = toaddr  msg['Subject'] = "SUBJECT OF THE EMAIL"    body = "TEXT YOU WANT TO SEND"    msg.attach(MIMEText(body, 'plain'))    filename = "fileName"  attachment = open("path of file", "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)    server = smtplib.SMTP('smtp.gmail.com', 587)  server.starttls()  server.login(fromaddr, "sender mail password")  text = msg.as_string()  server.sendmail(fromaddr, toaddr, text)  server.quit()  

Make sure to allow “less secure apps” on your Gmail account


Solution:7

The simplest code I could get to is:

#for attachment email  from django.core.mail import EmailMessage        def attachment_email(request):              email = EmailMessage(              'Hello', #subject              'Body goes here', #body              'MyEmail@MyEmail.com', #from              ['SendTo@SendTo.com'], #to              ['bcc@example.com'], #bcc              reply_to=['other@example.com'],              headers={'Message-ID': 'foo'},              )                email.attach_file('/my/path/file')              email.send()  

It was based on the official Django documentation


Solution:8

from email.mime.multipart import MIMEMultipart  from email.mime.image import MIMEImage  from email.mime.text import MIMEText  import smtplib    msg = MIMEMultipart()    password = "password"  msg['From'] = "from_address"  msg['To'] = "to_address"  msg['Subject'] = "Attached Photo"  msg.attach(MIMEImage(file("abc.jpg").read()))  file = "file path"  fp = open(file, 'rb')  img = MIMEImage(fp.read())  fp.close()  msg.attach(img)  server = smtplib.SMTP('smtp.gmail.com: 587')  server.starttls()  server.login(msg['From'], password)  server.sendmail(msg['From'], msg['To'], msg.as_string())  server.quit()  


Solution:9

Other answers are excellent, though I still wanted to share a different approach in case someone is looking for alternatives.

Main difference here is that using this approach you can use HTML/CSS to format your message, so you can get creative and give some styling to your email. Though you aren't enforced to use HTML, you can also still use only plain text.

Notice that this function accepts sending the email to multiple recipients and also allows to attach multiple files.

I've only tried this on Python 2, but I think it should work fine on 3 as well:

import os.path  import smtplib  from email.mime.multipart import MIMEMultipart  from email.mime.text import MIMEText  from email.mime.application import MIMEApplication    def send_email(subject, message, from_email, to_email=[], attachment=[]):      """      :param subject: email subject      :param message: Body content of the email (string), can be HTML/CSS or plain text      :param from_email: Email address from where the email is sent      :param to_email: List of email recipients, example: ["a@a.com", "b@b.com"]      :param attachment: List of attachments, exmaple: ["file1.txt", "file2.txt"]      """      msg = MIMEMultipart()      msg['Subject'] = subject      msg['From'] = from_email      msg['To'] = ", ".join(to_email)      msg.attach(MIMEText(message, 'html'))        for f in attachment:          with open(f, 'rb') as a_file:              basename = os.path.basename(f)              part = MIMEApplication(a_file.read(), Name=basename)            part['Content-Disposition'] = 'attachment; filename="%s"' % basename          msg.attach(part)        email = smtplib.SMTP('your-smtp-host-name.com')      email.sendmail(from_email, to_email, msg.as_string())  

I hope this helps! :-)


Solution:10

Below is combination of what I've found from SoccerPlayer's post Here and the following link that made it easier for me to attach an xlsx file. Found Here

file = 'File.xlsx'  username=''  password=''  send_from = ''  send_to = 'recipient1 , recipient2'  Cc = 'recipient'  msg = MIMEMultipart()  msg['From'] = send_from  msg['To'] = send_to  msg['Cc'] = Cc  msg['Date'] = formatdate(localtime = True)  msg['Subject'] = ''  server = smtplib.SMTP('smtp.gmail.com')  port = '587'  fp = open(file, 'rb')  part = MIMEBase('application','vnd.ms-excel')  part.set_payload(fp.read())  fp.close()  encoders.encode_base64(part)  part.add_header('Content-Disposition', 'attachment', filename='Name File Here')  msg.attach(part)  smtp = smtplib.SMTP('smtp.gmail.com')  smtp.ehlo()  smtp.starttls()  smtp.login(username,password)  smtp.sendmail(send_from, send_to.split(',') + msg['Cc'].split(','), msg.as_string())  smtp.quit()  


Solution:11

from email.mime.text import MIMEText  from email.mime.multipart import MIMEMultipart  import smtplib  import mimetypes  import email.mime.application    smtp_ssl_host = 'smtp.gmail.com'  # smtp.mail.yahoo.com  smtp_ssl_port = 465  s = smtplib.SMTP_SSL(smtp_ssl_host, smtp_ssl_port)  s.login(email_user, email_pass)      msg = MIMEMultipart()  msg['Subject'] = 'I have a picture'  msg['From'] = email_user  msg['To'] = email_user    txt = MIMEText('I just bought a new camera.')  msg.attach(txt)    filename = 'introduction-to-algorithms-3rd-edition-sep-2010.pdf' #path to file  fo=open(filename,'rb')  attach = email.mime.application.MIMEApplication(fo.read(),_subtype="pdf")  fo.close()  attach.add_header('Content-Disposition','attachment',filename=filename)  msg.attach(attach)  s.send_message(msg)  s.quit()  

For explanation, you can use this link it explains properly https://medium.com/@sdoshi579/to-send-an-email-along-with-attachment-using-smtp-7852e77623


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »