Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Send Emails using Python (Multiple Examples)

Python lets you automate the task of sending emails by using its built-in modules. Doing so frees you from the tedious and time-consuming task of manually sending emails to thousands of users.

This tutorial will look into some fast, easy ways of sending emails and working with Python’s built-in email modules.

Table of Contents

Check if Email exists

Often, you may want to check whether an email entered by a user is a valid email or syntactically incorrect. Moreover, you may also want to check whether the email address actually exists. This can be quickly done using Python.

A valid email address has a specific format. There always exists an ‘@’ symbol. The prefix is the part before the @ sign, and the postfix is followed after the @ sign.

The postfix has to be a verified domain name. Email addresses can contain numbers, alphabets, periods, dashes, and underscores.

If a dash or underscore is used, it needs to be followed by an alphabet or a number. These are the rules that define a correct email address.

Python’s re module comes in handy if you want to check the syntax of an email address entered by a user. ‘re’ is a short-form for regular expressions.

You can create a regular expression that matches the syntax of a valid email. To do this, you need to understand how regular expressions work. Below is a regular expression that checks the syntax for an email address.

import re

valid_regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'

def check(email):

  if(re.fullmatch(valid_regex, email)):

    print("This is a valid email") 

  else:

    print("This is an invalid email")
 
email = "[email protected]"

check(email)

Using the re module requires you to have a solid understanding of the regular expressions.

An even better way to check whether an email exists is to use a third-party package named validate-email-address. You can install this module using a package manager such as pip.

$ pip install py3-validate-email
from validate_email import validate_email

valid_email = validate_email(email_address='[email protected]')

The great thing about this package is that it checks the syntax of an email and checks whether the given email address exists by simulating an actual email delivery. To do this, you need to set the check_smtp flag to true.

from validate_email import validate_email

valid_email = validate_email(email_address='[email protected]', check_smtp = True)    

Python Email server

To send emails using Python, you need to set up an email Server first. The most common way and the industry-standard protocol for sending emails is by using the SMTP protocol.

SMTP is an abbreviation for Simple Mail Transfer Protocol. Email service providers make use of SMTP servers and the SMTP protocol to send or relay messages.

You can create your own SMTP email server using the smtplib module of Python. The module lets you send simple messages without a subject line or multimedia.

Python also has an inbuilt email package that allows you to send additional attachments alongside your text message. When used in conjunction with the smtplib module, you can send rich emails with attachments and subject lines.

To create an email server using the smtplib module, you first need to run the Import statement.

import smtplib

You can then create an SMTP instance that encapsulates an SMTP connection. You can set up the optional parameters host and port to specify the port and host, depending upon your particular email service provider.

To set up a connection that closes automatically, you need to use the ‘with’ statement.

from smtplib import SMTP

with SMTP(host= "exampledomain.com", port= 587) as smtp:

    smtp.starttls()

    smtp.noop()

When you use SMTP, the connection initiated is not secure. This is why you need to encrypt it using starttls().

An alternative is to start a secure connection from the beginning rather than encrypting it after the connection has been initiated. The SMTP_SSL instance is used for this case.

from smtplib import SMTP

server = "smtp-mail.outlook.com"

port = 587

with smtplib.SMTP_SSL(server, port) as server:

    server.login("[email protected]", password="StrongPassword")

Send Email with Python

Once you have set up your email server, you can relay emails to valid addresses. The sendmail() function does this. It requires you to specify the email address of the sender and receiver, along with the message.

If your SMTP server requires authentication to send a message, you’ll need to enter the credentials of your email account.

You can pass the username and password to the login() function, which will perform the authentication.

When using the smtplib module, there are two ways you could go about sending emails. Both of them ensure that your SMTP connection is secure and encrypted.

Sending Email via SMTP

As seen earlier, you can first initiate a connection that is not encrypted over TLS, and later encrypt it using starttls(). In this case, an instance of the SMTP class is created.

import smtplib

import ssl

port = 587  

smtp_server = "smtp-mail.outlook.com"

sender = "[email protected]"

recipient = "[email protected]"

sender_password = "strongpassword"

message = """

Subject: This is a test message

Sent using Python."""

SSL_context = ssl.create_default_context()

with smtplib.SMTP(smtp_server, port) as server:

    server.starttls(context=SSL_context)

    server.login(sender, sender_password)

    server.sendmail(sender, recipient, message)

Send with SMTP SSL

The second way to send an email is to initiate a secure connection over TLS. This is the right option in situations where SSL is required from the beginning of the connection.

import smtplib

import ssl

port = 465  

smtp_server = "smtp-mail.outlook.com"

sender = "[email protected]"

recipient = "[email protected]"

sender_password = "strongpassword"

message = """

Subject: This is a test message

Send using Python."""

SSL_context = ssl.create_default_context()

with smtplib.SMTP_SSL(smtp_server, port, context=SSL_context) as server:

    server.login(sender, sender_password)

    server.sendmail(sender, recipient, message)

Send Email without SMTP server

If you do not want to set up an SMTP server to send emails, the chilkat module will be your best bet. It contains the Chilkat MailMan class, which is responsible for sending and receiving emails through SMTP and POP3 servers, respectively.

The module provides a method MxLookup that performs a DNS MX lookup to find the mail server using the recipient’s email address. You’ll need to install the chilkat module for doing this.

import sys

import chilkat

mailman = chilkat.CkMailMan()

receiver_address = "[email protected]"

smtpHost = mailman.mxLookup(receiver_address)

if (mailman.get_LastMethodSuccess() != True):

    print(mailman.lastErrorText())

    sys.exit()

mailman.put_SmtpHost(smtpHost)

mail = chilkat.CkEmail()

mail.put_Subject("A test subject")

mail.put_Body("Hello!")

mail.put_From("")

mail.AddTo("", receiver_address)

success = mailman.SendEmail(mail)

if (success != True):

    print(mailman.lastErrorText())

else:

    print("Sent!")

Email MIME text

If you want to send plain text emails without subjects or emphasis (bolds, italics, or underlines), the smtplib module from Python is enough to get the job done.

However, you often want to add attachments (images, hyperlinks, etc.) or responsive content in real-life scenarios with your plain text. Python’s built-in email module comes in handy in such situations.

MIME, an abbreviation for Multipurpose Internet Mail Extensions, is a type of email that uses HTML combined with plain text.

It extends the SMTP protocol to support images, videos, audio, and other attachments. Python’s email.mime module allows you to include HTML or attachments when sending emails over the SMTP server.

To do that, you need to import the modules by running the following statement.

from email.mime.text import MIMEText

from email.mime.multipart import MIMEMultipart

import smtplib

import ssl

port = 587

server = "smtp-mail.outlook.com"

sender = "[email protected]"

recipient = "[email protected]"

password = "strongpassword"

msg = MIMEMultipart()       

message = """Hi,
This is a MIME text
"""

msg['From']= sender_email

msg['To']= receiver_email

msg['Subject']="This is a text email for MIME"

msg.attach(MIMEText(message, "plain"))

text = msg.as_string()

SSLcontext = ssl.create_default_context()

with smtplib.SMTP(server, port) as server:

    server.starttls(context=SSLcontext)

    server.login(sender, password)

    server.sendmail(sender, recipient, text) 

Send HTML Email

Besides sending MIME text over an SMTP server, the email.mime also works well for sending HTML emails. The process is exactly the same as above, with a subtle difference in the MIMEText() function.

You passed “plain” as the second argument in the previous code example since the message was a simple plain text. When you want to send an HTML text, you change your text and this argument to “html.”

from email.mime.text import MIMEText

from email.mime.multipart import MIMEMultipart

import smtplib

import ssl

port = 587

server = "smtp-mail.outlook.com"

sender = "[email protected]"

recipient = "[email protected]"

password = "strongpassword"

msg = MIMEMultipart()       

html_message = """

    
        

This is HTML

""" msg.attach(MIMEText(html_message, "html")) text = msg.as_string() SSLcontext = ssl.create_default_context() with smtplib.SMTP(server, port) as server: server.starttls(context=SSLcontext) server.login(sender, password) server.sendmail(sender, recipient, text)

Specify CC and BCC

The email.mime module also lets you specify CC and BCC recipients within your email message. To do so, you need to specify additional headers in your Multipart message.

from email.mime.text import MIMEText

from email.mime.multipart import MIMEMultipart

import smtplib

import ssl

port = 587

server = "smtp-mail.outlook.com"

sender = "[email protected]"

recipient = "[email protected]"

password = "strongpassword"

msg = MIMEMultipart()       

message = """
    An email with CC and BCC
"""

msg['From']= sender

msg['To']= recipient

msg['Subject']= "This is TEST"

msg["Bcc"] = recipient

msg["Cc"] = '[email protected]'

msg.attach(MIMEText(message, "plain"))

text = msg.as_string()

SSLcontext = ssl.create_default_context()

with smtplib.SMTP(server, port) as server:

    server.starttls(context=SSLcontext)

    server.login(sender, password)

    server.sendmail(sender, recipient, text)

Send Email with attachment

Attachments are sent over the SMTP server in the form of binary files. To do so, you need to encode the attachments in base64, a common binary-to-text encoding scheme for encoding binary data into ASCII characters.

For instance, you can send a pdf file by reading it as an octet-stream with a MIMEBase instance and encoding it using the encoders module within Python’s email library.

from email.mime.base import MIMEBase

from email.mime.multipart import MIMEMultipart

from email.mime.text import MIMEText

import smtplib, ssl

from email import encoders


port = 587

server = "smtp-mail.outlook.com"

sender = "[email protected]"

recipient = "[email protected]"

password = "strongpassword"

msg = MIMEMultipart()       

message = "This email includes an attachment"

msg.attach(MIMEText(message, "plain"))

filename = "example.pdf"

with open(filename, "rb") as pdf:

    attachment = MIMEBase("application", "octet-stream")

    attachment.set_payload(pdf.read())

encoders.encode_base64(attachment)

attachment.add_header(
    "Content-Disposition",
    f"attachment; filename= {filename}",
)

msg.attach(attachment)


SSLcontext = ssl.create_default_context()

with smtplib.SMTP(server, port) as server:

    server.starttls(context=SSLcontext)

    server.login(sender, password)

    server.sendmail(sender, recipient, msg.as_string())

Send Email with inline images

Sometimes you may want to embed images inside the HTML text. To do that, you can convert your image into base64 encoded format and send it over.

Fortunately, Python has a library to do that for you. You can import the base64 library and use the b64encode() function that does this seamlessly.

from email.mime.multipart import MIMEMultipart

from email.mime.text import MIMEText

from email.mime.image import MIMEImage

import smtplib, ssl, base64

port = 587

server = "smtp-mail.outlook.com"

sender = "[email protected]"

recipient = "[email protected]"

password = "strongPassword"

msg = MIMEMultipart()       

msg['From']= sender

msg['To']= recipient

msg['Subject']= "My subject"

filename = "example.jpg"

image = base64.b64encode(open(filename, "rb").read())

image_base64 = image.decode()

html_img = """

    
        

""" msg.attach(MIMEText(html_img, "html")) text = msg.as_string() context = ssl.create_default_context() with smtplib.SMTP(smtp_server, port) as server: server.starttls(context=context) server.login(sender, password ) server.sendmail(sender, recipient, text)

Send Email to internationalized Email address (non ASCII)

Before emails gained worldwide recognition, they were mainly composed of ASCII characters and compiled with RFC 822 standard.

These days emails are sent internationally in many more character sets that are language-specific. To send internationalized emails, you need to use the email.header module, which encodes non-ASCII characters into RFC 2822-compliant format.

If your subject or sender fields contain non-ASCII characters, you can use the Header class to create a Header instance and pass the character set that the string was encoded in.

A corresponding decode_header() function decodes the encoded string into the original character set.

import email, smtplib, ssl

from email.mime.text import MIMEText

from email.mime.multipart import MIMEMultipart

from email.header import Header, decode_header

subject = "Some non ASCII text"

receiver_email = "Pelé@example.com"

message = MIMEMultipart('mixed')

message['Subject'] = Header(subject, 'utf-8')

message['To'] = Header(receiver_email, 'iso-8859-1')

text = message.as_string()

print(text)

decode_header(text)

Send DKIM signed mail

Using Python, you can send digitally signed emails using your private key. This is extremely useful in situations where authentication of a sender is essential.

To do that, you need to install a third-party package named dkimpy. You’ll need to install the package using the setup.py file.

Once done, you can import it by running the statement:

import dkim

Now you can generate a signature of your message using your private key (You’ll need to generate a public/private keypair for doing this). After that, you’ll have to attach the digital signature to your Multipart message and you’re all set.

import smtplib, dkim, time, os

from email.mime.multipart import MIMEMultipart

from email.mime.text import MIMEText

port = 587

smtp_server = "smtp-mail.outlook.com"

sender_email = "[email protected]"

receiver_email = "[email protected]"

password = "strongPassword"

msg = MIMEMultipart()       

msg['From']= sender_email

msg['To']= receiver_email

msg['Subject']= "This is TEST"

message = "A digitally signed email"

msg.attach(message)

headers=[b'from', b'to', b'subject']

privateKey = open(os.path.join('private_kry.pem')).read()

signature = dkim.sign(msg.as_string(), b'key1', b'mydomain.com', privateKey.encode(), include_headers=headers)

signature = signature.decode()

msg['DKIM-Signature'] = signature[len("DKIM-Signature: "):]

context = ssl.create_default_context()

with smtplib.SMTP(smtp_server, port) as server:

    server.starttls(context=context)

    server.login(sender_email, password )

    server.sendmail(sender_email, receiver_email,msg)

print('Sent')

Send Email to multiple recipients

The real benefits of email automation are reaped when you want to send personalized emails to multiple recipients. Perhaps you have a CSV file that contains many users’ names and email addresses.

You can read the CSV file in Python and loop over each line to retrieve the name and email of the recipient.

Once you have the recipient’s information, you can make your message more personalized by using str.format() and placeholders. Here’s how you do it:

import csv

import smtplib

import ssl

body = "Hello {name}!"

port = 587

server = "smtp-mail.outlook.com"

sender = "[email protected]"

password = "strongPassword"

SSLcontext = ssl.create_default_context()

with smtplib.SMTP(server, port) as server:

    server.starttls(context = SSLcontext)

    server.login(sender_email, password)

    with open("file.csv") as file_handle:

        content = csv.reader(file_handle)

        next(content)  

        for name, email in content:

            server.sendmail(sender, email, body.format(name = name))



This post first appeared on LikeGeeks, please read the originial post: here

Share the post

Send Emails using Python (Multiple Examples)

×

Subscribe to Likegeeks

Get updates delivered right to your inbox!

Thank you for your subscription

×