# `imaplib` --- IMAP4 プロトコルクライアント

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

このモジュールでは三つのクラス、 `IMAP4`, `IMAP4_SSL` と `IMAP4_stream` を定義します。これらのクラスは IMAP4 サーバへの接続をカプセル化し、 RFC 2060 に定義されている IMAP4rev1 クライアントプロトコルの大規模なサブセットを実装しています。このクラスは IMAP4 (RFC 1730) 準拠のサーバと後方互換性がありますが、 `STATUS` コマンドは IMAP4 ではサポートされていないので注意してください。

Availability: not WASI.

このモジュールは WebAssembly では動作しないか、利用不可です。詳しくは、WebAssembly プラットフォーム を見てください。

Three classes are provided by the `imaplib` module, `IMAP4` is the base class:

class imaplib.IMAP4(host='', port=IMAP4_PORT, timeout=None)

  This class implements the actual IMAP4 protocol. The connection is created and protocol version (IMAP4 or IMAP4rev1) is determined when the instance is initialized. If host is not specified, `''` (the local host) is used. If port is omitted, the standard IMAP4 port (143) is used. The optional timeout parameter specifies a timeout in seconds for the connection attempt. If timeout is not given or is `None`, the global default socket timeout is used.

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

      >>> from imaplib import IMAP4
      >>> with IMAP4("domain.org") as M:
      ...     M.noop()
      ...
      ('OK', [b'Nothing Accomplished. d25if65hy903weo.87'])

  バージョン 3.5 で変更: `with` 構文のサポートが追加されました。

  バージョン 3.9 で変更: オプションの timeout 引数が追加されました。

例外は `IMAP4` クラスの属性として定義されています:

exception IMAP4.error

  何らかのエラー発生の際に送出される例外です。例外の理由は文字列としてコンストラクタに渡されます。

exception IMAP4.abort

  IMAP4 サーバのエラーが生じると、この例外が送出されます。この例外は `IMAP4.error` のサブクラスです。通常、インスタンスを閉じ、新たなインスタンスを再び生成することで、この例外から復旧できます。

exception IMAP4.readonly

  この例外は書き込み可能なメールボックスの状態がサーバによって変更された際に送出されます。この例外は `IMAP4.error` のサブクラスです。他の何らかのクライアントが現在書き込み権限を獲得しており、メールボックスを開きなおして書き込み権限を再獲得する必要があります。

このモジュールではもう一つ、安全 (secure) な接続を使ったサブクラスがあります:

class imaplib.IMAP4_SSL(host='', port=IMAP4_SSL_PORT, *, ssl_context=None, timeout=None)

  This is a subclass derived from `IMAP4` that connects over an SSL encrypted socket (to use this class you need a socket module that was compiled with SSL support). If host is not specified, `''` (the local host) is used. If port is omitted, the standard IMAP4-over-SSL port (993) is used. ssl_context is a `ssl.SSLContext` object which allows bundling SSL configuration options, certificates and private keys into a single (potentially long-lived) structure. Please read セキュリティで考慮すべき点 for best practices.

  The optional timeout parameter specifies a timeout in seconds for the connection attempt. If timeout is not given or is `None`, the global default socket timeout is used.

  バージョン 3.3 で変更: ssl_context 引数が追加されました。

  バージョン 3.4 で変更: このクラスは `ssl.SSLContext.check_hostname` と Server Name Indication でホスト名のチェックをサポートしました。(`ssl.HAS_SNI` を参照してください)。

  バージョン 3.9 で変更: オプションの timeout 引数が追加されました。

  バージョン 3.12 で変更: 非推奨の keyfile と certfile 引数を削除しました。

さらにもう一つのサブクラスは、子プロセスで確立した接続を使用する場合に使用します:

class imaplib.IMAP4_stream(command)

  `IMAP4` から派生したサブクラスで、 command を `subprocess.Popen()` に渡して作成される `stdin/stdout` ディスクリプタと接続します。

以下のユーティリティ関数が定義されています:

imaplib.Internaldate2tuple(datestr)

  IMAP4 の `INTERNALDATE` 文字列を解析してそれに相当するローカルタイムを返します。戻り値は `time.struct_time` のタプルか、文字列のフォーマットが不正な場合は `None` です。

imaplib.Int2AP(num)

  整数を [`A` .. `P`] からなる文字集合を用いて表現した bytes に変換します。

imaplib.ParseFlags(flagstr)

  IMAP4 `FLAGS` 応答を個々のフラグからなるタプルに変換します。

imaplib.Time2Internaldate(date_time)

  Convert date_time to an IMAP4 `INTERNALDATE` representation. The return value is a string in the form: `"DD-Mmm-YYYY HH:MM:SS +HHMM"` (including double-quotes). The date_time argument can be a number (int or float) representing seconds since epoch (as returned by `time.time()`), a 9-tuple representing local time an instance of `time.struct_time` (as returned by `time.localtime()`), an aware instance of `datetime.datetime`, or a double-quoted string. In the last case, it is assumed to already be in the correct format.

IMAP4 メッセージ番号は、メールボックスに対する変更が行われた後には変化します; 特に、`EXPUNGE` 命令はメッセージの削除を行いますが、残ったメッセージには再度番号を振りなおします。従って、メッセージ番号ではなく、UID 命令を使い、その UID を利用するよう強く勧めます。

モジュールの末尾に、より拡張的な使用例が収められたテストセクションがあります。

参考

Documents describing the protocol, sources for servers implementing it, by the University of Washington's IMAP Information Center can all be found at (Source Code) https://github.com/uw-imap/imap (Not Maintained).

## IMAP4 オブジェクト

All IMAP4rev1 commands are represented by methods of the same name, either uppercase or lowercase.

命令に対する引数は全て文字列に変換されます。例外は `AUTHENTICATE` の引数と `APPEND` の最後の引数で、これは IMAP4 リテラルとして渡されます。必要に応じて (IMAP4 プロトコルが感知対象としている文字が文字列に入っており、かつ丸括弧か二重引用符で囲われていなかった場合) 文字列はクオートされます。しかし、`LOGIN` 命令の password 引数は常にクオートされます。文字列がクオートされないようにしたい (例えば `STORE` 命令の flags 引数) 場合、文字列を丸括弧で囲んでください (例: `r'(\Deleted)'`)。

Most commands return a tuple: `(type, [data, ...])` where type is usually `'OK'` or `'NO'`, and data is either the text from the command response, or mandated results from the command. Each data is either a `bytes`, or a tuple. If a tuple, then the first part is the header of the response, and the second part contains the data (ie: 'literal' value).

以下のコマンドにおける message_set オプションは、操作の対象となるひとつあるいは複数のメッセージを指す文字列です。単一のメッセージ番号 (`'1'`) かメッセージ番号の範囲 (`'2:4'`)、あるいは連続していないメッセージをカンマでつなげたもの (`'1:3,6:9'`) となります。範囲指定でアスタリスクを使用すると、上限を無限とすることができます (`'3:*'`)。

`IMAP4` のインスタンスは以下のメソッドを持っています:

IMAP4.append(mailbox, flags, date_time, message)

  指定された名前のメールボックスに message を追加します。

IMAP4.authenticate(mechanism, authobject)

  認証命令です --- 応答の処理が必要です。

  mechanism は利用する認証メカニズムを与えます。認証メカニズムはインスタンス変数 `capabilities` の中に `AUTH=mechanism` という形式で現れる必要があります。

  authobject は呼び出し可能なオブジェクトである必要があります:

      data = authobject(response)

  It will be called to process server continuation responses; the response argument it is passed will be `bytes`. It should return `bytes` data that will be base64 encoded and sent to the server. It should return `None` if the client abort response `*` should be sent instead.

  バージョン 3.5 で変更: string usernames and passwords are now encoded to `utf-8` instead of being limited to ASCII.

IMAP4.check()

  サーバ上のメールボックスにチェックポイントを設定します。

IMAP4.close()

  現在選択されているメールボックスを閉じます。削除されたメッセージは書き込み可能メールボックスから除去されます。`LOGOUT` 前に実行することを勧めます。

IMAP4.copy(message_set, new_mailbox)

  message_set で指定したメッセージ群を new_mailbox の末尾にコピーします。

IMAP4.create(mailbox)

  mailbox と名づけられた新たなメールボックスを生成します。

IMAP4.delete(mailbox)

  mailbox と名づけられた古いメールボックスを削除します。

IMAP4.deleteacl(mailbox, who)

  mailbox における who についてのACLを削除(権限を削除)します。

IMAP4.enable(capability)

  Enable capability (see RFC 5161). Most capabilities do not need to be enabled. Currently only the `UTF8=ACCEPT` capability is supported (see RFC 6855).

  Added in version 3.5: The `enable()` method itself, and RFC 6855 support.

IMAP4.expunge()

  選択されたメールボックスから削除された要素を永久に除去します。各々の削除されたメッセージに対して、`EXPUNGE` 応答を生成します。返されるデータには `EXPUNGE` メッセージ番号を受信した順番に並べたリストが入っています。

IMAP4.fetch(message_set, message_parts)

  メッセージ (の一部) を取りよせます。message_parts はメッセージパートの名前を表す文字列を丸括弧で囲ったもので、例えば: `"(UID BODY[TEXT])"` のようになります。返されるデータはメッセージパートのエンベロープ情報とデータからなるタプルです。

IMAP4.getacl(mailbox)

  mailbox に対する `ACL` を取得します。このメソッドは非標準ですが、`Cyrus` サーバでサポートされています。

IMAP4.getannotation(mailbox, entry, attribute)

  mailbox に対する `ANNOTATION` を取得します。このメソッドは非標準ですが、`Cyrus` サーバでサポートされています。

IMAP4.getquota(root)

  `quota` root により、リソース使用状況と制限値を取得します。このメソッドは RFC 2087 で定義されている IMAP4 QUOTA 拡張の一部です。

IMAP4.getquotaroot(mailbox)

  mailbox に対して `quota` root を実行した結果のリストを取得します。このメソッドは RFC 2087 で定義されている IMAP4 QUOTA 拡張の一部です。

IMAP4.idle(duration=None)

  Return an `Idler`: an iterable context manager implementing the IMAP4 `IDLE` command as defined in RFC 2177.

  The returned object sends the `IDLE` command when activated by the `with` statement, produces IMAP untagged responses via the iterator protocol, and sends `DONE` upon context exit.

  All untagged responses that arrive after sending the `IDLE` command (including any that arrive before the server acknowledges the command) will be available via iteration. Any leftover responses (those not iterated in the `with` context) can be retrieved in the usual way after `IDLE` ends, using `IMAP4.response()`.

  Responses are represented as `(type, [data, ...])` tuples, as described in IMAP4 Objects.

  The duration argument sets a maximum duration (in seconds) to keep idling, after which any ongoing iteration will stop. It can be an `int` or `float`, or `None` for no time limit. Callers wishing to avoid inactivity timeouts on servers that impose them should keep this at most 29 minutes (1740 seconds). Requires a socket connection; duration must be `None` on `IMAP4_stream` connections.

      >>> with M.idle(duration=29 * 60) as idler:
      ...     for typ, data in idler:
      ...         print(typ, data)
      ...
      EXISTS [b'1']
      RECENT [b'1']

  Idler.burst(interval=0.1)

    Yield a burst of responses no more than interval seconds apart (expressed as an `int` or `float`).

    This generator is an alternative to iterating one response at a time, intended to aid in efficient batch processing. It retrieves the next response along with any immediately available subsequent responses. (For example, a rapid series of `EXPUNGE` responses after a bulk delete.)

    Requires a socket connection; does not work on `IMAP4_stream` connections.

        >>> with M.idle() as idler:
        ...     # get a response and any others following by < 0.1 seconds
        ...     batch = list(idler.burst())
        ...     print(f'processing {len(batch)} responses...')
        ...     print(batch)
        ...
        processing 3 responses...
        [('EXPUNGE', [b'2']), ('EXPUNGE', [b'1']), ('RECENT', [b'0'])]

    Tip

    The `IDLE` context's maximum duration, as passed to `IMAP4.idle()`, is respected when waiting for the first response in a burst. Therefore, an expired `Idler` will cause this generator to return immediately without producing anything. Callers should consider this if using it in a loop.

  注釈

  The iterator returned by `IMAP4.idle()` is usable only within a `with` statement. Before or after that context, unsolicited responses are collected internally whenever a command finishes, and can be retrieved with `IMAP4.response()`.

  注釈

  The `Idler` class name and structure are internal interfaces, subject to change. Calling code can rely on its context management, iteration, and public method to remain stable, but should not subclass, instantiate, compare, or otherwise directly reference the class.

  Added in version 3.14.

IMAP4.list([directory[, pattern]])

  pattern にマッチする directory メールボックス名を列挙します。directory の標準の設定値は最上レベルのメールフォルダで、pattern は標準の設定では全てにマッチします。返されるデータには `LIST` 応答のリストが入っています。

IMAP4.login(user, password)

  平文パスワードを使ってクライアントを照合します。password はクオートされます。

IMAP4.login_cram_md5(user, password)

  パスワードの保護のため、クライアント認証時に `CRAM-MD5` だけを使用します。これは、`CAPABILITY` レスポンスに `AUTH=CRAM-MD5` が含まれる場合のみ有効です。

  バージョン 3.15 で変更: An `IMAP4.error` is raised if MD5 support is not available.

IMAP4.logout()

  サーバへの接続を遮断します。サーバからの `BYE` 応答を返します。

  バージョン 3.8 で変更: The method no longer ignores silently arbitrary exceptions.

IMAP4.lsub(directory='""', pattern='*')

  購読しているメールボックス名のうち、ディレクトリ内でパターンにマッチするものを列挙します。directory の標準の設定値は最上レベルのメールフォルダで、pattern は標準の設定では全てにマッチします。返されるデータには返されるデータはメッセージパートエンベロープ情報とデータからなるタプルです。

IMAP4.myrights(mailbox)

  mailboxにおける自分のACLを返します (すなわち自分がmailboxで持っている権限を返します)。

IMAP4.namespace()

  RFC 2342 で定義されるIMAP名前空間を返します。

IMAP4.noop()

  サーバに `NOOP` を送信します。

IMAP4.open(host, port, timeout=None)

  Opens socket to port at host. The optional timeout parameter specifies a timeout in seconds for the connection attempt. If timeout is not given or is `None`, the global default socket timeout is used. Also note that if the timeout parameter is set to be zero, it will raise a `ValueError` to reject creating a non-blocking socket. This method is implicitly called by the `IMAP4` constructor. The connection objects established by this method will be used in the `IMAP4.read()`, `IMAP4.readline()`, `IMAP4.send()`, and `IMAP4.shutdown()` methods. You may override this method.

  引数 `self`, `host`, `port` を指定して 監査イベント `imaplib.open` を送出します。

  バージョン 3.9 で変更: timeout 引数が追加されました。

IMAP4.partial(message_num, message_part, start, length)

  メッセージの後略された部分を取り寄せます。返されるデータはメッセージパートエンベロープ情報とデータからなるタプルです。

IMAP4.proxyauth(user)

  user として認証されたものとします。認証された管理者がユーザの代理としてメールボックスにアクセスする際に使用します。

IMAP4.read(size)

  遠隔のサーバから size バイト読み出します。このメソッドはオーバライドすることができます。

IMAP4.readline()

  遠隔のサーバから一行読み出します。このメソッドはオーバライドすることができます。

IMAP4.recent()

  サーバに更新を促します。新たなメッセージがない場合応答は `None` になり、そうでない場合 `RECENT` 応答の値になります。

IMAP4.rename(oldmailbox, newmailbox)

  oldmailbox という名前のメールボックスを newmailbox に名称変更します。

IMAP4.response(code)

  応答 code を受信していれば、そのデータを返し、そうでなければ `None` を返します。通常の形式 (usual type) ではなく指定したコードを返します。

IMAP4.search(charset, criterion[, ...])

  Search mailbox for matching messages. charset may be `None`, in which case no `CHARSET` will be specified in the request to the server. The IMAP protocol requires that at least one criterion be specified; an exception will be raised when the server returns an error. charset must be `None` if the `UTF8=ACCEPT` capability was enabled using the `enable()` command.

  以下はプログラム例です:

      # M is a connected IMAP4 instance...
      typ, msgnums = M.search(None, 'FROM', '"LDJ"')

      # or:
      typ, msgnums = M.search(None, '(FROM "LDJ")')

IMAP4.select(mailbox='INBOX', readonly=False)

  メールボックスを選択します。返されるデータは mailbox 内のメッセージ数 (`EXISTS` 応答) です。標準の設定では mailbox は `'INBOX'` です。readonly が設定された場合、メールボックスに対する変更はできません。

IMAP4.send(data)

  遠隔のサーバに `data` を送信します。このメソッドはオーバライドすることができます。

  引数 `self`, `data` を指定して 監査イベント `imaplib.send` を送出します。

IMAP4.setacl(mailbox, who, what)

  `ACL` を mailbox に設定します。このメソッドは非標準ですが、`Cyrus` サーバでサポートされています。

IMAP4.setannotation(mailbox, entry, attribute[, ...])

  `ANNOTATION` を mailbox に設定します。このメソッドは非標準ですが、`Cyrus` サーバでサポートされています。

IMAP4.setquota(root, limits)

  `quota` root のリソースを limits に設定します。このメソッドは RFC 2087 で定義されている IMAP4 QUOTA 拡張の一部です。

IMAP4.shutdown()

  `open` で確立された接続を閉じます。 `IMAP4.logout()` は暗黙的にこのメソッドを呼び出します。このメソッドはオーバライドすることができます。

IMAP4.socket()

  サーバへの接続に使われているソケットインスタンスを返します。

IMAP4.sort(sort_criteria, charset, search_criterion[, ...])

  `sort` 命令は `search` に結果の並べ替え (sort) 機能をつけた変種です。返されるデータには、条件に合致するメッセージ番号をスペースで分割したリストが入っています。

  sort 命令は search_criterion の前に二つの引数を持ちます; sort_criteria のリストを丸括弧で囲ったものと、検索時の charset です。`search` と違って、検索時の charset は必須です。`uid sort` 命令もあり、`search` に対する `uid search` と同じように `sort` 命令に対応します。`sort` 命令はまず、charset 引数の指定に従って searching criteria の文字列を解釈し、メールボックスから与えられた検索条件に合致するメッセージを探します。次に、合致したメッセージの数を返します。

  `IMAP4rev1` 拡張命令です。

IMAP4.starttls(ssl_context=None)

  Send a `STARTTLS` command. The ssl_context argument is optional and should be a `ssl.SSLContext` object. This will enable encryption on the IMAP connection. Please read セキュリティで考慮すべき点 for best practices.

  Added in version 3.2.

  バージョン 3.4 で変更: The method now supports hostname check with `ssl.SSLContext.check_hostname` and Server Name Indication (see `ssl.HAS_SNI`).

IMAP4.status(mailbox, names)

  mailbox の指定ステータス名の状態情報を要求します。

IMAP4.store(message_set, command, flag_list)

  メールボックス内のメッセージ群のフラグ設定を変更します。 command は RFC 2060 のセクション 6.4.6 で指定されているもので、 "FLAGS", "+FLAGS", あるいは "-FLAGS" のいずれかとなります。オプションで末尾に ".SILENT" がつくこともあります。

  たとえば、すべてのメッセージに削除フラグを設定するには次のようにします:

      typ, data = M.search(None, 'ALL')
      for num in data[0].split():
         M.store(num, '+FLAGS', '\\Deleted')
      M.expunge()

  注釈

  Creating flags containing ']' (for example: "[test]") violates RFC 3501 (the IMAP protocol). However, imaplib has historically allowed creation of such tags, and popular IMAP servers, such as Gmail, accept and produce such flags. There are non-Python programs which also create such tags. Although it is an RFC violation and IMAP clients and servers are supposed to be strict, imaplib still continues to allow such tags to be created for backward compatibility reasons, and as of Python 3.6, handles them if they are sent from the server, since this improves real-world compatibility.

IMAP4.subscribe(mailbox)

  新たなメールボックスを購読 (subscribe) します。

IMAP4.thread(threading_algorithm, charset, search_criterion[, ...])

  `thread` コマンドは `search` にスレッドの概念を加えた変形版です。返されるデータは空白で区切られたスレッドメンバのリストを含んでいます。

  各スレッドメンバは0以上のメッセージ番号からなり、空白で区切られており、親子関係を示しています。

  Thread has two arguments before the search_criterion argument(s); a threading_algorithm, and the searching charset. Note that unlike `search`, the searching charset argument is mandatory. There is also a `uid thread` command which corresponds to `thread` the way that `uid search` corresponds to `search`. The `thread` command first searches the mailbox for messages that match the given searching criteria using the charset argument for the interpretation of strings in the searching criteria. It then returns the matching messages threaded according to the specified threading algorithm.

  `IMAP4rev1` 拡張命令です。

IMAP4.uid(command, arg[, ...])

  command args を、メッセージ番号ではなく UID で指定されたメッセージ群に対して実行します。命令内容に応じた応答を返します。少なくとも一つの引数を与えなくてはなりません; 何も与えない場合、サーバはエラーを返し、例外が送出されます。

IMAP4.unsubscribe(mailbox)

  古いメールボックスの購読を解除 (unsubscribe) します。

IMAP4.unselect()

  `imaplib.IMAP4.unselect()` frees server's resources associated with the selected mailbox and returns the server to the authenticated state. This command performs the same actions as `imaplib.IMAP4.close()`, except that no messages are permanently removed from the currently selected mailbox.

  Added in version 3.9.

IMAP4.xatom(name[, ...])

  サーバから `CAPABILITY` 応答で通知された単純な拡張命令を許容 (allow) します。

以下の属性が `IMAP4` のインスタンス上で定義されています:

IMAP4.PROTOCOL_VERSION

  サーバから返された `CAPABILITY` 応答にある、サポートされている最新のプロトコルです。

IMAP4.debug

  デバッグ出力を制御するための整数値です。初期値はモジュール変数 `Debug` から取られます。3 以上の値にすると各命令をトレースします。

IMAP4.utf8_enabled

  Boolean value that is normally `False`, but is set to `True` if an `enable()` command is successfully issued for the `UTF8=ACCEPT` capability.

  Added in version 3.5.

## IMAP4 の使用例

以下にメールボックスを開き、全てのメッセージを取得して印刷する最小の (エラーチェックをしない) 使用例を示します:

    import getpass, imaplib

    M = imaplib.IMAP4(host='example.org')
    M.login(getpass.getuser(), getpass.getpass())
    M.select()
    typ, data = M.search(None, 'ALL')
    for num in data[0].split():
        typ, data = M.fetch(num, '(RFC822)')
        print('Message %s\n%s\n' % (num, data[0][1]))
    M.close()
    M.logout()