Skip to content

send_email

holzkohlengrill edited this page Dec 15, 2023 · 6 revisions

Two implementation examples (Steve & Marcel):

Gmailer example - Steve

import sys
import argparse


def send_mail(to_email, subject, message, from_email, email_password):

    import smtplib
    from email.mime.text import MIMEText
    from email.header import Header

    msg = MIMEText(message, _charset="UTF-8")

    msg['From'] = from_email
    msg['To'] = to_email
    msg['Subject'] = Header(subject, "utf-8")

    # if you want to use other mail providers you need to find
    #  out a way which server and port they use
    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.ehlo()
    server.starttls()
    server.login(from_email, email_password)
    try:
        server.sendmail(from_email, to_email, msg.as_string())
    except:
        print("Unexpected error while sending:" + str(sys.exc_info()[0]))

    server.quit()

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="send email via python", epilog="stg7 2016", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('message',
                        type=str,
                        default="test",
                        help="email message")
    parser.add_argument('--from_email',
                        type=str,
                        help="email address from where you want to send")
    parser.add_argument('--from_email_password',
                        type=str,
                        help="password of email address from where you want to send")
    parser.add_argument('--to_email',
                        type=str,
                        help="recipient's email address")
    parser.add_argument('--subject',
                        type=str,
                        default="test",
                        help="email subject")

    argsdict = vars(parser.parse_args())
    send_mail(argsdict["to_email"],
              argsdict["subject"],
              argsdict["message"],
              argsdict["from_email"],
              argsdict["from_email_password"])

Gmailer example Marcel

Class implementation

import smtplib
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

import pypiscout as SCout


class Gmailer():
    def __init__(self, username, password, hostURL="smtp.gmail.com", secure=True):
        """
        Init Gmailer - default values are for Google servers

        Disable 2 step verification and allow `less secure apps` to access your google account (https://support.google.com/accounts/answer/6010255); you might need to display unlock Captcha if you still get an `SMTPAuthenticationError` error (https://accounts.google.com/DisplayUnlockCaptcha)

        Google restrictions: Free accounts are limited to 500 emails per day and are rate-limited to about 20 emails per second
        Google Ports: 465 (SSL) oder 587 (TLS/STARTTLS)

        :param hostURL: URL of the SMTP server
        :param secure: use SSL (True) or not (secure is of type bool)
        """
        self.SSL = secure
        self.hostURL = hostURL

        if self.SSL is True:
            SCout.info("Using secure (SSL) connection...")
            self.SMTPport = 465
            self.server = smtplib.SMTP_SSL(host=self.hostURL, port=self.SMTPport)
            self.server.ehlo()
            self.server.login(username, password)
        else:
            raise NotImplementedError
            # TODO: fix this case for non-secure connections

            SCout.info("Using non-secure (unencrypted) connection...")
            self.SMTPport = 465
            self.server = smtplib.SMTP(host=self.hostURL, port=self.SMTPport)
            self.server.ehlo()

    def send(self, FROM, TO, SUBJECT, BODY):
        def contains_non_ascii_characters(message):
            return not all(ord(c) < 128 for c in message)

        def add_header(message, header_name, header_value):
            if contains_non_ascii_characters(header_value):
                h = Header(header_value, 'utf-8')
                message[header_name] = h
            else:
                message[header_name] = header_value
            return message

        msg = MIMEMultipart('alternative')
        msg = add_header(msg, 'Subject', SUBJECT)

        if contains_non_ascii_characters(BODY):
            html_text = MIMEText(BODY.encode('utf-8'), 'html', 'utf-8')
        else:
            html_text = MIMEText(BODY, 'html')

        msg.attach(html_text)

        try:
            self.server.sendmail(FROM, TO, msg.as_string())
            SCout.info("Email sent!")
        except:
            SCout.error("Email not sent - something went wrong...")

    def closeConnection(self):
        self.server.close()

Usage

import requests
import lxml


contentXPattern = """//*[@id="requests-http-for-humans"]/div[1]/div"""
website = requests.get("http://docs.python-requests.org/en/master/")

lxmlWebsiteObj = lxml.html.fromstring(website.content)
roiWebsite = lxmlWebsiteObj.xpath(contentXPattern)[0]   # we only want the first result
websiteContentBin = lxml.html.tostring(roiWebsite)      # preserves html

# Here you could hash `websiteContentBin` and check if it changed comparing the hashes

websiteText = websiteContentBin.decode()

# init our Gmailer class and use it
blah = Gmailer(username="[email protected]", password="mbyBeautifulPassword")
FROM = "me"
TO = "[email protected]"
SUBJECT = "This is my subject"
BODY = websiteText

blah.send(FROM=FROM, TO=TO, SUBJECT=SUBJECT, BODY=BODY)
blah.closeConnection()
Clone this wiki locally