imaplib --- IMAP4 协议客户端

源代码: Lib/imaplib.py


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

可用性:非 WASI。

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

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

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

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

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

>>> 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 支持的 socket 模块)。如果未指定 host,则使用 ''(本地主机)。如果省略 port,则使用标准的 IMAP4-over-SSL 端口(993)。ssl_context 是一个 ssl.SSLContext 对象,它允许将 SSL 配置选项、证书和私钥捆绑到一个(可能长期存在的)结构中。请阅读 安全考量 以了解最佳实践。

可选的 timeout 参数指定连接尝试的超时时间(以秒为单位)。如果未给出 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 参数可以是一个表示自纪元以来秒数的数字(整数或浮点数,如 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 追加到指定名称的邮箱中。

IMAP4.authenticate(mechanism, authobject)

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

mechanism 指定要使用的认证机制——它应出现在实例变量 capabilities 中,形式为 AUTH=mechanism

authobject 必须是一个可调用对象:

data = authobject(response)

它将被调用以处理服务器的继续响应;传递给它的 response 参数将是 bytes。它应该返回 bytes 类型的 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 在 mailbox 上设置的 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 的指定 ANNOTATIONs。该方法非标准,但 Cyrus 服务器支持。

IMAP4.getquota(root)

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

IMAP4.getquotaroot(mailbox)

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

IMAP4.idle(duration=None)

返回一个 Idler:一个可迭代的上下文管理器,实现了 RFC 2177 中定义的 IMAP4 IDLE 命令。

返回的对象在被 with 语句激活时发送 IDLE 命令,通过 迭代器 协议产生 IMAP 未标记响应,并在上下文退出时发送 DONE

所有在发送 IDLE 命令后到达的未标记响应(包括在服务器确认该命令之前到达的任何响应)都可以通过迭代获得。任何剩余的响应(那些在 with 上下文中未迭代的响应)可以在 IDLE 结束后通过 IMAP4.response() 以常规方式检索。

响应表示为 (type, [data, ...]) 元组,如 IMAP4 Objects 中所述。

duration 参数设置一个最大空闲持续时间(以秒为单位),超过该时间后任何正在进行的迭代将停止。它可以是 intfloat,或者 None 表示没有时间限制。希望避免在施加不活动超时的服务器上超时的调用者应将其保持在最多 29 分钟(1740 秒)。需要套接字连接;在 IMAP4_stream 连接上,duration 必须为 None

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

产生一组响应,这些响应的间隔不超过 interval 秒(表示为 intfloat)。

这个 生成器 是逐个迭代响应的替代方案,旨在帮助高效的批处理。它检索下一个响应以及任何立即可用的后续响应。(例如,在批量删除后快速出现的一系列 EXPUNGE 响应。)

需要套接字连接;在 IMAP4_stream 连接上不起作用。

>>> 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'])]

提示

在等待一批响应中的第一个响应时,会遵守传递给 IMAP4.idle()IDLE 上下文的最大持续时间。因此,一个已过期的 Idler 将导致此生成器立即返回而不产生任何内容。如果在循环中使用它,调用者应考虑这一点。

备注

IMAP4.idle() 返回的迭代器只能在 with 语句中使用。在该上下文之前或之后,每当命令完成时,未经请求的响应会在内部收集,并可以使用 IMAP4.response() 检索。

备注

Idler 类名和结构是内部接口,可能会发生变化。调用代码可以依赖于其上下文管理、迭代和公共方法的稳定性,但不应子类化、实例化、比较或以其他方式直接引用该类。

在 3.14 版本加入。

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

列出 directory 中与 pattern 匹配的邮箱名称。directory 默认为顶级邮件文件夹,pattern 默认为匹配任何内容。返回的数据包含一个 LIST 响应的列表。

IMAP4.login(user, password)

使用明文密码标识客户端。password 将被加上引号。

IMAP4.login_cram_md5(user, password)

在向客户端标识时强制使用 CRAM-MD5 身份验证以保护密码。仅当服务器 CAPABILITY 响应包含短语 AUTH=CRAM-MD5 时才有效。

在 3.14 版更改: 如果 MD5 支持不可用,则会引发 IMAP4.error

IMAP4.logout()

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

在 3.8 版更改: 该方法不再静默地忽略任意异常。

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

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

IMAP4.myrights(mailbox)

显示我对一个邮箱的ACLs(即我在该邮箱上的权限)。

IMAP4.namespace()

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

IMAP4.noop()

向服务器发送 NOOP

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

host 上打开到 port 的套接字。可选的 timeout 参数指定了连接尝试的超时秒数。如果没有给出 timeout 或者为 None,则使用全局默认套接字超时。另请注意,如果将 timeout 参数设置为零,则会引发 ValueError 来拒绝创建非阻塞套接字。此方法由 IMAP4 构造函数隐式调用。由此方法建立的连接对象将在 IMAP4.read(), IMAP4.readline(), IMAP4.send()IMAP4.shutdown() 方法中使用。您可以重写此方法。

引发一个参数为 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。返回给定的代码,而不是通常的类型。

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。你可以重写此方法。

引发一个参数为 self, data审计事件 imaplib.send

IMAP4.setacl(mailbox, who, what)

mailbox 设置 ACL。该方法非标准,但 Cyrus 服务器支持。

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

mailbox 设置 ANNOTATIONs。该方法非标准,但 Cyrus 服务器支持。

IMAP4.setquota(root, limits)

设置 quota root 的资源 limits。该方法是 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 searchsearch 的关系一样。sort 命令首先使用 charset 参数来解释搜索条件中的字符串,在邮箱中搜索与给定搜索条件匹配的消息。然后,它返回匹配消息的编号。

这是一个 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。大于三的值会跟踪每个命令。

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