Created
July 2, 2019 23:09
-
-
Save matt-blodgett/0a95e07256d6b7df7c1e35c85fb460b0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import Union | |
import logging | |
import smtplib | |
from email.mime.multipart import MIMEMultipart | |
from email.mime.base import MIMEBase | |
from email.mime.text import MIMEText | |
from email import encoders | |
LOG = logging.getLogger(__name__) | |
SMTP_DEBUG_LEVEL = 0 # 0 == off, 1 == debug, 2 == timestamps | |
SMTP_HOST = 'smtp.gmail.com' | |
SMTP_PORT = 587 | |
SMTP_USER = '' | |
SMTP_PASSWORD = '' | |
def _log_success(method, response): | |
resp_code, resp_msg = response | |
# LOG.info(f'SMTP: SUCCESS <{method}: {{code={resp_code}, message={resp_msg}}}>') | |
print(f'SMTP: SUCCESS <{method}: {{code={resp_code}, message={resp_msg}}}>') | |
def _log_failure(error): | |
err_cls = error.__class__.__name__ | |
err_code, err_msg = error.args | |
LOG.error(f'SMTP: FAILURE <smtplib.{err_cls} {{code={err_code}, message={err_msg}}}>') | |
def _fail_safely(func): | |
def _try_and_catch(*args, **kwargs): | |
try: | |
return func(*args, **kwargs) | |
except smtplib.SMTPException as e: | |
_log_failure(e) | |
return False | |
return _try_and_catch | |
class Email: | |
def __init__(self, sender=SMTP_USER, password=SMTP_PASSWORD, host=SMTP_HOST, port=SMTP_PORT): | |
self.sender = sender | |
self.password = password | |
self.host = host | |
self.port = port | |
self.subject = None | |
self.body = None | |
self.attachments = [] | |
self.message = MIMEMultipart() | |
def set_message(self, subject: Union[str, None], body: Union[str, None], html=False) -> None: | |
self.subject = subject | |
if body is None: | |
self.body = None | |
else: | |
self.body = MIMEText(body, 'plain' if not html else 'html') | |
def add_attachment(self, data: bytes, filename: str, mimetype=r'application\octet-stream') -> MIMEBase: | |
attachment = MIMEBase(*mimetype.split('\\')) | |
attachment.set_payload(data) | |
encoders.encode_base64(attachment) | |
attachment.add_header('Content-Disposition', f'attachment; filename="{filename}"') | |
self.attachments.append(attachment) | |
return attachment | |
@_fail_safely | |
def send(self, recipients: Union[str, list, tuple], cc=None, bcc=None) -> bool: | |
self.message['Subject'] = self.subject | |
self.message['From'] = self.sender | |
self.message['To'] = recipients | |
self.message['Cc'] = cc | |
self.message['Bcc'] = bcc | |
if self.body is not None: | |
self.message.attach(self.body) | |
for attachment in self.attachments: | |
self.message.attach(attachment) | |
print(f'SMTP: Creating TLS SMTP client {{host={self.host}, port={self.port}}}') | |
with smtplib.SMTP(self.host, self.port) as smtp_client: | |
smtp_client.set_debuglevel(SMTP_DEBUG_LEVEL) | |
print(f'SMTP: Sending Email {{sender={self.sender}, recipients={recipients}, cc={cc}, bcc={bcc}}}') | |
response = smtp_client.starttls() | |
_log_success('starttls', response) | |
response = smtp_client.login(self.sender, self.password) | |
_log_success('login', response) | |
smtp_client.send_message(self.message) | |
LOG.info('SMTP: SUCCESS <send: Email sent successfully>') | |
print('SMTP: SUCCESS <send: Email sent successfully>') | |
self.subject = None | |
self.body = None | |
self.attachments = [] | |
self.message = MIMEMultipart() | |
return True |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment