Python Send Html, Image And Attachment Email Example

In last article Python SMTP Send Email Example we had learnt how the email transfer from the internet to receiver’s email address, we have also learnt the basic source code to send email to SMTP server in Python program. This article we will tell you how to send more complex email content such as html format content, image and attachment through SMTP server.

1. Send HTML Content In Email.

What if we want to send HTML messages instead of plain text in email? The method is simple. When you construct the MIMEText object, pass in the HTML string and change the second parameter from ‘plain’ to ‘html’, other code are same. When you send the email again, you can see html content in the email body.

msg = MIMEText('<html><body><h1>Hello World</h1>' +
'<p>this is hello world from <a href="http://www.python.org">Python</a>...</p>' +
'</body></html>', 'html', 'utf-8')

2. Send Email With Attachments.

Mail with attachments can be regarded as mail with several parts: text and attachments. So, we can construct a MIMEMultipart object to represent the mail itself, then add a MIMEText object that contains email content to the mail body, and then add a MIMEBase object to the mail body to represent the attachment. Then, follow the normal send process to send the message ( MIMEMultipart object ) to smtp server then the email with attachments will be received.

# get user input
# input sender email address and password:
from_addr = input('From: ')
password = input('Password: ')
# input receiver email address.
to_addr = input('To: ')
# input smtp server ip address:
smtp_server = input('SMTP server: ')

# email object that has multiple part:
msg = MIMEMultipart()
msg['From'] = from_addr
msg['To'] = to_addr
msg['Subject'] = Header('hello world from smtp server', 'utf-8').encode()

# attache a MIMEText object to save email content
msg_content = MIMEText('send with attachment...', 'plain', 'utf-8')
msg.attach(msg_content)

# to add an attachment is just add a MIMEBase object to read a picture locally.
with open('/Users/jerry/img1.png', 'rb') as f:
    # set attachment mime and file name, the image type is png
    mime = MIMEBase('image', 'png', filename='img1.png')
    # add required header data:
    mime.add_header('Content-Disposition', 'attachment', filename='img1.png')
    mime.add_header('X-Attachment-Id', '0')
    mime.add_header('Content-ID', '<0>')
    # read attachment file content into the MIMEBase object
    mime.set_payload(f.read())
    # encode with base64
    encoders.encode_base64(mime)
    # add MIMEBase object to MIMEMultipart object
    msg.attach(mime)

server = smtplib.SMTP(smtp_server, 25)
server.set_debuglevel(1)
server.login(from_addr, password)
server.sendmail(from_addr, [to_addr], msg.as_string())
server.quit()

3. Send Email With Image.

What if you want to embed an image in the body of the mail? Is it okay to link the image address directly in HTML mail? The answer is that most email service providers automatically block pictures with external links because they don’t know whether these links point to malicious websites or not.

To embed the image into the body of the mail, we just need to add the image as an attachment in the way of sending attachments. Then, in HTML, we can embed the attachment as an image by referring to src= “cid:0”. If you have multiple pictures, numbering them in turn and then referring to different cid: x.

 msg.attach(MIMEText('<html><body><h1>Hello</h1>' +
'<p><img src="cid:0"></p>' +
'</body></html>', 'html', 'utf-8'))

4. Support Both HTML And Plain Text Formats.

If we send HTML mail, the recipient can browse the content of the mail normally through the browser or software such as Outlook, but what if the device used by the recipient is too old to view HTML mail? The solution is to attach a plain text while sending HTML. If the recipient can’t view the mail in HTML format, it can automatically degrade to view the plain text mail.

Using MIMEMultipart, you can combine HTML and Plain Text content in one email. Note that subtype should be alternative.

msg = MIMEMultipart('alternative')
msg['From'] = input('From: ')
msg['To'] = input('To: ')
msg['Subject'] = input('Subject: ')

msg.attach(MIMEText('hello this is a plain text version.', 'plain', 'utf-8'))
msg.attach(MIMEText('<html><body><h1>Hello this is html version</h1></body></html>', 'html', 'utf-8'))

5. Encrypted SMTP.

When connecting to SMTP server using standard port 25, it uses plaintext transmission, and the whole process of sending mail may be eavesdropped. To send email safer, you can encrypt SMTP sessions, which is essentially to create an SSL secure connection before sending mail using the SMTP protocol.

# define smtp server domain and port number.
smtp_server = 'smtp.yahoo.com'
smtp_port = 989
# create smtp server object.
server = smtplib.SMTP(smtp_server, smtp_port)
# use ssl protocol to secure the smtp session connection, all the data transferred by the session will be secured. 
server.starttls()
# send the email as normal.
server.set_debuglevel(1)