I had an opportunity to implement SMTP communication in Python, so I will write the implementation method.
When I was researching various implementation methods, I found a lot of information about implementing with the legacy API of the standard library, but I could not find much method with the currently recommended API. Django, a web framework, also uses legacy APIs, so I couldn't refer to the code of major libraries and frameworks.
So, I implemented it while reading the code centering on the Python smtplib
and ʻemail` standard libraries.
import smtplib
from email.message import EmailMessage
class MailClient:
def __init__(self, mail_data: Dict[str, Any] = {}) -> None:
"""
Args:
mail_data(Dict[]): Defaults to {}.
"""
self._mail_data = mail_data
def request(self) -> bool:
"""
Returns:
bool
"""
with smtplib.SMTP(host=SMTP_HOST, port=int(SMTP_PORT)) as smtp:
smtp.login(SMTP_USER, SMTP_PASSWORD)
errors = smtp.send_message(self.message())
if isinstance(errors, dict) and len(errors) > 0:
logger.warn(
f'''Failed to send to all recipients.
Details: {errors}'''
)
return True
def message(self) -> EmailMessage:
msg = EmailMessage()
msg['From'] = self._mail_data['from_address']
msg['To'] = self._mail_data['to_address']
msg['Subject'] = self._mail_data['subject']
msg.set_default_type('text/plain')
msg.set_content(self._mail_data['message'])
bcc = self._mail_data.get('bcc')
if bcc:
msg['Bcc'] = convert_to_str(bcc)
cc = self._mail_data.get('cc')
if cc:
msg['Cc'] = convert_to_str(cc)
return msg
Start a connection with the SMTP server with smtplib.SMTP
. If you are using TLS, use smtplib.SMTP_SSL
, or make a connection in clear text and then usestarttls ()
to connect with TLS.
After successfully establishing the connection, authenticate with login ()
. Then send the data with send_message
. It is sendmail that is actually responsible for sending data. Execute the SMTP command in this function to send an email.
Regarding error handling, this time I didn't write try-except because I can simply raise if an exception occurs. However, when sending to multiple destinations, if even one fails, it is recorded as a log. That information is the return value of send_message
and is stored in the ʻerrors` variable. The error type is Dict, the key is the destination address, and the value is a tuple containing the STMP response code and the corresponding message. If you want to know more about when send_message / sendmail returns a value, go to here There is a source code, so please read it.
This time, the mail data is created using EmailMessage of the email module, but you can directly assign a character string to send_message
or sendmail
. However, we do not recommend it because it is difficult if you do not understand the protocol specifications. Use Email Message whenever possible.
I was planning to publish this article sooner, but I forgot to write it halfway, so it became like writing a blog (laughs). Have a nice year: snowman2:
--smtplib --- SMTP Protocol Client
Recommended Posts