We have implemented the function to send emails in Python! You can easily attach files!
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.
I'm sorry for the change. .. ..
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