Skip to content

Instantly share code, notes, and snippets.

@karthicraghupathi
Last active August 16, 2022 17:59
Show Gist options
  • Save karthicraghupathi/072be2dabde66c8633e7e44ce8894a2f to your computer and use it in GitHub Desktop.
Save karthicraghupathi/072be2dabde66c8633e7e44ce8894a2f to your computer and use it in GitHub Desktop.
Send email in Python 3
import smtplib
import traceback
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import COMMASPACE, formataddr, formatdate, parseaddr
from pathlib import Path
from typing import List
class MailClient:
def __init__(
self,
host: str,
port: int,
use_tls: bool,
user: str,
password: str,
debug=False,
):
self._host = host
self._port = port
self._use_tls = use_tls
self._user = user
self._password = password
self._debug = debug
self._connection = None
@staticmethod
def format_addr(addr: str) -> str:
return formataddr(parseaddr(addr))
def _send(self, from_addr: str, to_addrs: str, msg: str) -> None:
try:
self._connection = smtplib.SMTP(host=self._host, port=self._port)
self._connection.set_debuglevel(1 if self._debug else 0)
if self._use_tls:
self._connection.starttls()
if self._user and self._password:
self._connection.login(self._user, self._password)
self._connection.sendmail(from_addr, to_addrs, msg)
except:
print(traceback.format_exc())
finally:
self._connection.quit()
def sendmail(
self,
from_addr: str,
to_addrs: List[str],
reply_to_addr: str = None,
cc_addrs: List[str] = None,
bcc_addrs: List[str] = None,
subject: str = None,
plain_text_body: str = None,
html_body: str = None,
attachments: List[str] = None,
):
cleaned_from_addr = self.format_addr(from_addr)
cleaned_to_addrs = COMMASPACE.join(
[self.format_addr(addr) for addr in to_addrs]
)
message = MIMEMultipart("alternative")
message["Date"] = formatdate()
message["From"] = cleaned_from_addr
message["To"] = cleaned_to_addrs
if reply_to_addr:
message.add_header("Reply-To", self.format_addr(reply_to_addr))
if cc_addrs:
message["Cc"] = COMMASPACE.join(
[self.format_addr(addr) for addr in cc_addrs]
)
if bcc_addrs:
message["Bcc"] = COMMASPACE.join(
[self.format_addr(addr) for addr in bcc_addrs]
)
if subject:
message["Subject"] = subject
if plain_text_body:
message.attach(MIMEText(plain_text_body, "plain"))
if html_body:
message.attach(MIMEText(html_body, "html"))
if attachments:
for item in attachments:
with open(item, "rb") as attachment:
part = MIMEBase("application", "octet-stream")
part.set_payload(attachment.read())
encoders.encode_base64(part)
part.add_header(
"Content-Disposition",
'attachment; filename="{}"'.format(Path(item).name),
)
message.attach(part)
self._send(cleaned_from_addr, cleaned_to_addrs, message.as_string())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment