imaplib — IMAP4 协议客户端

源代码: Lib/imaplib.py


此模块定义了三个类,IMAP4IMAP4_SSLIMAP4_stream,它们封装了到 IMAP4 服务器的连接,并实现了 RFC 2060 中定义的 IMAP4rev1 客户端协议的很大一部分子集。它向后兼容 IMAP4 (RFC 1730) 服务器,但请注意 STATUS 命令在 IMAP4 中不受支持。

可用性:不是 WASI。

此模块在 WebAssembly 上不起作用或不可用。有关更多信息,请参阅 WebAssembly 平台

imaplib 模块提供了三个类,IMAP4 是基类

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

此类实现了实际的 IMAP4 协议。当实例初始化时,将创建连接并确定协议版本(IMAP4 或 IMAP4rev1)。如果未指定 host,则使用 ''(本地主机)。如果省略 port,则使用标准 IMAP4 端口 (143)。可选的 timeout 参数指定连接尝试的超时时间(以秒为单位)。如果未给定超时时间或为 None,则使用全局默认套接字超时时间。

IMAP4 类支持 with 语句。像这样使用时,当 with 语句退出时,会自动发出 IMAP4 LOGOUT 命令。例如:

>>> 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 的子类。其他一些客户端现在拥有写权限,并且需要重新打开邮箱才能重新获得写权限。

还有一个用于安全连接的子类

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

这是从 IMAP4 派生的子类,该子类通过 SSL 加密套接字进行连接(要使用此类,您需要一个使用 SSL 支持编译的套接字模块)。如果未指定 host,则使用 ''(本地主机)。如果省略 port,则使用标准 IMAP4 over SSL 端口 (993)。ssl_context 是一个 ssl.SSLContext 对象,该对象允许将 SSL 配置选项、证书和私钥捆绑到一个(可能长期存在的)结构中。请阅读 安全注意事项 以获得最佳实践。

可选的 timeout 参数指定连接尝试的超时时间(以秒为单位)。如果未给定超时时间或为 None,则使用全局默认套接字超时时间。

在 3.3 版本中更改: 添加了 ssl_context 参数。

在 3.4 版本中更改: 此类现在支持使用 ssl.SSLContext.check_hostname服务器名称指示(请参阅 ssl.HAS_SNI)进行主机名检查。

在 3.9 版本中更改: 添加了可选的 timeout 参数。

在 3.12 版本中更改: 已删除已弃用的 keyfilecertfile 参数。

第二个子类允许由子进程创建的连接

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] 中的字符将整数转换为字节表示形式。

imaplib.ParseFlags(flagstr)

将 IMAP4 FLAGS 响应转换为单个标志的元组。

imaplib.Time2Internaldate(date_time)

date_time 转换为 IMAP4 INTERNALDATE 表示形式。返回值是以下形式的字符串:"DD-Mmm-YYYY HH:MM:SS +HHMM" (包括双引号)。date_time 参数可以是表示自 epoch 以来的秒数的数字(int 或 float)(如 time.time() 返回的),一个表示本地时间的 9 元组,一个 time.struct_time 的实例(如 time.localtime() 返回的),一个 datetime.datetime 的感知实例,或者一个双引号字符串。在最后一种情况下,假定它已经是正确的格式。

请注意,IMAP4 消息编号会随着邮箱的更改而更改;特别是在 EXPUNGE 命令执行删除操作后,剩余的消息会被重新编号。因此,强烈建议使用 UID,并使用 UID 命令。

在本模块的末尾,有一个包含更广泛用法示例的测试部分。

另请参阅

描述该协议的文档,实现该协议的服务器的源代码,以及华盛顿大学的 IMAP 信息中心,都可以在(**源代码**)https://github.com/uw-imap/imap(**未维护**)找到。

IMAP4 对象

所有 IMAP4rev1 命令都由同名的方法表示,可以是全大写或全小写。

除了 AUTHENTICATE 之外,以及 APPEND 的最后一个参数(作为 IMAP4 字面量传递),命令的所有参数都将转换为字符串。如有必要(字符串包含 IMAP4 协议敏感字符,并且未用括号或双引号括起来),则每个字符串都会被引用。但是,LOGIN 命令的 password 参数始终被引用。如果要避免引用参数字符串(例如:STOREflags 参数),请将字符串括在括号中(例如:r'(\Deleted)')。

每个命令都会返回一个元组:(type, [data, ...]),其中 type 通常为 'OK''NO'data 是命令响应中的文本或命令规定的结果。每个 data 都是 bytes 或元组。如果为元组,则第一部分是响应的头部,第二部分包含数据(即“字面量”值)。

下面命令的 message_set 选项是一个字符串,用于指定要对其执行操作的一个或多个消息。它可以是简单的消息编号('1')、消息编号范围('2:4')或以逗号分隔的不连续范围组('1:3,6:9')。范围可以包含一个星号,以指示无限上限('3:*')。

IMAP4 实例具有以下方法

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

message 附加到名为 mailbox 的邮箱。

IMAP4.authenticate(mechanism, authobject)

验证命令 — 需要响应处理。

mechanism 指定要使用的身份验证机制 - 它应以 AUTH=mechanism 的形式出现在实例变量 capabilities 中。

authobject 必须是可调用对象

data = authobject(response)

将调用它来处理服务器的延续响应;传递给它的 response 参数将是 bytes。它应返回 bytes data,该 data 将被 base64 编码并发送到服务器。如果应改为发送客户端中止响应 *,则应返回 None

在 3.5 版本中更改: 字符串用户名和密码现在被编码为 utf-8,而不是被限制为 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)

删除在邮箱上为 who 设置的 ACL(删除任何权限)。

IMAP4.enable(capability)

启用capability(参见RFC 5161)。大多数功能不需要启用。目前仅支持 UTF8=ACCEPT 功能(参见RFC 6855)。

3.5 版本新增: enable() 方法本身,以及 RFC 6855 支持。

IMAP4.expunge()

从选定的邮箱中永久删除已删除的项目。为每条删除的消息生成一个 EXPUNGE 响应。返回的数据包含按接收顺序排列的 EXPUNGE 消息编号列表。

IMAP4.fetch(message_set, message_parts)

提取(部分)消息。message_parts 应该是用括号括起来的消息部分名称字符串,例如:"(UID BODY[TEXT])"。返回的数据是消息部分信封和数据的元组。

IMAP4.getacl(mailbox)

获取 mailboxACL。此方法是非标准的,但 Cyrus 服务器支持它。

IMAP4.getannotation(mailbox, entry, attribute)

检索 mailbox 的指定 ANNOTATION。此方法是非标准的,但 Cyrus 服务器支持它。

IMAP4.getquota(root)

获取 root 的资源使用情况和限制的 quota。此方法是 rfc2087 中定义的 IMAP4 QUOTA 扩展的一部分。

IMAP4.getquotaroot(mailbox)

获取名为 mailboxquota roots 列表。此方法是 rfc2087 中定义的 IMAP4 QUOTA 扩展的一部分。

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 时才有效。

IMAP4.logout()

关闭与服务器的连接。返回服务器 BYE 响应。

3.8 版本更改: 此方法不再静默忽略任意异常。

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

列出与模式匹配的目录中订阅的邮箱名称。directory 默认为顶级目录,pattern 默认为匹配任何邮箱。返回的数据是消息部分信封和数据的元组。

IMAP4.myrights(mailbox)

显示我对于邮箱的 ACL(即我在邮箱上拥有的权限)。

IMAP4.namespace()

返回 RFC 2342 中定义的 IMAP 命名空间。

IMAP4.noop()

向服务器发送 NOOP

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

hostport 打开套接字。可选的 timeout 参数指定连接尝试的超时时间(以秒为单位)。如果未给定超时或超时为 None,则使用全局默认套接字超时。另请注意,如果将 timeout 参数设置为零,它将引发 ValueError 以拒绝创建非阻塞套接字。此方法由 IMAP4 构造函数隐式调用。此方法建立的连接对象将用于 IMAP4.read()IMAP4.readline()IMAP4.send()IMAP4.shutdown() 方法。您可以覆盖此方法。

引发一个 审计事件 imaplib.open,参数为 selfhostport

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。返回给定的代码,而不是通常的类型。

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

在邮箱中搜索匹配的消息。charset 可以为 None,在这种情况下,不会在发送到服务器的请求中指定 CHARSET。IMAP 协议要求至少指定一个标准;当服务器返回错误时,将引发异常。如果使用 enable() 命令启用了 UTF8=ACCEPT 功能,则 charset 必须为 None

示例

# 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 发送到远程服务器。您可以覆盖此方法。

使用参数 selfdata 引发 审计事件 imaplib.send

IMAP4.setacl(mailbox, who, what)

mailbox 设置一个 ACL。该方法是非标准的,但 Cyrus 服务器支持它。

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

mailbox 设置 ANNOTATION。该方法是非标准的,但 Cyrus 服务器支持它。

IMAP4.setquota(root, limits)

设置 root 的资源 limitsquota。此方法是 rfc2087 中定义的 IMAP4 QUOTA 扩展的一部分。

IMAP4.shutdown()

关闭在 open 中建立的连接。此方法由 IMAP4.logout() 隐式调用。您可以覆盖此方法。

IMAP4.socket()

返回用于连接到服务器的套接字实例。

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

sort 命令是 search 的变体,对结果具有排序语义。返回的数据包含一个以空格分隔的匹配消息编号列表。

Sort 在 search_criterion 参数之前有两个参数;一个包含在括号中的 sort_criteria 列表和一个搜索 charset。请注意,与 search 不同,搜索 charset 参数是强制性的。还有一个 uid sort 命令,它对应于 sort,就像 uid search 对应于 search 一样。sort 命令首先使用字符集参数解释搜索条件中的字符串,在邮箱中搜索与给定搜索条件匹配的消息。然后返回匹配的消息编号。

这是一个 IMAP4rev1 扩展命令。

IMAP4.starttls(ssl_context=None)

发送一个 STARTTLS 命令。ssl_context 参数是可选的,应该是一个 ssl.SSLContext 对象。这将启用 IMAP 连接上的加密。请阅读 安全注意事项 以获得最佳实践。

在 3.2 版本中添加。

在 3.4 版本中更改: 此方法现在支持使用 ssl.SSLContext.check_hostname服务器名称指示 进行主机名检查(请参阅 ssl.HAS_SNI)。

IMAP4.status(mailbox, names)

请求 mailbox 的命名状态条件。

IMAP4.store(message_set, command, flag_list)

更改邮箱中消息的标志处理。commandRFC 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()

注意

创建包含“]”的标志(例如:“[test]”)违反了 RFC 3501(IMAP 协议)。但是,imaplib 在历史上一直允许创建此类标签,并且流行的 IMAP 服务器(如 Gmail)接受并生成此类标志。还有一些非 Python 程序也会创建此类标签。尽管这违反了 RFC,并且 IMAP 客户端和服务器应该严格执行,但出于向后兼容性的原因,imaplib 仍然允许创建此类标签,并且从 Python 3.6 开始,如果它们是从服务器发送过来的,则会处理它们,因为这提高了实际兼容性。

IMAP4.subscribe(mailbox)

订阅新的邮箱。

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

thread 命令是 search 的一个变体,它为结果提供线程语义。返回的数据包含一个以空格分隔的线程成员列表。

线程成员由零个或多个消息编号组成,以空格分隔,表示连续的父消息和子消息。

thread 命令在 search_criterion 参数之前有两个参数:threading_algorithm 和搜索的 charset。请注意,与 search 不同,搜索的 charset 参数是必需的。还有一个 uid thread 命令,它与 thread 的对应关系类似于 uid searchsearch 的对应关系。thread 命令首先使用 charset 参数解释搜索条件中的字符串,在邮箱中搜索符合给定搜索条件的消息。然后,它会根据指定的线程算法返回匹配的消息。

这是一个 IMAP4rev1 扩展命令。

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

使用 UID 而不是消息编号来标识消息,执行命令参数。返回与命令对应的响应。必须提供至少一个参数;如果未提供任何参数,服务器将返回错误并引发异常。

IMAP4.unsubscribe(mailbox)

取消订阅旧邮箱。

IMAP4.unselect()

imaplib.IMAP4.unselect() 释放服务器与选定邮箱关联的资源,并将服务器返回到已验证状态。此命令执行与 imaplib.IMAP4.close() 相同的操作,但不会从当前选定的邮箱中永久删除任何消息。

3.9 版本新增。

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

允许服务器在 CAPABILITY 响应中通知的简单扩展命令。

以下属性在 IMAP4 的实例上定义

IMAP4.PROTOCOL_VERSION

服务器 CAPABILITY 响应中支持的最新协议。

IMAP4.debug

控制调试输出的整数值。初始值取自模块变量 Debug。大于 3 的值会跟踪每个命令。

IMAP4.utf8_enabled

布尔值,通常为 False,但如果成功为 UTF8=ACCEPT 功能发出 enable() 命令,则设置为 True

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