Learn Python: How to send email in Python application

If you are developing some Python module or application that needs to send some message to your users, one of the communication channel that you will use Email. Like any other language or framework, you will have a question about how can you send email from your application using Python. In this post, I will show you my EmailSender class. This class encapsulates all the low level details and expose one method sendEmail to allow your application to send email to recipients.

EmalSender

Before I provide some details how this is accomplished in Python, I will show you the code I use.

# email_sender.py
from smtplib import SMTP, SMTPAuthenticationError, SMTPException, SMTPRecipientsRefused
from email.message import EmailMessage, Message
from config import Config
from email_account import EmailAccount
import mimetypes
import os

class EmailSender:
    """
    Use EmailSender class to send emails to recipients.
    """
    def __init__(self, emailAccount): 
        self.emailAccount = emailAccount

    def sendEmail(self, subject, message, fromEmail, to, cc="", bcc="", attachments=None):
        try:
            smtp_sever = SMTP(self.emailAccount.host, self.emailAccount.port)
            if (len(self.emailAccount.username) != 0):
                smtp_sever.login(self.emailAccount.username, self.emailAccount.password)

            email_message = EmailMessage()
            email_message["Subject"] = subject
            email_message["From"] = fromEmail
            email_message["To"] = to
            email_message["CC"] = cc
            email_message["BCC"] = bcc
            email_message.set_content(message)
            if (attachments != None):
                for attachment_file in attachments:
                    # Before reading attachment file, check if file exists or not
                    if not os.path.exists(attachment_file):
                        continue

                    with open(attachment_file, "rb") as attachment:
                        # Guess file's mimetype
                        ctype, encoding = mimetypes.guess_type(attachment_file)
                        # If we are not able to guess mimetype, then set it to generic octet-stream type
                        if ctype is None or encoding is not None:
                            ctype = "application/octet-stream"
                        
                        # Split the mimetype into main and subtype. We will need these individual types
                        # when attaching the file's content to email.
                        main_type, sub_type = ctype.split("/",1)
                        
                        attachment_data = attachment.read()
                        email_message.add_attachment(attachment_data, 
                                                        maintype=main_type, 
                                                        subtype=sub_type,
                                                        filename=os.path.basename(attachment_file))

            smtp_sever.send_message(msg=email_message)
        except SMTPException:
            print("SMTP error!")
        except SMTPAuthenticationError:
            print("SMTP authetnication failed!")
        except SMTPRecipientsRefused:
            print("SMTP recepients refused")
        finally:
            pass


if __name__ == "__main__":
    app_config = Config()
    app_config.load()
    email_sender = EmailSender(app_config.configuration.emailAccount)
    email_sender.sendEmail(subject="Hello Python",
                           message="Geetings from Python Email Sender", 
                           fromEmail="xyz@foo.com", 
                           to="bar@baz.com",
                           cc="joe@foo.com",
                           bcc="doe@foo.com",
                           attachments=["config.json"])


# email_account.py

class EmailAccount:
    def __init__(self, email, 
                displayName, host, 
                username, password, 
                enableSsl=False,useDefaultCredentials=False,port=25):
        self.email=email
        self.displayName = displayName
        self.host = host
        self.username = username
        self.password = password
        self.port = port
        self.enableSsl = enableSsl
        self.useDefaultCredentials = useDefaultCredentials

SMTP

In Python, SMTP protocol functionality is provided by smtplib module. In your code, you are going to need to import objects from this module. Next is construction of message that needs to be sent in your email. Python has email package that provides functionality to create message details that is RFC compliant.

EmailSender class allows the caller to provide path of attachments that need to be send to recipients. The implementation ensures that attachment files exist and can be read. The implementation uses a support class, EmailAccount, to encapsulates host and other information about sending server. These settings include credentials settings as well. You can extend this class to include other authentication methods as well.

Search

Social

Weather

20.8 °C / 69.4 °F

weather conditions Clouds

Monthly Posts

Blog Tags