I tried to implement the mail sending function in Python

Introduction

We have implemented the function to send emails in Python! You can easily attach files!

How to use

I will explain how to use it using sending an email from gmail as an example.

Get the user and password of gmail by referring to the link below. Send Gmail in Python

After acquisition, execute the following program.


from_address = 'Source address'
to_address = 'Destination address'
subject = 'subject'
body = 'Text'
#Path of the file to attach
attachment = 'test.txt'
user = 'user'
password = 'password'

mail = Mail('smtp.gmail.com', 587, user, password)
#No attachments
mail.send(from_address, to_address, subject, body)
#There is an attachment
mail.send(from_address, to_address, subject, body, attachments=attachment)

Multiple people can send by passing the destination email address (including cc and bcc) in a list. Similarly, you can attach multiple files by passing the attachments in a list.

At the end

I'm sorry for the change. .. ..

Implementation

import copy
import os
import smtplib
from email.header import Header
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import formatdate
from typing import Union


class Mail(object):
    """
Class to send email
    """

    def __init__(self, smtp_host: str, smtp_port: int, user: str = None, password: str = None):
        """constructor

        Args:
            smtp_host:smtp host
            smtp_port:smtp port
            user:User
            password:password
        """
        self.smtp_host = smtp_host
        self.smtp_port = smtp_port
        self.user = user
        self.password = password

    def send(self, from_address: str, to_addresses: Union[str, list], subject: str, body: str,
             attachments: Union[str, list] = None, profile: str = None, cc_addresses: Union[str, list] = None,
             bcc_addresses: Union[str, list] = None):
        """send an email

        Args:
            from_address:Source address
            to_addresses:Destination address
            subject:subject
            body:Text
            attachments:Attachment
            profile:Profile
            cc_addresses:cc address
            bcc_addresses:bcc address

        """

        if attachments:
            msg = self.create_body_with_attachment(
                from_address, to_addresses, subject, body, attachments, profile, cc_addresses, bcc_addresses)
        else:
            msg = self.create_body(from_address, to_addresses, subject, body, profile, cc_addresses, bcc_addresses)

        if type(to_addresses) is list:
            send_list = copy.copy(to_addresses)
        else:
            send_list = [to_addresses]

        if cc_addresses:
            if type(cc_addresses) is list:
                send_list = send_list + cc_addresses
            else:
                send_list = send_list + [cc_addresses]

        if bcc_addresses:
            if type(cc_addresses) is list:
                send_list = send_list + bcc_addresses
            else:
                send_list = send_list + [bcc_addresses]

        smtpobj = smtplib.SMTP(self.smtp_host, self.smtp_port)
        smtpobj.ehlo()
        smtpobj.starttls()
        smtpobj.ehlo()
        if self.password:
            smtpobj.login(self.user, self.password)
        smtpobj.sendmail(from_address, send_list, msg.as_string())
        smtpobj.close()

    def create_body_with_attachment(self, from_address, to_addresses, subject, body, attachments, profile,
                                    cc_addresses=None, bcc_addresses=None):
        """Create an email body with attachments

        Args:
            from_address:Source address
            to_addresses:Destination address
            subject:subject
            body:Text
            attachments:Attachment
            profile:Profile
            cc_addresses:cc address
            bcc_addresses:bcc address

        Returns:
the content of the email
        """

        msg = MIMEMultipart()
        msg = self.create_msg(msg, from_address, to_addresses, subject, profile, cc_addresses, bcc_addresses)
        body = MIMEText(body.encode("utf-8"), 'html', 'utf-8')
        msg.attach(body)

        if type(attachments) is not list:
            attachments = [attachments]

        for attachment in attachments:
            base_name = os.path.basename(attachment)
            with open(attachment, "rb") as f:
                part = MIMEApplication(
                    f.read(),
                    Name=base_name
                )

            part['Content-Disposition'] = 'attachment; filename="{}"'.format(base_name)
            msg.attach(part)

        return msg

    def create_body(self, from_address, to_addresses, subject, body, profile, cc_addresses=None, bcc_addresses=None):
        """Create email body

        Args:
            from_address:Source address
            to_addresses:Destination address
            subject:subject
            body:Text
            profile:Profile
            cc_addresses:cc address
            bcc_addresses:bcc address

        Returns:
the content of the email
        """

        msg = MIMEText(body.encode("utf-8"), 'html', 'utf-8')
        return self.create_msg(msg, from_address, to_addresses, subject, profile, cc_addresses, bcc_addresses)

    @staticmethod
    def create_msg(msg, from_address, to_addresses, subject, profile=None, cc_addresses=None, bcc_addresses=None):
        msg['Subject'] = subject
        if profile:
            msg['From'] = '{} <{}>'.format(Header(profile.encode('utf-8'), 'utf-8').encode(), from_address)
        else:
            msg['From'] = from_address

        def to_string_addresses(addresses):
            if type(addresses) is list:
                return ','.join(addresses)
            else:
                return addresses

        msg['To'] = to_string_addresses(to_addresses)
        msg['Bcc'] = to_string_addresses(bcc_addresses)
        msg['Cc'] = to_string_addresses(cc_addresses)

        msg['Date'] = formatdate()

        return msg

Recommended Posts

I tried to implement the mail sending function in Python
I tried to implement PLSA in Python
I tried to implement permutation in Python
I tried to implement PLSA in Python 2
I tried to implement ADALINE in Python
I tried to implement PPO in Python
I tried to implement TOPIC MODEL in Python
I tried to implement selection sort in python
I tried to graph the packages installed in Python
I tried to implement a pseudo pachislot in Python
I tried to implement Dragon Quest poker in Python
I tried to implement GA (genetic algorithm) in Python
I tried to implement a one-dimensional cellular automaton in Python
I tried to implement blackjack of card game in Python
I tried to implement a misunderstood prisoner's dilemma game in Python
I also tried to imitate the function monad and State monad with a generator in Python
I tried simulating the "birthday paradox" in Python
I tried the least squares method in Python
I implemented the inverse gamma function in python
I tried to implement the traveling salesman problem
I want to display the progress in Python!
[Python] I tried to summarize the set type (set) in an easy-to-understand manner.
I tried to implement a card game of playing cards in Python
I tried to implement PCANet
I tried to implement StarGAN (1)
I want to easily implement a timeout in python
I tried to implement Minesweeper on terminal with python
I tried to touch the CSV file with Python
I tried to solve the soma cube with python
I tried to implement an artificial perceptron with python
I tried to approximate the sin function using chainer
[Python] I tried to graph the top 10 eyeshadow rankings
I want to write in Python! (3) Utilize the mock
I tried to summarize how to use pandas in python
I tried to solve the problem with Python Vol.1
I want to use the R dataset in python
Python OpenCV tried to display the image in text.
I tried to summarize the string operations of Python
I tried to implement merge sort in Python with as few lines as possible
I tried to make a simple mail sending application with tkinter of Python
[Python] I tried to get the type name as a string from the type function
I want to get the file name, line number, and function name in Python 3.4
I tried to implement what seems to be a Windows snipping tool in Python
I tried to find the entropy of the image with python
I tried to simulate how the infection spreads with Python
Implement R's power.prop.test function in python
I tried the accuracy of three Stirling's approximations in python
I tried to create API list.csv in Python from swagger.yaml
I tried various methods to send Japanese mail with Python
I tried to touch Python (installation)
In the python command python points to python3.8
Implement the Singleton pattern in Python
I tried to implement adversarial validation
I tried to summarize the code often used in Pandas
I tried to illustrate the time and time in C language
I tried programming the chi-square test in Python and Java.
[Python] I tried to visualize the follow relationship of Twitter
I tried to summarize the commands often used in business
I tried to implement hierarchical clustering
I wrote the queue in Python
I tried to enumerate the differences between java and python