# 21.17. `smtplib` --- SMTP プロトコルクライアント

ソースコード: Lib/smtplib.py

`smtplib` モジュールは、SMTPまたはESMTPのリスナーデーモンを備えた任意のインターネット上のホストにメールを送るために使用することができる SMTPクライアント・セッション・オブジェクトを定義します。 SMTPおよびESMTPオペレーションの詳細は、 RFC 821 (Simple Mail Transfer Protocol) や RFC 1869 (SMTP Service Extensions)を調べてください。

class `smtplib.``SMTP`(host='', port=0, local_hostname=None, [timeout, ]source_address=None)

  `SMTP` インスタンスはSMTP接続をカプセル化します。SMTPとESMTP操作の完全なレパートリーをサポートするメソッドがあります。オプションパラメータのhostおよびportが指定されている場合、SMTPの `connect()` メソッドは初期化中にこれらのパラメータを使って呼び出されます。 local_hostname を指定した場合、それはHELO/EHLOコマンドのローカルホストのFQDNとして使用されます。指定しない場合、ローカルホスト名は `socket.getfqdn()` を使用して検索されます。 `connect()` 呼び出しが成功コード以外を返すと、 `SMTPConnectError` が送出されます。オプションの timeout パラメータは、接続試行のようなブロッキング操作のタイムアウトを秒単位で指定します（指定されていない場合、グローバルなデフォルトのタイムアウト設定が使用されます）。タイムアウトが切れると、 `socket.timeout` が送出されます。オプションのsource_addressパラメータを使用すると、複数のネットワークインターフェイスを持つマシンの特定の送信元アドレス、かつ（または）特定の送信元TCPポートにバインドできます。接続する前にソケットを送信元アドレスとしてバインドするためにタプル(host, port)が必要です。省略された場合（あるいは、hostまたはportがそれぞれ `''` かつ/または0の場合）、OSのデフォルト動作が使用されます。

  For normal use, you should only require the initialization/connect, `sendmail()`, and `SMTP.quit()` methods. An example is included below.

  The `SMTP` class supports the `with` statement. When used like this, the SMTP `QUIT` command is issued automatically when the `with` statement exits. E.g.:

      >>> 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 が0の場合、標準のSMTP-over-SSLポート（465）が使用されます。オプション引数 local_hostname, timeout, source_address は `SMTP` クラスと同じ意味を持ちます。 context オプションは `SSLContext` を含むことができ、安全な接続のさまざまな側面を設定することができます。ベストプラクティスについては セキュリティで考慮すべき点 を読んでください。

  keyfile and certfile are a legacy alternative to context, and can point to a PEM formatted private key and certificate chain file for the SSL connection.

  バージョン 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)

  The LMTP protocol, which is very similar to ESMTP, is heavily based on the standard SMTP client. It's common to use Unix sockets for LMTP, so our `connect()` method must support that as well as a regular host:port server. The optional arguments local_hostname and source_address have the same meaning as they do in the `SMTP` class. To specify a Unix socket, you must use an absolute path for host, starting with a '/'.

  認証は、通常の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 - Simple Mail Transfer Protocol

  SMTP のプロトコル定義です。このドキュメントでは SMTP のモデル、操作手順、プロトコルの詳細についてカバーしています。

RFC 1869 - SMTP Service Extensions

  SMTP に対する ESMTP 拡張の定義です。このドキュメントでは、新たな命令による SMTP の拡張、サーバによって提供される命令を動的に発見する機能のサポート、およびいくつかの追加命令定義について記述しています。

## 21.17.1. SMTP オブジェクト

`SMTP` クラスインスタンスは次のメソッドを提供します:

`SMTP.``set_debuglevel`(level)

  デバッグ出力レベルを設定します。level が 1 や `True` の場合、接続ならびにサーバとの送受信のメッセージがデバッグメッセージとなります。level が 2 の場合、それらのメッセージにタイムスタンプが付きます。

  バージョン 3.5 で変更: デバッグレベル2が追加されました。

`SMTP.``docmd`(cmd, args='')

  サーバへコマンド cmd を送信します。オプション引数 args はスペース文字でコマンドに連結します。戻り値は、整数値のレスポンスコードと、サーバからの応答の値をタプルで返します (サーバからの応答が数行に渡る場合でも一つの大きな文字列で返します)。

  数値応答コードと実際の応答行 (複数の応答は 1 つの長い行に結合されます) からなる 2 値タプルを返します。

  通常、このメソッドを明示的に使う必要はありません。他のメソッドを実装するのに使い、自分で拡張したものをテストするのに役立つかもしれません。

  応答待ちのときにサーバへの接続が切れると `SMTPServerDisconnected` が送出されます。

`SMTP.``connect`(host='localhost', port=0)

  ホスト名とポート番号をもとに接続します。デフォルトはlocalhostの標準的なSMTPポート(25番)に接続します。もしホスト名の末尾がコロン(`':'`)で、後に番号がついている場合は、「ホスト名:ポート番号」として扱われます。このメソッドはコンストラクタにホスト名及びポート番号が指定されている場合、自動的に呼び出されます。戻り値は、この接続の応答内でサーバによって送信された応答コードとメッセージの2要素タプルです。

`SMTP.``helo`(name='')

  SMTPサーバに `HELO` コマンドで身元を示します。デフォルトではhostname引数はローカルホストを指します。サーバーが返したメッセージは、オブジェクトの `helo_resp` 属性に格納されます。

  通常は `sendmail()` が呼びだすため、これを明示的に呼び出す必要はありません。

`SMTP.``ehlo`(name='')

  `EHLO` を利用し、ESMTPサーバに身元を明かします。デフォルトではhostname引数はローカルホストのFQDNです。また、ESMTPオプションのために応答を調べたものは、 `has_extn()` に備えて保存されます。また、幾つかの情報を属性に保存します: サーバーが返したメッセージは `ehlo_resp` 属性に、 `does_esmtp` 属性はサーバーがESMTPをサポートしているかどうかによって true か false に、 `esmtp_features` 属性は辞書で、サーバーが対応しているSMTP サービス拡張の名前と、もしあればそのパラメータを格納します。

  メールを送信する前に `has_extn()` を使おうとしない限り、このメソッドを明示的に呼ぶ必要はないはずです。必要な場合は `sendmail()` に暗黙的に呼ばれます。

`SMTP.``ehlo_or_helo_if_needed`()

  This method calls `ehlo()` and/or `helo()` if there has been no previous `EHLO` or `HELO` command this session. It tries ESMTP `EHLO` first.

  `SMTPHeloError`

    サーバーが `HELO` に正しく返答しませんでした。

`SMTP.``has_extn`(name)

  name が拡張SMTPサービスセットに含まれている場合には `True` を返し、そうでなければ `False` を返します。大小文字は区別されません。

`SMTP.``verify`(address)

  `VRFY` を利用してSMTPサーバにアドレスの妥当性をチェックします。妥当である場合はコード250と完全な RFC 822 アドレス (人名を含む) のタプルを返します。それ以外の場合は、400以上のエラーコードとエラー文字列を返します。

  注釈

  ほとんどのサイトはスパマーの裏をかくためにSMTPの `VRFY` は使用不可になっています。

`SMTP.``login`(user, password, *, initial_response_ok=True)

  認証が必要なSMTPサーバにログインします。認証に使用する引数はユーザ名とパスワードです。まだセッションが無い場合は、 `EHLO` または `HELO` コマンドでセッションを作ります。ESMTPの場合は `EHLO` が先に試されます。認証が成功した場合は通常このメソッドは戻りますが、例外が起こった場合は以下の例外が上がります:

  `SMTPHeloError`

    サーバーが `HELO` に正しく返答しませんでした。

  `SMTPAuthenticationError`

    サーバがユーザ名/パスワードでの認証に失敗しました。

  `SMTPNotSupportedError`

    `AUTH` コマンドはサーバにサポートされていません。

  `SMTPException`

    適当な認証方法が見付かりませんでした。

  Each of the authentication methods supported by `smtplib` are tried in turn if they are advertised as supported by the server. See `auth()` for a list of supported authentication methods. initial_response_ok is passed through to `auth()`.

  オプションのキーワード引数 initial_response_ok は、それをサポートする認証方法に対して、チャレンジ/レスポンスを要求するのではなく、 "AUTH"コマンドとともに RFC 4954 で指定された"初期応答"を送信できるかどうかを指定します。

  バージョン 3.5 で変更: `SMTPNotSupportedError` が送出される場合があります。initial_response_ok 引数が追加されました。

`SMTP.``auth`(mechanism, authobject, *, initial_response_ok=True)

  Issue an `SMTP` `AUTH` command for the specified authentication mechanism, and handle the challenge response via authobject.

  mechanism specifies which authentication mechanism is to be used as argument to the `AUTH` command; the valid values are those listed in the `auth` element of `esmtp_features`.

  authobject must be a callable object taking an optional single argument:

  > data = authobject(challenge=None)

  If optional keyword argument initial_response_ok is true, `authobject()` will be called first with no argument. It can return the RFC 4954 "initial response" ASCII `str` which will be encoded and sent with the `AUTH` command as below. If the `authobject()` does not support an initial response (e.g. because it requires a challenge), it should return `None` when called with `challenge=None`. If initial_response_ok is false, then `authobject()` will not be called first with `None`.

  If the initial response check returns `None`, or if initial_response_ok is false, `authobject()` will be called to process the server's challenge response; the challenge argument it is passed will be a `bytes`. It should return ASCII `str` data that will be base64 encoded and sent to the server.

  The `SMTP` class provides `authobjects` for the `CRAM-MD5`, `PLAIN`, and `LOGIN` mechanisms; they are named `SMTP.auth_cram_md5`, `SMTP.auth_plain`, and `SMTP.auth_login` respectively. They all require that the `user` and `password` properties of the `SMTP` instance are set to appropriate values.

  User code does not normally need to call `auth` directly, but can instead call the `login()` method, which will try each of the above mechanisms in turn, in the order listed. `auth` is exposed to facilitate the implementation of authentication methods not (or not yet) supported directly by `smtplib`.

  バージョン 3.5 で追加.

`SMTP.``starttls`(keyfile=None, certfile=None, context=None)

  TLS (Transport Layer Security) モードで SMTP 接続します。続く全てのSMTP コマンドは暗号化されます。その後、もう一度 `ehlo()` を呼んでください。

  If keyfile and certfile are provided, they are used to create an `ssl.SSLContext`.

  Optional context parameter is an `ssl.SSLContext` object; This is an alternative to using a keyfile and a certfile and if specified both keyfile and certfile should be `None`.

  もしまだ `EHLO` か `HELO` コマンドが実行されていない場合、このメソッドは ESMTP `EHLO` を先に試します。

  バージョン 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 で変更: The method now supports hostname check with `SSLContext.check_hostname` and Server Name Indicator (see `HAS_SNI`).

  バージョン 3.5 で変更: The error raised for lack of STARTTLS support is now the `SMTPNotSupportedError` subclass instead of the base `SMTPException`.

`SMTP.``sendmail`(from_addr, to_addrs, msg, mail_options=(), rcpt_options=())

  メールを送信します。必要な引数は RFC 822 のfromアドレス文字列、 RFC 822 のtoアドレス文字列またはアドレス文字列のリスト、メッセージ文字列です。送信側は `MAIL FROM` コマンドで使用される mail_options の ESMTPオプション(`8bitmime` のような)のリストを得るかもしれません。全ての `RCPT` コマンドで使われるべきESMTPオプション (例えば `DSN` コマンド)は、 rcpt_options を通して利用することができます。(もし送信先別にESMTPオプションを使う必要があれば、メッセージを送るために `mail()` 、 `rcpt()` 、 `data()` といった下位レベルのメソッドを使う必要があります。)

  注釈

  配送エージェントは from_addr、to_addrs 引数を使い、メッセージのエンベロープを構成します。`sendmail` はメッセージヘッダを修正しません。

  msg may be a string containing characters in the ASCII range, or a byte string. A string is encoded to bytes using the ascii codec, and lone `\r` and `\n` characters are converted to `\r\n` characters. A byte string is not modified.

  まだセッションが無い場合は、 `EHLO` または `HELO` コマンドでセッションを作ります。ESMTPの場合は `EHLO` が先に試されます。また、サーバがESMTP対応ならば、メッセージサイズとそれぞれ指定されたオプションも渡します。(featureオプションがあればサーバの広告をセットします) `EHLO` が失敗した場合は、ESMTPオプションの無い `HELO` が試されます。

  このメソッドは最低でも1人の受信者にメールが受け取られたときは正常に戻ります。そうでない場合は例外を投げます。つまり、このメソッドが例外を送出しないときは誰かが送信したメールを受け取ったはずです。また、例外を送出しない場合は拒絶された受信者ごとに項目のある辞書を返します。各項目はサーバーが送ったSMTPエラーコードと付随するエラーメッセージのタプルを持ちます。

  If `SMTPUTF8` is included in mail_options, and the server supports it, from_addr and to_addrs may contain non-ASCII characters.

  このメソッドは次の例外を送出することがあります:

  `SMTPRecipientsRefused`

    全ての受信を拒否され、誰にもメールが届けられませんでした。例外オブジェクトの `recipients` 属性は、受信拒否についての情報の入った辞書オブジェクトです。 (辞書は少なくとも一つは受信されたときに似ています)。

  `SMTPHeloError`

    サーバーが `HELO` に正しく返答しませんでした。

  `SMTPSenderRefused`

    サーバが from_addr を受理しませんでした。

  `SMTPDataError`

    サーバが予期しないエラーコードを返しました (受信拒否以外)。

  `SMTPNotSupportedError`

    mail_options に `SMTPUTF8` が与えられましたが、サーバがサポートしていません。

  また、この他の注意として、例外が上がった後もコネクションは開いたままになっています。

  バージョン 3.2 で変更: msg はバイト文字列でも構いません。

  バージョン 3.5 で変更: `SMTPUTF8` のサポートが追加されました。`SMTPUTF8` が与えられたが、サーバがサポートしていない場合は `SMTPNotSupportedError` が送出されます。

`SMTP.``send_message`(msg, from_addr=None, to_addrs=None, mail_options=(), rcpt_options=())

  This is a convenience method for calling `sendmail()` with the message represented by an `email.message.Message` object. The arguments have the same meaning as for `sendmail()`, except that msg is a `Message` object.

  If from_addr is `None` or to_addrs is `None`, `send_message` fills those arguments with addresses extracted from the headers of msg as specified in RFC 5322: from_addr is set to the Sender field if it is present, and otherwise to the From field. to_addrs combines the values (if any) of the To, Cc, and Bcc fields from msg. If exactly one set of Resent-* headers appear in the message, the regular headers are ignored and the Resent-* headers are used instead. If the message contains more than one set of Resent-* headers, a `ValueError` is raised, since there is no way to unambiguously detect the most recent set of Resent- headers.

  `send_message` serializes msg using `BytesGenerator` with `\r\n` as the linesep, and calls `sendmail()` to transmit the resulting message. Regardless of the values of from_addr and to_addrs, `send_message` does not transmit any Bcc or Resent-Bcc headers that may appear in msg. If any of the addresses in from_addr and to_addrs contain non-ASCII characters and the server does not advertise `SMTPUTF8` support, an `SMTPNotSupported` error is raised. Otherwise the `Message` is serialized with a clone of its `policy` with the `utf8` attribute set to `True`, and `SMTPUTF8` and `BODY=8BITMIME` are added to mail_options.

  バージョン 3.2 で追加.

  バージョン 3.5 で追加: 国際化アドレスのサポート (`SMTPUTF8`)。

`SMTP.``quit`()

  SMTPセッションを終了し、接続を閉じます。SMTP `QUIT` コマンドの結果を返します。

下位レベルのメソッドは標準SMTP/ESMTPコマンド `HELP` 、 `RSET` 、 `NOOP` 、 `MAIL` 、 `RCPT` 、 `DATA` に対応しています。通常これらは直接呼ぶ必要はなく、また、ドキュメントもありません。詳細はモジュールのコードを調べてください。

## 21.17.2. SMTP 使用例

次の例は最低限必要なメールアドレス('To' と 'From')を含んだメッセージを送信するものです。この例では 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()

注釈

多くの場合、 `email` パッケージの機能を使って email メッセージを構築し、それを、 `send_message()` で送信する、という手順を用います。 email: 使用例 を参照してください。