目次

前のトピックへ

20.11. nntplib — NNTP プロトコルクライアント

次のトピックへ

20.13. smtpd — SMTP サーバー

このページ

20.12. smtplib — SMTP プロトコルクライアント

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

class smtplib.SMTP([host[, port[, local_hostname[, timeout]]]])

SMTP インスタンスはSMTPコネクションをカプセル化し、 SMTPとESMTPの命令をサポートをします。オプションであるhostとportを与えた場合は、 SMTPクラスのインスタンスが作成されると同時に、 connect() メソッドを呼び出し初期化されます。また、ホストから応答が無い場合は、 SMTPConnectError が上げられます。オプションの timeout 引数を与える場合、コネクションの接続時などのブロックする操作におけるタイムアウト時間を秒数で設定します。(指定されなかった場合は、グローバルのデフォルトタイムアウト設定が利用されます)

普通に使う場合は、初期化と接続を行ってから、 sendmail() と quit() メソッドを呼びます。使用例は先の方で記載しています。

バージョン 2.6 で変更: timeout が追加されました

class smtplib.SMTP_SSL([host[, port[, local_hostname[, keyfile[, certfile[, timeout]]]]]])

SMTP_SSL のインスタンスは SMTP のインスタンスと全く同じように動作します。 SMTP_SSL は、接続の最初の段階からSSLが要求され、 starttls() では対応できない場合にのみ利用されるべきです。 host が指定されなかった場合は、localhostが利用されます。 port が指定されなかった場合は、標準の SMTP-over-SSL ポート(465) が利用されます。 keyfile と certfile もオプションで、SSL接続のための、PEMフォーマットのプライベートキーと、証明パス(certificate chain)ファイルを指定することができます。オプションの timeout 引数を与える場合、コネクションの接続時などのブロックする操作におけるタイムアウト時間を秒数で設定します。(指定されなかった場合は、グローバルのデフォルトタイムアウト設定が利用されます)

バージョン 2.6 で追加.

class smtplib.LMTP([host[, port[, local_hostname]]])

ESMTPに非常に似ているLMTPプロトコルは、SMTPクライアントに基づいています。 LMTPにはよくUnixソケットが利用されるので、 connect() メソッドは通常の host:port サーバーと同じようにUnixソケットもサポートしています。 Unixソケットを指定するには、 host 引数に、 ‘/’ で始まる絶対パスを指定します。

認証は、通常のSMTP機構を利用してサポートされています。 Unixソケットを利用する場合、LMTPは通常認証をサポートしたり要求したりはしません。しかし、あなたが必要であれば、利用することができます。

バージョン 2.6 で追加.

このモジュールの例外には次のものがあります:

exception smtplib.SMTPException

このモジュールの例外クラスのベースクラスです。

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.SMTPAuthenticationError

SMTP 認証が失敗しました。最もあり得る可能性は、サーバーがユーザ名/パスワードのペアを受付なかった事です。

参考

RFC 821 - Simple Mail Transfer Protocol
SMTP のプロトコル定義です。このドキュメントでは SMTP のモデル、操作手順、プロトコルの詳細についてカバーしています。
RFC 1869 - SMTP Service Extensions
SMTP に対する ESMTP 拡張の定義です。このドキュメントでは、新たな命令による SMTP の拡張、サーバによって提供される命令を動的に発見する機能のサポート、およびいくつかの追加命令定義について記述しています。

20.12.1. SMTP オブジェクト

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

SMTP.set_debuglevel(level)

コネクション間でやりとりされるメッセージ出力のレベルをセットします。メッセージの冗長さは level に応じて決まります。

SMTP.connect([host[, port]])

ホスト名とポート番号をもとに接続します。デフォルトはlocalhostの標準的なSMTPポート(25番)に接続します。もしホスト名の末尾がコロン(':')で、後に番号がついている場合は、「ホスト名:ポート番号」として扱われます。このメソッドはコンストラクタにホスト名及びポート番号が指定されている場合、自動的に呼び出されます。

SMTP.docmd(cmd[, argstring])

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

通常、この命令を明示的に使う必要はありませんが、自分で拡張するする時に使用するときに役立つかもしれません。

応答待ちのときに、サーバへのコネクションが失われると、 SMTPServerDisconnected が上がります。

SMTP.helo([hostname])

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

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

SMTP.ehlo([hostname])

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()

このメソッドは、現在のセッションでまだ EHLO か HELO コマンドが実行されていない場合、 ehlo() and/or helo() メソッドを呼び出します。このメソッドは先に ESMTP EHLO を試します。

SMTPHeloError
サーバーが HELO に正しく返事しなかった.

バージョン 2.6 で追加.

SMTP.has_extn(name)

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

SMTP.verify(address)

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

ノート

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

SMTP.login(user, password)

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

SMTPHeloError
サーバが HELO に返答できなかった。
SMTPAuthenticationError
サーバがユーザ名/パスワードでの認証に失敗した。
SMTPException
どんな認証方法も見付からなかった。
SMTP.starttls([keyfile[, certfile]])

TLS(Transport Layer Security)モードでSMTPコネクションを出し、全てのSMTPコマンドは暗号化されます。これは ehlo() をもう一度呼びだすときにするべきです。

keyfile と certfile が提供された場合に、 socket モジュールの ssl() 関数が通るようになります。

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

バージョン 2.6 で変更.

SMTPHeloError
サーバーが HELO に正しく返事しなかった
SMTPException
サーバーが STARTTLS 拡張に対応していない

バージョン 2.6 で変更.

RuntimeError
実行中の Python インタプリタで、 SSL/TLS サポートが利用できない
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 引数を使い、メッセージのエンベロープを構成します。 SMTP はメッセージヘッダを修正しません。

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

このメソッドは最低でも1つの受信者にメールが受け入れられたときは普通に戻りますが、そうでない場合は例外を投げます。このメソッドが例外を投げられなければ、誰かが送信したメールを得るべきです。また、例外を投げれなかった場合は、拒絶された受取人ごとへの1つのエントリーと共に、辞書を返します。各エントリーは、サーバーによって送られたSMTPエラーコードおよびエラーメッセージのタプルを含んでいます。

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

SMTPRecipientsRefused
全ての受信を拒否され、誰にもメールが届けられませんでした。例外オブジェクトの recipients 属性は、受信拒否についての情報の入った辞書オブジェクトです。 (辞書は少なくとも一つは受信されたときに似ています)。
SMTPHeloError
サーバが HELP に返答しませんでした。
SMTPSenderRefused
サーバが from_addr を弾きました。
SMTPDataError
サーバが予期しないエラーコードを返しました。(受信拒否以外)

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

SMTP.quit()

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

バージョン 2.6 で変更: 結果を返すようになりました

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

20.12.2. SMTP 使用例

次の例は最低限必要なメールアドレス(‘To’ と ‘From’)を含んだメッセージを送信するものです。この例では RFC 822 ヘッダの加工もしていません。メッセージに含まれるヘッダは、メッセージに含まれる必要があり、特に、明確な’To’、と’From’アドレスはメッセージヘッダに含まれている必要があります。

import smtplib
import string

def prompt(prompt):
    return raw_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 1:
    try:
        line = raw_input()
    except EOFError:
        break
    if not line:
        break
    msg = msg + line

print "Message length is " + repr(len(msg))

server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()

ノート

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