Pythonでメールを送る方法を素振りしたかったのでメモします。SMTPを使用し、マルチパートメールを送るところまでを目標とします。
なお、実務ではSESを使用したり、SendGridを使用することが多いと思うので、あくまでローカルでメールの動作確認をする程度しか使用できません。
環境
- Python
- 3.12.2
- MailHog
- v1.0.1
事前条件
MailHogを利用して、SMTPを受け取るメールテストサーバを立てます。
mail: image: mailhog/mailhog:latest ports: - 8025:8025 # WebUI - 1025:1025 # SMTP
対応
Pythonのビルトインライブラリのsmtplib
を使用します。
基本的にはライブラリのメソッドしか使用していないので、次のコードを参考にしてください。
マルチパートメールのためにEmailMessage
とset_content
とadd_alternative
くらいしか特色はないです。
from typing import Final from email.message import EmailMessage from smtplib import SMTP class Mailer: class Local: host: Final[str] = "localhost" port: Final[int] = 1025 @classmethod def send(cls): body_text = "Hello, this is a test email sent by Python smtplib." body_html = ( "<html>Hello, this is a test email sent by Python smtplib.</html>" ) msg = EmailMessage() msg.set_content(body_text) msg.add_alternative(body_html, subtype="html") msg["Subject"] = "Python SMTP Mail Subject" msg["From"] = "no-reply@example.com" msg["To"] = "1@example.com" try: with SMTP(host=cls.host, port=cls.port) as smtp: smtp.send_message(msg) except Exception as e: print(f"Failed to send email. Error {str(e)}") raise e
ソースコード
テスト時にメールが飛ばないように、モックにしています。
- https://github.com/hirotoKirimaru/fastapi-practice/blob/b32e195384e575a5784a0c7a78201f470bf4ae75/src/helper/mailer.py#L7
- https://github.com/hirotoKirimaru/fastapi-practice/blob/b32e195384e575a5784a0c7a78201f470bf4ae75/tests/helpers/test_mailer.py#L4
終わりに
大きく解説するような箇所は無いのですが、マルチパートメールがあるのでブログにしました。
ビルトインライブラリがあるから、悩まなくていいのもいいですね。