smtplib —SMTPプロトコルクライアント
ソースコード: :source: `Lib / smtplib.py`
smtplib モジュールは、SMTPまたはESMTPリスナーデーモンを備えた任意のインターネットマシンにメールを送信するために使用できるSMTPクライアントセッションオブジェクトを定義します。 SMTPおよびESMTPの操作の詳細については、 RFC 821 (簡易メール転送プロトコル)および RFC 1869 (SMTPサービス拡張)を参照してください。
- class smtplib.SMTP(host=, port=0, local_hostname=None, [timeout, ]source_address=None)
SMTP インスタンスは、SMTP接続をカプセル化します。 SMTPおよびESMTP操作の完全なレパートリーをサポートするメソッドがあります。 オプションのホストとポートのパラメーターが指定されている場合、SMTP connect()メソッドは、初期化中にそれらのパラメーターを使用して呼び出されます。 指定した場合、 local_hostname は、HELO / EHLOコマンドのローカルホストのFQDNとして使用されます。 それ以外の場合、ローカルホスト名は socket.getfqdn()を使用して検出されます。 connect()呼び出しが成功コード以外を返す場合、 SMTPConnectError が発生します。 オプションの timeout パラメーターは、接続試行などのブロック操作のタイムアウトを秒単位で指定します(指定されていない場合は、グローバルなデフォルトのタイムアウト設定が使用されます)。 タイムアウトが経過すると、 socket.timeout が発生します。 オプションのsource_addressパラメータを使用すると、複数のネットワークインターフェイスを備えたマシンの特定の送信元アドレスや特定の送信元TCPポートにバインドできます。 接続する前にソケットを送信元アドレスとしてバインドするには、2タプル(ホスト、ポート)が必要です。 省略した場合(またはホストまたはポートがそれぞれ
および/または0の場合)、OSのデフォルトの動作が使用されます。
通常の使用では、初期化/接続、 sendmail()、および SMTP.quit()メソッドのみが必要です。 例を以下に示します。
SMTP クラスは、 with ステートメントをサポートします。 このように使用すると、
with
ステートメントが終了すると、SMTPQUIT
コマンドが自動的に発行されます。 例えば:>>> from smtplib import SMTP >>> with SMTP("domain.org") as smtp: ... smtp.noop() ... (250, b'Ok') >>>
バージョン3.3で変更: with ステートメントのサポートが追加されました。
バージョン3.3で変更: source_address引数が追加されました。
バージョン3.5の新機能: SMTPUTF8拡張機能( RFC 6531 )がサポートされるようになりました。
- class smtplib.SMTP_SSL(host=, port=0, local_hostname=None, keyfile=None, certfile=None, [timeout, ]context=None, source_address=None)
SMTP_SSL インスタンスは、 SMTP のインスタンスとまったく同じように動作します。 SMTP_SSL は、接続の最初からSSLが必要であり、
starttls()
の使用が適切でない場合に使用する必要があります。 host が指定されていない場合、ローカルホストが使用されます。 port がゼロの場合、標準のSMTP-over-SSLポート(465)が使用されます。 オプションの引数 local_hostname 、 timeout 、および source_address は、 SMTP クラスと同じ意味を持ちます。 context もオプションで、 SSLContext を含めることができ、安全な接続のさまざまな側面を構成できます。 ベストプラクティスについては、セキュリティに関する考慮事項をお読みください。keyfile および certfile は、 context のレガシー代替手段であり、SSL接続用のPEM形式の秘密鍵および証明書チェーンファイルを指すことができます。
バージョン3.3で変更: context が追加されました。
バージョン3.3で変更: source_address引数が追加されました。
バージョン3.4で変更:クラスは ssl.SSLContext.check_hostname および Server Name Indication によるホスト名チェックをサポートするようになりました( ssl.HAS_SNI を参照) )。
バージョン3.6以降非推奨: keyfile および certfile は非推奨になり、 context が優先されます。 代わりに ssl.SSLContext.load_cert_chain()を使用するか、 ssl.create_default_context()にシステムの信頼できるCA証明書を選択させてください。
- class smtplib.LMTP(host=, port=LMTP_PORT, local_hostname=None, source_address=None)
ESMTPと非常によく似たLMTPプロトコルは、標準のSMTPクライアントに大きく基づいています。 LMTPにはUnixソケットを使用するのが一般的であるため、
connect()
メソッドは、通常のhost:portサーバーと同様にそれをサポートする必要があります。 オプションの引数local_hostnameおよびsource_addressは、 SMTP クラスの場合と同じ意味を持ちます。 Unixソケットを指定するには、 host の絶対パスを「/」で始める必要があります。認証は、通常のSMTPメカニズムを使用してサポートされます。 Unixソケットを使用する場合、LMTPは通常、認証をサポートまたは必要としませんが、マイレージは異なる場合があります。
例外の適切な選択も定義されています。
- exception smtplib.SMTPException
OSError のサブクラス。これは、このモジュールによって提供される他のすべての例外の基本例外クラスです。
バージョン3.4で変更: SMTPExceptionが OSError のサブクラスになりました
- exception smtplib.SMTPServerDisconnected
- この例外は、サーバーが予期せず切断された場合、またはサーバーに接続する前に SMTP インスタンスを使用しようとした場合に発生します。
- exception smtplib.SMTPResponseException
- SMTPエラーコードを含むすべての例外の基本クラス。 これらの例外は、SMTPサーバーがエラーコードを返したときに生成される場合があります。 エラーコードはエラーの
smtp_code
属性に格納され、smtp_error
属性はエラーメッセージに設定されます。
- exception smtplib.SMTPSenderRefused
- 送信者のアドレスは拒否されました。 すべての SMTPResponseException 例外で設定された属性に加えて、これはSMTPサーバーが拒否した文字列に「sender」を設定します。
- exception smtplib.SMTPRecipientsRefused
- すべての受信者アドレスが拒否されました。 各受信者のエラーには、属性
recipients
を介してアクセスできます。これは、 SMTP.sendmail()が返すのとまったく同じ種類の辞書です。
- exception smtplib.SMTPDataError
- SMTPサーバーはメッセージデータの受け入れを拒否しました。
- exception smtplib.SMTPConnectError
- サーバーとの接続の確立中にエラーが発生しました。
- exception smtplib.SMTPHeloError
- サーバーは
HELO
メッセージを拒否しました。
- exception smtplib.SMTPNotSupportedError
試行されたコマンドまたはオプションは、サーバーでサポートされていません。
バージョン3.5の新機能。
- exception smtplib.SMTPAuthenticationError
- SMTP認証が失敗しました。 おそらく、サーバーは提供されたユーザー名とパスワードの組み合わせを受け入れませんでした。
も参照してください
- RFC 821 -シンプルメール転送プロトコル
- SMTPのプロトコル定義。 このドキュメントでは、SMTPのモデル、操作手順、およびプロトコルの詳細について説明します。
- RFC 1869 -SMTPサービス拡張
- SMTPのESMTP拡張機能の定義。 これは、新しいコマンドでSMTPを拡張し、サーバーによって提供されるコマンドの動的検出をサポートするためのフレームワークについて説明し、いくつかの追加コマンドを定義します。
SMTPオブジェクト
SMTP インスタンスには次のメソッドがあります。
- SMTP.set_debuglevel(level)
デバッグ出力レベルを設定します。 level の値が1または
True
の場合、接続およびサーバーとの間で送受信されるすべてのメッセージのデバッグメッセージが表示されます。 level の値が2の場合、これらのメッセージにはタイムスタンプが付けられます。バージョン3.5で変更:デバッグレベル2を追加。
- SMTP.docmd(cmd, args=)
コマンド cmd をサーバーに送信します。 オプションの引数 args は、スペースで区切ってコマンドに連結するだけです。
これは、数値応答コードと実際の応答行で構成される2タプルを返します(複数行の応答は1つの長い行に結合されます)。
通常の操作では、このメソッドを明示的に呼び出す必要はありません。 これは他のメソッドを実装するために使用され、プライベート拡張機能のテストに役立つ場合があります。
応答を待っている間にサーバーへの接続が失われると、 SMTPServerDisconnected が発生します。
- SMTP.connect(host='localhost', port=0)
- 特定のポートでホストに接続します。 デフォルトでは、標準のSMTPポート(25)でローカルホストに接続します。 ホスト名がコロン(
':'
)の後に数字が続く場合、そのサフィックスは削除され、その数字は使用するポート番号として解釈されます。 インスタンス化中にホストが指定された場合、このメソッドはコンストラクターによって自動的に呼び出されます。 サーバーが接続応答で送信した応答コードとメッセージの2タプルを返します。
- SMTP.helo(name=)
HELO
を使用して、SMTPサーバーに対して自分自身を識別します。 hostname引数のデフォルトは、ローカルホストの完全修飾ドメイン名です。 サーバーから返されたメッセージは、オブジェクトのhelo_resp
属性として保存されます。通常の操作では、このメソッドを明示的に呼び出す必要はありません。 必要に応じて、 sendmail()によって暗黙的に呼び出されます。
- SMTP.ehlo(name=)
EHLO
を使用して、ESMTPサーバーに対して自分自身を識別します。 hostname引数のデフォルトは、ローカルホストの完全修飾ドメイン名です。 ESMTPオプションの応答を調べて、 has_extn()で使用できるように保存します。 また、いくつかの情報属性を設定します。サーバーから返されるメッセージはehlo_resp
属性として保存され、does_esmtp
はサーバーがESMTPをサポートするかどうかに応じてtrueまたはfalseに設定され、 [X207X ]は、このサーバーがサポートするSMTPサービス拡張機能の名前とそのパラメーター(存在する場合)を含む辞書になります。メールを送信する前に has_extn()を使用する場合を除いて、このメソッドを明示的に呼び出す必要はありません。 必要に応じて、 sendmail()によって暗黙的に呼び出されます。
- SMTP.ehlo_or_helo_if_needed()
- このセッションで以前に
EHLO
またはHELO
コマンドがなかった場合、このメソッドは ehlo()および/または helo()を呼び出します。 最初にESMTPEHLO
を試行します。
SMTPHeloError
- サーバーは
HELO
グリーティングに正しく応答しませんでした。
- SMTP.has_extn(name)
- name がサーバーから返されるSMTPサービス拡張機能のセットに含まれている場合は、 True を返し、それ以外の場合は False を返します。 大文字と小文字は区別されません。
- SMTP.verify(address)
SMTP
VRFY
を使用して、このサーバーのアドレスの有効性を確認してください。 ユーザーアドレスが有効な場合、コード250と完全な RFC 822 アドレス(人間の名前を含む)で構成されるタプルを返します。 それ以外の場合は、400以上のSMTPエラーコードとエラー文字列を返します。ノート
多くのサイトは、スパマーを阻止するためにSMTP
VRFY
を無効にしています。
- SMTP.login(user, password, *, initial_response_ok=True)
認証が必要なSMTPサーバーにログインします。 引数は、認証に使用するユーザー名とパスワードです。 このセッションで以前に
EHLO
またはHELO
コマンドがなかった場合、このメソッドは最初にESMTPEHLO
を試行します。 このメソッドは、認証が成功した場合に正常に返されるか、次の例外が発生する可能性があります。SMTPHeloError
サーバーは
HELO
グリーティングに正しく応答しませんでした。SMTPAuthenticationError
サーバーはユーザー名とパスワードの組み合わせを受け入れませんでした。
SMTPNotSupportedError
AUTH
コマンドはサーバーでサポートされていません。SMTPException
適切な認証方法が見つかりませんでした。
smtplib でサポートされている各認証方法は、サーバーでサポートされているとアドバタイズされている場合、順番に試行されます。 サポートされている認証方法のリストについては、 auth()を参照してください。 initial_response_ok は auth()に渡されます。
オプションのキーワード引数 initial_response_ok は、それをサポートする認証方法について、 RFC 4954 で指定された「初期応答」を
AUTH
コマンドであり、チャレンジ/レスポンスを要求するのではありません。バージョン3.5での変更: SMTPNotSupportedError が発生する可能性があり、 initial_response_ok パラメーターが追加されました。
- SMTP.auth(mechanism, authobject, *, initial_response_ok=True)
指定された認証メカニズムに対して
SMTP
AUTH
コマンドを発行し、 authobject を介してチャレンジレスポンスを処理します。メカニズムは、
AUTH
コマンドの引数として使用する認証メカニズムを指定します。 有効な値は、esmtp_features
のauth
要素にリストされている値です。authobject は、オプションの単一引数を取る呼び出し可能なオブジェクトである必要があります。
data = authobject(challenge = None)
オプションのキーワード引数 initial_response_ok がtrueの場合、
authobject()
が引数なしで最初に呼び出されます。 RFC 4954 「初期応答」ASCIIstr
を返すことができます。これは、以下のようにAUTH
コマンドでエンコードおよび送信されます。authobject()
が初期応答をサポートしていない場合(例: チャレンジが必要なため)、challenge=None
で呼び出すと、None
を返す必要があります。 initial_response_ok がfalseの場合、authobject()
はNone
で最初に呼び出されません。初期応答チェックが
None
を返す場合、または initial_response_ok がfalseの場合、authobject()
が呼び出されてサーバーのチャレンジ応答が処理されます。 渡される challenge 引数は、bytes
になります。 これは、base64でエンコードされてサーバーに送信されるASCIIstr
data を返す必要があります。SMTP
クラスは、CRAM-MD5
、PLAIN
、およびLOGIN
メカニズムにauthobjects
を提供します。 それぞれSMTP.auth_cram_md5
、SMTP.auth_plain
、SMTP.auth_login
という名前が付けられています。 これらはすべて、SMTP
インスタンスのuser
およびpassword
プロパティが適切な値に設定されている必要があります。ユーザーコードは通常、
auth
を直接呼び出す必要はありませんが、代わりに login()メソッドを呼び出すことができます。このメソッドは、上記の各メカニズムをリストされた順序で順番に試行します。auth
は、 smtplib によって直接サポートされていない(またはまだサポートされていない)認証方法の実装を容易にするために公開されています。バージョン3.5の新機能。
- SMTP.starttls(keyfile=None, certfile=None, context=None)
SMTP接続をTLS(トランスポート層セキュリティ)モードにします。 以降のすべてのSMTPコマンドは暗号化されます。 その後、 ehlo()を再度呼び出す必要があります。
keyfile および certfile が提供されている場合、それらは ssl.SSLContext を作成するために使用されます。
オプションの context パラメーターは、 ssl.SSLContext オブジェクトです。 これは、キーファイルと証明書ファイルを使用する代わりの方法であり、指定した場合、キーファイルと証明書ファイルの両方を
None
にする必要があります。このセッションで以前に
EHLO
またはHELO
コマンドがなかった場合、このメソッドは最初にESMTPEHLO
を試行します。バージョン3.6以降非推奨: keyfile および certfile は非推奨になり、 context が優先されます。 代わりに ssl.SSLContext.load_cert_chain()を使用するか、 ssl.create_default_context()にシステムの信頼できるCA証明書を選択させてください。
SMTPHeloError
サーバーは
HELO
グリーティングに正しく応答しませんでした。SMTPNotSupportedError
サーバーはSTARTTLS拡張機能をサポートしていません。
RuntimeError
PythonインタープリターではSSL / TLSサポートを利用できません。
バージョン3.3で変更: context が追加されました。
バージョン3.4で変更:このメソッドは、
SSLContext.check_hostname
およびサーバー名インジケーターによるホスト名チェックをサポートするようになりました( HAS_SNI を参照)。バージョン3.5で変更: STARTTLSサポートがないために発生したエラーは、ベース SMTPException ではなく SMTPNotSupportedError サブクラスになりました。
- SMTP.sendmail(from_addr, to_addrs, msg, mail_options=(), rcpt_options=())
メールを送信します。 必要な引数は、 RFC 822 from-address文字列、 RFC 822 to-address文字列のリストです(裸の文字列は1つのアドレスを持つリストとして扱われます)、およびメッセージ文字列。 呼び出し元は、
MAIL FROM
コマンドで使用されるESMTPオプション(8bitmime
など)のリストを mail_options として渡すことができます。 すべてのRCPT
コマンドで使用する必要があるESMTPオプション(DSN
コマンドなど)は、 rcpt_options として渡すことができます。 (受信者ごとに異なるESMTPオプションを使用する必要がある場合は、mail()
、rcpt()
、data()
などの低レベルの方法を使用してメッセージを送信する必要があります。)ノート
from_addr および to_addrs パラメーターは、トランスポートエージェントによって使用されるメッセージエンベロープを構築するために使用されます。
sendmail
は、メッセージヘッダーを変更しません。msg は、ASCII範囲の文字を含む文字列、またはバイト文字列の場合があります。 文字列はASCIIコーデックを使用してバイトにエンコードされ、
\r
および\n
の1文字が\r\n
文字に変換されます。 バイト文字列は変更されません。このセッションで以前に
EHLO
またはHELO
コマンドがなかった場合、このメソッドは最初にESMTPEHLO
を試行します。 サーバーがESMTPを実行する場合、メッセージサイズと指定された各オプションがサーバーに渡されます(オプションがサーバーがアドバタイズする機能セットに含まれている場合)。EHLO
が失敗した場合、HELO
が試行され、ESMTPオプションが抑制されます。このメソッドは、メールが少なくとも1人の受信者に受け入れられた場合に正常に返されます。 それ以外の場合は、例外が発生します。 つまり、このメソッドで例外が発生しない場合は、誰かがあなたのメールを受け取る必要があります。 このメソッドで例外が発生しない場合は、拒否された受信者ごとに1つのエントリを持つディクショナリが返されます。 各エントリには、SMTPエラーコードのタプルと、サーバーから送信された付随するエラーメッセージが含まれています。
SMTPUTF8
が mail_options に含まれていて、サーバーがそれをサポートしている場合、 from_addr および to_addrs に非ASCII文字が含まれる場合があります。このメソッドでは、次の例外が発生する可能性があります。
SMTPRecipientsRefused
すべての受信者は拒否されました。 誰もメールを受け取らなかった。 例外オブジェクトの
recipients
属性は、拒否された受信者に関する情報(少なくとも1人の受信者が受け入れられたときに返されるものなど)を含む辞書です。SMTPHeloError
サーバーは
HELO
グリーティングに正しく応答しませんでした。SMTPSenderRefused
サーバーは from_addr を受け入れませんでした。
SMTPDataError
サーバーは、予期しないエラーコード(受信者の拒否以外)で応答しました。
SMTPNotSupportedError
SMTPUTF8
は mail_options で指定されましたが、サーバーではサポートされていません。
特に明記されていない限り、例外が発生した後でも接続は開かれます。
バージョン3.2で変更: msg はバイト文字列である可能性があります。
バージョン3.5で変更:
SMTPUTF8
のサポートが追加され、SMTPUTF8
が指定されているがサーバーがサポートしていない場合、 SMTPNotSupportedError が発生する可能性があります。
- SMTP.send_message(msg, from_addr=None, to_addrs=None, mail_options=(), rcpt_options=())
これは、 email.message.Message オブジェクトで表されるメッセージを使用して sendmail()を呼び出すための便利なメソッドです。 引数は、 msg が
Message
オブジェクトであることを除いて、 sendmail()と同じ意味を持ちます。from_addr が
None
であるか、 to_addrs がNone
である場合、send_message
はそれらの引数をのヘッダーから抽出されたアドレスで埋めます。 RFC 5322 で指定されているmsg : from_addr は、 Sender フィールドが存在する場合は設定され、それ以外の場合は From フィールド。 to_addrs は、 msg の To 、 Cc 、および Bcc フィールドの値(存在する場合)を組み合わせます。 Resent- * ヘッダーのセットが1つだけメッセージに表示されている場合、通常のヘッダーは無視され、代わりに Resent-* ヘッダーが使用されます。 メッセージに複数の Resent- * ヘッダーのセットが含まれている場合、 Resent- [の最新のセットを明確に検出する方法がないため、 ValueError が発生します。 X190X]ヘッダー。send_message
は、 BytesGenerator と\r\n
を linesep として使用して、 msg をシリアル化し、 sendmail()を呼び出します。結果のメッセージを送信します。 from_addr および to_addrs の値に関係なく、send_message
は Bcc または Resent-Bcc ヘッダーを送信しません。 msg に表示される場合があります。 from_addr および to_addrs のアドレスのいずれかに非ASCII文字が含まれていて、サーバーがSMTPUTF8
サポートをアドバタイズしない場合、SMTPNotSupported
エラーが発生します。 それ以外の場合、Message
は、 utf8 属性がTrue
、SMTPUTF8
に設定されたポリシーのクローンでシリアル化されます。 X153X] が mail_options に追加されました。バージョン3.2の新機能。
バージョン3.5の新機能:国際化されたアドレスのサポート(
SMTPUTF8
)。
- SMTP.quit()
- SMTPセッションを終了し、接続を閉じます。 SMTP
QUIT
コマンドの結果を返します。
標準のSMTP / ESMTPコマンドHELP
、RSET
、NOOP
、MAIL
、RCPT
、およびDATA
もサポートされています。 通常、これらを直接呼び出す必要はないため、ここでは説明しません。 詳細については、モジュールコードを参照してください。
SMTPの例
この例では、メッセージエンベロープに必要なアドレス(「宛先」および「差出人」アドレス)と、配信するメッセージの入力をユーザーに求めます。 メッセージに含まれるヘッダーは、入力されたメッセージに含まれている必要があることに注意してください。 この例では、 RFC 822 ヘッダーの処理は行われません。 特に、「To」および「From」アドレスは、メッセージヘッダーに明示的に含める必要があります。
import smtplib
def prompt(prompt):
return input(prompt).strip()
fromaddr = prompt("From: ")
toaddrs = prompt("To: ").split()
print("Enter message, end with ^D (Unix) or ^Z (Windows):")
# Add the From: and To: headers at the start!
msg = ("From: %s\r\nTo: %s\r\n\r\n"
% (fromaddr, ", ".join(toaddrs)))
while True:
try:
line = input()
except EOFError:
break
if not line:
break
msg = msg + line
print("Message length is", len(msg))
server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()