Python は smtplib モジュールを使ってメール送信インタフェースを提供していますが、Django はさらにいくつかの軽いラッパーを用意しています。これらのラッパーは、 メールをよりすばやく送信したり、開発中にメール送信をテストしたり、SMTP を使用できないプラットフォームをサポートしたりするために用意されています。
コードは django.core.mail モジュールにあります。
簡単なメール送信には send_mail() を使用します。たとえば、プレーンテキストのメッセージを送信するには、次のようにします。
from django.core.mail import send_mail
send_mail(
"Subject here",
"Here is the message.",
"from@example.com",
["to@example.com"],
fail_silently=False,
)
追加のメール送信機能が必要な場合は、EmailMessage または EmailMultiAlternatives を使用してください。例えば、特定のテンプレートとカスタムヘッダーを使用して、HTMLバージョンとプレーンテキストバージョンの両方を含むマルチパートメールを送信する場合は、次のようにします。
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
# First, render the plain text content.
text_content = render_to_string(
"templates/emails/my_email.txt",
context={"my_variable": 42},
)
# Secondly, render the HTML content.
html_content = render_to_string(
"templates/emails/my_email.html",
context={"my_variable": 42},
)
# Then, create a multipart email instance.
msg = EmailMultiAlternatives(
"Subject here",
text_content,
"from@example.com",
["to@example.com"],
headers={"List-Unsubscribe": "<mailto:unsub@example.com>"},
)
# Lastly, attach the HTML content to the email instance and send.
msg.attach_alternative(html_content, "text/html")
msg.send()
設定内の EMAIL_HOST と EMAIL_PORT で指定された SMTP ホストとポートを使用して、メールが送信されます。EMAIL_HOST_USER と EMAIL_HOST_PASSWORD が指定されている場合は、SMTP サーバーの認証に使われます。そして、EMAIL_USE_TLS と EMAIL_USE_SSL 設定により、セキュアコネクションを使うかどうかをコントロールします。
注釈
django.core.mail で送信されるメールの文字セットは、DEFAULT_CHARSET 設定の値にセットされます。
send_mail()¶ほとんどの場合、 django.core.mail.send_mail() を使ってメールを送信できます。
subject、message、from_email、recipient_list の 4 つの引数は必須です。
subject: 文字列。
message: 文字列。
from_email: 文字列。もし None なら、 Django は DEFAULT_FROM_EMAIL 設定の値を使います。
recipient_list: メールアドレスを表す文字列のリスト。recipient_list の各メンバーは、メールメッセージの "To:" フィールドで他の受信者を見ることができます。
fail_silently: 真偽値です。これが False の場合、エラーが発生したときに send_mail() は smtplib.SMTPException を発生させます。可能な例外のリストについては smtplib のドキュメントを参照してください。これらの例外はすべて SMTPException のサブクラスです。
auth_user: SMTP サーバー認証のためのユーザー名で、省略可能。指定されなかった場合、Django EMAIL_HOST_USER 設定の値を使います。
auth_password: SMTP サーバー認証のためのパスワードで、省略可能。指定されなかった場合、Django は EMAIL_HOST_PASSWORD 設定の値を使います。
connection: メール送信のために使うバックエンドで、省略可能。指定しなかった場合、デフォルトのバックエンドのインスタンスが使われます。詳しくは メールのバックエンド を参照してください。
html_message: html_message が指定された場合、送信されるメールは multipart/alternative となり、text/plain コンテンツタイプを持つ message と text/html コンテンツタイプを持つ html_message を合わせ持つものになります。
返り値は、送信に成功したメッセージの数です (送信されるメッセージが 1 つだけの場合もあるため、0 や 1 になることもあります)。
send_mass_mail()¶django.core.mail.send_mass_mail() は、大量のメール送信を扱うために用意されています。
datatuple はメッセージの集合を表すタプルです。タプル内の各要素は、それぞれ1種類のメッセージを表すタプルであり、次の形式を持ちます。
(subject, message, from_email, recipient_list)
fail_silently、auth_user、auth_password の 3 つは、send_mail() と同じように機能します。
datatuple に含まれる各要素は、最終的には別々のメールメッセージとなります。send_mail() における挙動と同じく、recipient_list 内の受信者は、メールメッセージの "To:" フィールドに書かれている他の受信者のアドレスを見ることができます。
たとえば、次のコードは異なる 2 つのメッセージを 異なる 2 つの受信者のセットに送信します。しかし、メールサーバーへのコネクションは 1 つしか開かれません。
message1 = (
"Subject here",
"Here is the message",
"from@example.com",
["first@example.com", "other@example.com"],
)
message2 = (
"Another Subject",
"Here is another message",
"from@example.com",
["second@test.com"],
)
send_mass_mail((message1, message2), fail_silently=False)
戻り値は、メッセージ送信に成功した数です。
send_mass_mail() と send_mail() の比較¶send_mass_mail() と send_mail() 違いは、send_mail() が実行されるごとに毎回コネクションを開くのに対して、send_mass_mail() はすべてのメッセージに対して 1 つだけコネクションを使います。これにより、send_mass_mail() の方が若干効率がよくなっています。
mail_admins()¶django.core.mail.mail_admins() は、ADMINS 設定で定義されているサイト管理者 (admin) に対してメールを送信するためのショートカットです。
mail_admins() は件名の前に EMAIL_SUBJECT_PREFIX 設定の値を付けますが、デフォルトでは "[Django] " です。
メールの "From: " ヘッダは SERVER_EMAIL 設定の値になります。
このメソッドは利便性と読みやすさのために存在します。
html_message が指定された場合、送信されるメールは multipart/alternative となり、text/plain コンテンツタイプを持つ message と text/html コンテンツタイプを持つ html_message を合わせ持つものになります。
mail_managers()¶django.core.mail.mail_managers() は、mail_admins() とほぼ同じで、MANAGERS 設定で定義されているサイト管理者 (manager) にメールを送信します。
以下の例は、john@example.com と jane@example.com に1つのメールを送信します。2人とも "To:" 内に宛先が見られます。
send_mail(
"Subject",
"Message.",
"from@example.com",
["john@example.com", "jane@example.com"],
)
次の例は、john@example.com と jane@example.com にメールを送信しますが、受信者はどちらも個別のメールを受け取ります。
datatuple = (
("Subject", "Message.", "from@example.com", ["john@example.com"]),
("Subject", "Message.", "from@example.com", ["jane@example.com"]),
)
send_mass_mail(datatuple)
ヘッダインジェクション は、攻撃者が 、スクリプトで生成されたメールメッセージの "To:" と "From:" をコントロールするために、メールヘッダを挿入してしまうセキュリティ上の脆弱性です。
上述した Django のメール機能は、ヘッダー値の改行を禁止することによってヘッダインジェクションを防ぎます。 subject、from_email、recipient_list のいずれかに 改行 (Unix、Windows ないし Mac のスタイル) が含まれている場合、email 関数 (例えば send_mail()) は django.core.mail.BadHeaderError (ValueError のサブクラス) 投げるため、メールは送信されません。メール送信を行う関数にデータを渡す前に、開発者は責任を持ってすべてのデータを検証しておく必要があります。
ヘッダーが含まれている文字列を message として渡した場合、ヘッダー部分はメールメッセージの冒頭に出力されます。
次の例は、リクエストの POST データから subject、message、from_email を取得し、それを admin@example.com に送信し、完了したら "/contact/thanks/" にリダイレクトします。
from django.core.mail import BadHeaderError, send_mail
from django.http import HttpResponse, HttpResponseRedirect
def send_email(request):
subject = request.POST.get("subject", "")
message = request.POST.get("message", "")
from_email = request.POST.get("from_email", "")
if subject and message and from_email:
try:
send_mail(subject, message, from_email, ["admin@example.com"])
except BadHeaderError:
return HttpResponse("Invalid header found.")
return HttpResponseRedirect("/contact/thanks/")
else:
# In reality we'd use a form class
# to get proper validation errors.
return HttpResponse("Make sure all fields are entered and valid.")
EmailMessage クラス¶Django の send_mail() と send_mass_mail() 関数は EmailMessage クラスを実際に使うための小さなラッパーです。
EmailMessage クラスの機能のすべてが send_mail() やその他のラッパーで使用可能というわけではありません。高度な機能を使いたい場合 (例えば BCC の利用、ファイル添付やマルチパートのメールなど) EmailMessage のインスタンスを直接作成する必要があります。
注釈
これは設計特性です。send_mail() およびその関連の関数は、元は Django が提供した唯一のインタフェースでした。しかし、受け入れるパラメータのリストが次第に肥大化してきてしまったので、よりオブジェクト指向的な設計に移行し、元の関数は後方互換性確保のためだけに残すことになりました。
EmailMessage はメールメッセージ本体を作成する役割を担っており、その後、メールのバックエンド がメールを送信する役目を果たします。
利便性のため、 EmailMessage には単一のメールを送信するための send() メソッドが用意されています。複数のメッセージを送信する必要がある場合は、メールバックエンドAPIが 別の方法 を提供しています。
EmailMessage オブジェクト¶EmailMessage クラスは、以下のパラメータで (省略可能な引数が使われた場合、その順番で) 初期化されます。全てのパラメータは省略可能で、send() メソッドを呼ぶ前のタイミングでセットされます。
subject: メールの件名の行。
body: 本文のテキスト。プレーンテキストのメッセージでなければなりません。
from_email: 送信者のアドレス。 fred@example.com と "Fred" <fred@example.com> のどちらの形式でも構いません。省略された場合は DEFAULT_FROM_EMAIL の設定が使用されます。
to: 受信者のメールアドレスのリストまたはタプル。
bcc: メールを送信するときに "Bcc" ヘッダ内で使われるメールアドレスのリストまたはタプル。
connection: メールバックエンド のインスタンス。このパラメータは、send() を使用して EmailMessage を送信する際に、複数のメッセージに同じ接続を使用したい場合に指定します。省略された場合は、send() が呼び出されるときに新しい接続が作成されます。このパラメータは、send_messages() を使用する場合には無視されます。
attachments: A list of attachments to put on the message. These can
be instances of MIMEBase or
EmailAttachment, or a tuple with attributes
(filename, content, mimetype).
Support for EmailAttachment items of
attachments were added.
headers: メッセージに追加するヘッダーの辞書。キーはヘッダ名、値はヘッダ値です。メールメッセージに対して適切なヘッダ名と値にするのは、呼び出す側の責任です。対応する属性は extra_headers です。
メールを送信するときに "Cc" ヘッダ内で使われる、受信者のアドレスのリストまたはタプル。
reply_to: メールを送信するときに "Reply-To" ヘッダ内で使われる、受信者のアドレスのリストまたはタプル。
例:
from django.core.mail import EmailMessage
email = EmailMessage(
"Hello",
"Body goes here",
"from@example.com",
["to1@example.com", "to2@example.com"],
["bcc@example.com"],
reply_to=["another@example.com"],
headers={"Message-ID": "foo"},
)
このクラスには以下のメソッドがあります。
send(fail_silently=False) はメールを送信します。メールの作成時にコネクションが指定されていた場合は、そのコネクションが使用されます。 そうでない場合は、デフォルトのバックエンドのインスタンスがインスタンス化され、使用されます。キーワード引数 fail_silently が True の場合、メッセージの送信中に例外が発生した場合、その例外は処理されます。空の受信者リストは例外を発生させません。メッセージが正常に送信された場合は 1 を返し、そうでない場合は 0 を返します。
message() は送信するメッセージを保持する django.core.mail.SafeMIMEText オブジェクト (Python の MIMEText クラスのサブクラス) または django.core.mail.SafeMIMEMultipart オブジェクトを構築します。もし EmailMessage クラスを拡張する必要がある場合は、おそらくこのメソッドをオーバーライドして MIME オブジェクトに必要な内容を入れることになるでしょう。
recipients() は、to、cc、bcc のいずれかの属性に記録されている、メッセージの全ての受信者のリストを返します。サブクラス化するときには、メッセージの送信時に SMTP サーバが受信者の完全な一覧を必要とするため、このメソッドもオーバーライドする必要があります。クラス内で受信者を指定する別の方法を追加する場合は、このメソッドからも返される必要があります。
attach() は新しい添付ファイルを作成し、メッセージに追加します。attach() を呼ぶには2 つの方法があります。
MIMEBase のインスタンスを引数として渡すことができます。これは生成されるメッセージに直接挿入されます。
もしくは、attach() の 3 つの引数を引き渡します: filename、content、mimetype です。filename は、メール内に表示される添付ファイルの名前です。content は、添付ファイル内に含まれるデータです。mimetype は添付ファイルに対する MIME タイプで、省略可能です。mimetype を省略した場合、MIME コンテンツタイプは添付ファイルのファイル名から推測されます。
例:
message.attach("design.png", img_data, "image/png")
また message/rfc822 の mimetype を指定すると、 django.core.mail.EmailMessage や email.message.Message も受け付けます。
text/ で始まる mimetype では、コンテンツは文字列であることが期待されます。バイナリデータはUTF-8でデコードされ、それが失敗した場合、MIMEタイプは application/octet-stream に変更され、データは変更されずに添付されます。
さらに、 message/rfc822 の添付ファイルは RFC 2046 Section 5.2.1 に違反して base64 エンコードされることはなくなりました。これは Evolution と Thunderbird で添付ファイルを表示する際に問題を引き起こす可能性があります。
attach_file() はファイルシステム上のファイルを使って新しい添付ファイルを作成します。添付するファイルのパスと、: オプションで添付に使用する MIME タイプを指定して呼び出してください。MIMEタイプが省略された場合は、ファイル名から推測されます。次のように使用します:
message.attach_file("/images/weather_map.png")
text/ で始まるMIMEタイプでは、バイナリデータは attach() のように扱われます。
A named tuple to store attachments to an email.
The named tuple has the following indexes:
filename
content
mimetype
メールに複数のコンテンツバージョンを含めることは便利です。典型的な例として、メッセージのテキスト版とHTML版の両方を送信するケースがあります。Djangoのメールライブラリを使用すると、EmailMultiAlternatives クラスを使ってこれを実現できます。
A subclass of EmailMessage that allows additional versions of the
message body in the email via the attach_alternative() method. This
directly inherits all methods (including the class initialization) from
EmailMessage.
A list of EmailAlternative named tuples. This
is particularly useful in tests:
self.assertEqual(len(msg.alternatives), 1)
self.assertEqual(msg.alternatives[0].content, html_content)
self.assertEqual(msg.alternatives[0].mimetype, "text/html")
Alternatives should only be added using the attach_alternative()
method, or passed to the constructor.
In older versions, alternatives was a list of regular tuples,
as opposed to EmailAlternative named
tuples.
メール内にメッセージ本文の別の表現を添付します。
例えば、テキスト版とHTML版を組み合わせて送信する場合、次のようにします。
from django.core.mail import EmailMultiAlternatives
subject = "hello"
from_email = "from@example.com"
to = "to@example.com"
text_content = "This is an important message."
html_content = "<p>This is an <strong>important</strong> message.</p>"
msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
msg.attach_alternative(html_content, "text/html")
msg.send()
Returns a boolean indicating whether the provided text is
contained in the email body and in all attached MIME type
text/* alternatives.
This can be useful when testing emails. For example:
def test_contains_email_content(self):
subject = "Hello World"
from_email = "from@example.com"
to = "to@example.com"
msg = EmailMultiAlternatives(subject, "I am content.", from_email, [to])
msg.attach_alternative("<p>I am content.</p>", "text/html")
self.assertIs(msg.body_contains("I am content"), True)
self.assertIs(msg.body_contains("<p>I am content.</p>"), False)
A named tuple to store alternative versions of email content.
The named tuple has the following indexes:
content
mimetype
デフォルトでは、EmailMessage 内の body パラメータの MIME タイプは "text/plain" です。この設定だとメールクライアントにかかわらず全ての受信者がメールを読むことができるので、このままにしておくのが実用的です。しかし、受信者が代替のコンテンツタイプを扱えることが確かな場合には、EmailMessage の content_subtype 属性を使ってメインのコンテンツタイプを変更することもできます。主なタイプは常に "text" ですが、サブタイプを変更できます。例えば:
msg = EmailMessage(subject, html_content, from_email, [to])
msg.content_subtype = "html" # Main content is now text/html
msg.send()
実際のメール送信は、メールバックエンドによって処理されます。
メールバックエンドのクラスには以下のメソッドがあります:
open() は、長寿命のメール送信のコネクションをインスタンス化します。
close() は、現在のメール送信のコネクションを閉じます。
send_messages(email_messages) は EmailMessage オブジェクトのリストを送信します。コネクションがオープンになっていない場合、この呼び出しを行うと暗黙的にコネクションがオープンになり、その後コネクションがクローズされます。コネクションがすでにオープンになっている場合は、メールが送信された後もオープンのままです。
コンテキストマネジャーとしても使うことができ、必要に応じて自動的に open() と close() 呼びます:
from django.core import mail
with mail.get_connection() as connection:
mail.EmailMessage(
subject1,
body1,
from1,
[to1],
connection=connection,
).send()
mail.EmailMessage(
subject2,
body2,
from2,
[to2],
connection=connection,
).send()
django.core.mail 内の get_connection() 関数は、利用可能なメールバックエンドのインスタンスを返します。
デフォルトでは、get_connection() を呼び出すと EMAIL_BACKEND 内で指定されたメールバックエンドのインスタンスを返します。backend 引数を指定した場合、そのバックエンドがインスタンス化されます。
fail_silently 引数は、バックエンドがエラーをどのように扱うかをコントロールします。fail_silently が True の場合、メール送信プロセスの間に発生した例外は何の通知もされずに無視されます。
他の全ての引数は、メールバックエンドのコンストラクタに直接引き渡されます。
Django には複数のメール送信バックエンドを付属しています。SMTP バックエンド (デフォルトです) を除いて、これらのバックエンドはテストと開発のみで役立ちます。特別なメール送信が必要な場合には、独自のメールバックエンドを記述する を参照してください。
デフォルトのバックエンド。メールは SMTP サーバを通して送信されます。
引数が None の場合、各引数に対する値は、以下のそれぞれの設定から取得されます。
host: EMAIL_HOST
port: EMAIL_PORT
username: EMAIL_HOST_USER
password: EMAIL_HOST_PASSWORD
use_tls: EMAIL_USE_TLS
use_ssl: EMAIL_USE_SSL
timeout: EMAIL_TIMEOUT
ssl_keyfile: EMAIL_SSL_KEYFILE
ssl_certfile: EMAIL_SSL_CERTFILE
SMTP バックエンドは、Django によって継承されるデフォルトの構成です。明示的に指定したい場合は、設定内で以下の通り記述してください:
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
指定しなかった場合は、デフォルトの timeout は socket.getdefaulttimeout() によって指定されたものになり、デフォルトは None (タイムアウトなし) になります。
実際のメールを送信する代わりに、コンソールバックエンドは単に標準出力に送信されるメールを書き込みます。 デフォルトでは、コンソールバックエンドは stdout に書き込みます。 コネクションを構築するときに stream キーワード引数を指定することで、別のストリーム的なオブジェクトを使用できます。
このバックエンドを指定するには、設定内に以下の通り記述してください:
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
このバックエンドはプロダクトでの使用を想定していません -- 開発中の利便性のために提供されています。
ファイルバックエンドは、メールをファイルに書き込みます。新しいファイルは、このバックエンド上で開いたそれぞれの新しいセッションに対して作成されます。ファイルが書き込まれるディレクトリは、 get_connection() でコネクションを生成したときに EMAIL_FILE_PATH 設定または file_path キーワードから取得されます。
このバックエンドを指定するには、設定内に以下の通り記述してください:
EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend"
EMAIL_FILE_PATH = "/tmp/app-messages" # change this to a proper location
このバックエンドはプロダクトでの使用を想定していません -- 開発中の利便性のために提供されています。
'locmem' バックエンドは、 django.core.mail モジュールの特別な属性内にメッセージを保持します。outbox 属性は最初のメッセージが送信されるときに生成されます。送信される書くメッセージに対する EmailMessage インスタンスのリストです。
このバックエンドを指定するには、設定内に以下の通り記述してください:
EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
このバックエンドはプロダクトでの使用を想定していません -- 開発とテストにおける利便性のために提供されています。
Django のテストランナーは 自動的にこのバックエンドをテストに使います 。
名前が示すように、ダミーバックエンドはメッセージに何もしません。このバックエンドを指定するには、設定内に以下の通り記述してください:
EMAIL_BACKEND = "django.core.mail.backends.dummy.EmailBackend"
このバックエンドはプロダクトでの使用を想定していません -- 開発中の利便性のために提供されています。
メール送信の方法を変更する必要がある場合、独自のメールバックエンドを記述できます。設定ファイル内の EMAIL_BACKEND 設定が独自のバックエンドのクラスへの Python のインポートパスとなります。
独自のメールバックエンドは、django.core.mail.backends.base にある BaseEmailBackend をサブクラス化して作ります。独自のメールバックエンドには send_messages(email_messages) メソッドを実装する必要があります。このメソッドは EmailMessage インスタンスのリストを受け取り、送信に成功したメッセージの数を返します。バックエンドに永続的な (persistent) セッションやコネクションの概念がある場合は、open() メソッドと close() メソッドも実装する必要があります。実装のリファレンスについては smtp.EmailBackend を参照してください。
SMTP コネクション (またはその他のネットワークコネクション) の確立とクローズは、負荷の高い処理です。 送信するメールがたくさんある場合は、メールを送信するたびにコネクションの生成と破棄を繰り返すのではなく、SMTP コネクションを再利用する方が効率的です。
メールバックエンドにコネクションを再利用するよう通知するには、2 つの方法があります。
1つめは、1つの接続のもとで send_messages() メソッドを使用する方法です。このメソッドは、 EmailMessage (またはそのサブクラス)のインスタンスのリストを受け取り、それらすべてを1つの接続を使用して送信します。その結果、個々のメッセージに設定された connection は無視されます。
例えば、定期的なメール送信を表す EmailMessage オブジェクトのリストを返す get_notification_email() と呼ばれる関数がある場合、send_messages を 1度呼び出すだけでこれらのメールを送信できます:
from django.core import mail
connection = mail.get_connection() # Use default email connection
messages = get_notification_email()
connection.send_messages(messages)
この例では、send_messages() を呼び出してバックエンドのコネクションを開き、メッセージのリストを送信した後、再びコネクションを閉じています。
2つ目のアプローチは、メールバックエンドの open() メソッドと close() メソッドを使って手動でコネクションをコントロールする方法です。send_messages() は、すでにコネクションが開いている場合、自動でコネクションを開いたり閉じたりはしません。手動でコネクションを開いた場合、閉じるタイミングを自分でコントロールできます。たとえば、次のように書くことができます。
from django.core import mail
connection = mail.get_connection()
# Manually open the connection
connection.open()
# Construct an email message that uses the connection
email1 = mail.EmailMessage(
"Hello",
"Body goes here",
"from@example.com",
["to1@example.com"],
connection=connection,
)
email1.send() # Send the email
# Construct two more messages
email2 = mail.EmailMessage(
"Hello",
"Body goes here",
"from@example.com",
["to2@example.com"],
)
email3 = mail.EmailMessage(
"Hello",
"Body goes here",
"from@example.com",
["to3@example.com"],
)
# Send the two emails in a single call -
connection.send_messages([email2, email3])
# The connection was already open so send_messages() doesn't close it.
# We need to manually close the connection.
connection.close()
Django に電子メールをまったく送信させたくない場合もあるでしょう。たとえば、ウェブサイトの開発中に数千通のメールを送信したくはないでしょう。しかし、適切な条件で適切な人々にメールが送信され、これらのメールが正しい内容を含んでいるか検証したいことがあるかもしれません。
ローカル開発用にメールを設定する最も簡単な方法は console メールバックエンドを使うことです。このバックエンドはすべてのメールを stdout にリダイレクトし、メールの内容を検査できるようにします。
ファイル メールバックエンドも開発に役立ちます。このバックエンドは全ての SMTP コネクションをファイルにダンプし、都合の良いときに調べられるようにします。
もう1つのアプローチは、「ダム」SMTPサーバーを使用することです。このサーバーはメールをローカルで受信し、端末に表示するだけで、実際には何も送信しません。これを実現するには、aiosmtpd パッケージを利用する方法があります。
python -m pip install aiosmtpd
python -m aiosmtpd -n -l localhost:8025
このコマンドは、localhostのポート8025で待ち受ける最小限のSMTPサーバを起動します。このサーバはすべてのメールヘッダとメール本文を標準出力に出力します。あとは EMAIL_HOST と EMAIL_PORT を適宜設定するだけです。SMTPサーバのオプションについてのより詳細な議論については、 aiosmtpd モジュールのドキュメントを参照してください。
アプリケーションでのメール送信のユニットテストについては、テストのドキュメントの メールサービス セクションを参照してください。
7月 02, 2025