SMTPlib: Send Emails with Python

3 minute read

Introduction

Hello and welcome back everyone, in this blog we will be exploring how we can send emails using Python. We will be using SMTPlib.

According to the documentation of SMTPlib, The smtplib module defines an SMTP client session object that can be used to send mail to any internet machine with an SMTP or ESMTP listener daemon. For details of SMTP and ESMTP operation, consult RFC 821 (Simple Mail Transfer Protocol) and RFC 1869 (SMTP Service Extensions).

Here in this blog, we will create a class that will have the ability to create a session, send text email and then email with an attachment.

Imports

Lets import the necessary packages.

import smtplib
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import COMMASPACE, formatdate
import os
from os.path import basename
  • smtplib to send emails.
  • email and its modules to create a email with formats.
  • os to read path

Creating a Class

Here we will initialize a class and it will take host, port number, sender email and the password of the sender.

class Mail:

    def __init__(self, host="smtp.gmail.com", port=465, sender="sender@gmail.com", 
                 password="Topsy crate."):
        self.port = port
        self.smtp_server = host
        self.sender_mail = sender
        self.password = password

Creating a Service

Since we have all the information needed to login, we will create a service. We will create a service and finally login in it using email and password.

     def set_service(self):
        self.service = smtplib.SMTP(self.smtp_server,self.port)
        self.service.login(self.sender_mail, self.password)

Send Simple Email

To send a simple email, we already have a valid session and all we need now is the sender email, receiver and then subject. The content in below method is sent as a body.

    def send(self, emails, subject, content):        
        for email in emails:
            try:
                result = self.service.sendmail(self.sender_mail, email, f"Subject: {subject}\n{content}")
                print(f"Sent `{subject}` to: {email}")
            except:
                self.set_service()
                result = self.service.sendmail(self.sender_mail, email, f"Subject: {subject}\n{content}")
                print(f"Sent `{subject}` to: {email}")

Send Simple Attachment

To send an attachment in email, we will use MIMEMultipart and MIMEApplication to collect the email and attachment parts. The method takes emails, subject, content and folder as shown below in the docstring.

    def send_file(self, emails, subject, content, folder):
        """
        emails: where to send
        subject: what subject to send
        content: what content to send
        folder: which folder to send
        """
        msg = MIMEMultipart()
        msg['From'] = self.sender_mail
        msg['To'] = COMMASPACE.join(emails)
        msg['Date'] = formatdate(localtime=True)
        msg['Subject'] = subject

        msg.attach(MIMEText(content))
        
        for f in os.listdir(folder):
            with open(folder+f, "rb") as fil:
                part = MIMEApplication(
                    fil.read(),
                    Name=basename(f)
                )
            
            part['Content-Disposition'] = 'attachment; filename="%s"' % basename(f)
            msg.attach(part)

        try:
            self.service.sendmail(self.sender_mail, emails, msg.as_string())
        except Exception as e:
            self.set_service()
            self.service.sendmail(self.sender_mail, emails, msg.as_string())

Combining all

import smtplib
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import COMMASPACE, formatdate
import os
from os.path import basename

class Mail:
    def __init__(self, host="smtp.gmail.com", port=465, sender="sender@gmail.com", 
                 password="Topsy crate"):
        self.port = port
        self.smtp_server = host
        self.sender_mail = sender
        self.password = password

    def set_service(self):
        self.service = smtplib.SMTP(self.smtp_server,self.port)
        self.service.login(self.sender_mail, self.password)

    def send(self, emails, subject, content):
        
        for email in emails:
            try:
                result = self.service.sendmail(self.sender_mail, email, f"Subject: {subject}\n{content}")
                print(f"Sent `{subject}` to: {email}")
            except:
                self.set_service()
                result = self.service.sendmail(self.sender_mail, email, f"Subject: {subject}\n{content}")
                print(f"Sent `{subject}` to: {email}")
        #service.quit()

    def send_file(self, emails, subject, content, folder):
        """
        emails:
        subject:
        content:
        folder:
        """
        msg = MIMEMultipart()
        msg['From'] = self.sender_mail
        msg['To'] = COMMASPACE.join(emails)
        msg['Date'] = formatdate(localtime=True)
        msg['Subject'] = subject

        msg.attach(MIMEText(content))
        
        for f in os.listdir(folder):
            with open(folder+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)

        try:
            self.service.sendmail(self.sender_mail, emails, msg.as_string())
        except Exception as e:
            self.set_service()
            self.service.sendmail(self.sender_mail, emails, msg.as_string())



mailer = Mail(host="smtp.gmail.com", port=465, sender="sender@gmail.com", 
                 password="Topsy crate")
mailer.set_service()
mailer.send(emails_list, "Simpe Test Email", "Hey, \n This is just a test email.")
mailer.send_file(emails_comma_separated, "Attached Test Email", "Hey, \n This is just a test email.",folder)

In above example, folder is just a folder path that is accessible from this location. And the emails_list in mailer.send is the list of emails in list. And in mailer.send_file, emails are sent as comma separated value.

Comments