imaplib --- IMAP4 協(xié)議客戶端?

源代碼: Lib/imaplib.py


本模塊定義了三個類: IMAP4IMAP4_SSLIMAP4_stream 。這三個類封裝了與IMAP4服務器的連接并實現(xiàn)了 RFC 2060 當中定義的大多數(shù)IMAP4rev1客戶端協(xié)議。其與IMAP4( RFC 1730 )服務器后向兼容,但是 STATUS 指令在IMAP4中不支持。

imaplib 模塊提供了三個類,其中 IMAP4 是基類:

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

這個類實現(xiàn)了實際的 IMAP4 協(xié)議。 當其實例被實例化時會創(chuàng)建連接并確定協(xié)議版本 (IMAP4 或 IMAP4rev1)。 如果未指明 host,則會使用 '' (本地主機)。 如果省略 port,則會使用標準 IMAP4 端口 (143)。 可選的 timeout 形參指定連接嘗試的超時秒數(shù)。 如果未指定超時或為 None,則會使用全局默認的套接字超時。

IMAP4 類支持 with 語句。 當這樣使用時,IMAP4 LOGOUT 命令會在 with 語句退出時自動發(fā)出。 例如:

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

任何錯誤都將引發(fā)該異常。 異常的原因會以字符串的形式傳遞給構造器。

exception IMAP4.abort?

IMAP4 服務器錯誤會導致引發(fā)該異常。 這是 IMAP4.error 的子類。 請注意關閉此實例并實例化一個新實例通常將會允許從該異常中恢復。

exception IMAP4.readonly?

當一個可寫郵箱的狀態(tài)被服務器修改時會引發(fā)此異常。 此異常是 IMAP4.error 的子類。 某個其他客戶端現(xiàn)在會具有寫入權限,將需要重新打開該郵箱以重新獲得寫入權限。

另外還有一個針對安全連接的子類:

class imaplib.IMAP4_SSL(host='', port=IMAP4_SSL_PORT, keyfile=None, certfile=None, ssl_context=None, timeout=None)?

這是一個派生自 IMAP4 的子類,它使用經(jīng) SSL 加密的套接字進行連接 (為了使用這個類你需要編譯時附帶 SSL 支持的 socket 模塊)。 如果未指定 host,則會使用 '' (本地主機)。 如果省略了 port,則會使用標準的 IMAP4-over-SSL 端口 (993)。 ssl_context 是一個 ssl.SSLContext 對象,它允許將 SSL 配置選項、證書和私鑰打包放入一個單獨的 (可以長久存在的) 結構體中。 請閱讀 安全考量 以獲取最佳實踐。

keyfilecertfilessl_context 的舊式替代品 —— 它們可以指向 PEM 格式的私鑰和證書鏈文件用于 SSL 連接。 請注意 keyfile/certfile 形參不能與 ssl_context 共存,如果 keyfile/certfilessl_context 一同被提供則會引發(fā) ValueError

可選的 timeout 形參指明連接嘗試的超時秒數(shù)。 如果參數(shù)未給出或為 None,則會使用全局默認的套接字超時設置。

在 3.3 版更改: 增加了 ssl_context 形參。

在 3.4 版更改: 本類現(xiàn)在支持使用 ssl.SSLContext.check_hostname服務器名稱指示 (參閱 ssl.HAS_SNI)進行主機名檢查。

3.6 版后已移除: keyfilecertfile 已棄用并轉而推薦 ssl_context。 請改用 ssl.SSLContext.load_cert_chain(),或讓 ssl.create_default_context() 為你選擇系統(tǒng)所信任的 CA 證書。

在 3.9 版更改: 添加了可選的 timeout 形參。

第二個子類允許由子進程所創(chuàng)建的連接:

class imaplib.IMAP4_stream(command)?

這是一個派生自 IMAP4 的子類,它可以連接 stdin/stdout 文件描述符,此種文件是通過向 subprocess.Popen() 傳入 command 來創(chuàng)建的。

定義了下列工具函數(shù):

imaplib.Internaldate2tuple(datestr)?

解析一個 IMAP4 INTERNALDATE 字符串并返回對應的本地時間。 返回值是一個 time.struct_time 元組或者如果字符串格式錯誤則為 None

imaplib.Int2AP(num)?

將一個整數(shù)轉換為使用字符集 [A .. P] 的字節(jié)串表示形式。

imaplib.ParseFlags(flagstr)?

將一個 IMAP4 FLAGS 響應轉換為包含單獨旗標的元組。

imaplib.Time2Internaldate(date_time)?

date_time 轉換為 IMAP4 INTERNALDATE 表示形式。 返回值是以下形式的字符串: "DD-Mmm-YYYY HH:MM:SS +HHMM" (包括雙引號)。 date_time 參數(shù)可以是一個代表距離紀元起始的秒數(shù) (如 time.time() 的返回值) 的數(shù)字 (整數(shù)或浮點數(shù)),一個代表本地時間的 9 元組,一個 time.struct_time 實例 (如 time.localtime() 的返回值),一個感知型的 datetime.datetime 實例,或一個雙引號字符串。 在最后一種情況下,它會被假定已經(jīng)具有正確的格式。

請注意 IMAP4 消息編號會隨郵箱的改變而改變;特別是在使用 EXPUNGE 命令執(zhí)行刪除后剩余的消息會被重新編號。 因此高度建議通過 UID 命令來改用 UID。

模塊的最后有一段測試,其中包含的用法示例更加廣泛。

參見

描述該協(xié)議的文檔,實現(xiàn)該協(xié)議的服務器源代碼,由華盛頓大學 IMAP 信息中心提供 (源代碼) https://github.com/uw-imap/imap (不再維護)。

IMAP4 對象?

所有 IMAP4rev1 命令都表示為同名的方法,可以為大寫或小寫形式。

命令的所有參數(shù)都會被轉換為字符串,只有 AUTHENTICATE 例外,而 APPEND 的最后一個參數(shù)會被作為 IMAP4 字面值傳入。 如有必要 (字符串包含 IMAP4 協(xié)議中的敏感字符并且未加圓括號或雙引號) 每個字符串都會被轉碼。 但是,LOGIN 命令的 password 參數(shù)總是會被轉碼。 如果你想讓某個參數(shù)字符串免于被轉碼 (例如: STOREflags 參數(shù)) 則要為該字符串加上圓括號 (例如: r'(\Deleted)')。

每條命令均返回一個元組: (type, [data, ...]) 其中 type 通常為 'OK''NO',而 data 為來自命令響應的文本,或為來自命令的規(guī)定結果。 每個 data 均為 bytes 或者元組。 如果為元組,則其第一部分是響應的標頭,而第二部分將包含數(shù)據(jù) (例如: 'literal' 值)。

以下命令的 message_set 選項為指定要操作的一條或多條消息的字符串。 它可以是一個簡單的消息編號 ('1'),一段消息編號區(qū)間 ('2:4'),或者一組以逗號分隔的非連續(xù)區(qū)間 ('1:3,6:9')。 區(qū)間可以包含一個星號來表示無限的上界 ('3:*')。

IMAP4 實例具有下列方法:

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

message 添加到指定的郵箱。

IMAP4.authenticate(mechanism, authobject)?

認證命令 --- 要求對響應進行處理。

mechanism 指明要使用哪種認證機制 —— 它應當在實例變量 capabilities 中以 AUTH=mechanism 的形式出現(xiàn)。

authobject 必須是一個可調用對象:

data = authobject(response)

它將被調用以便處理服務器連續(xù)響應;傳給它的 response 參數(shù)將為 bytes 類型。 它應當返回 base64 編碼的 bytes 數(shù)據(jù) 并發(fā)送給服務器。 或者在客戶端中止響應時返回 None 并應改為發(fā)送 *。

在 3.5 版更改: 字符串形式的用戶名和密碼現(xiàn)在會被執(zhí)行 utf-8 編碼而不限于 ASCII 字符。

IMAP4.check()?

為服務器上的郵箱設置檢查點。

IMAP4.close()?

關閉當前選定的郵箱。 已刪除的消息會從可寫郵箱中被移除。 在 LOGOUT 之前建議執(zhí)行此命令。

IMAP4.copy(message_set, new_mailbox)?

message_set 消息拷貝到 new_mailbox 的末尾。

IMAP4.create(mailbox)?

新建名為 mailbox 新郵箱。

IMAP4.delete(mailbox)?

刪除名為 mailbox 的舊郵箱。

IMAP4.deleteacl(mailbox, who)?

刪除郵箱上某人的 ACL (移除任何權限)。

IMAP4.enable(capability)?

啟用 capability (參見 RFC 5161)。 大多數(shù)功能都不需要被啟用。 目前只有 UTF8=ACCEPT 功能受到支持 (參見 RFC 6855)。

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

IMAP4.expunge()?

從選定的郵箱中永久移除被刪除的條目。 為每條被刪除的消息各生成一個 EXPUNGE 響應。 返回包含按接收時間排序的 EXPUNGE 消息編號的列表。

IMAP4.fetch(message_set, message_parts)?

獲取消息(的各個部分)。 message_parts 應為加圓標號的消息部分名稱字符串,例如: "(UID BODY[TEXT])"。 返回的數(shù)據(jù)是由消息部分封包和數(shù)據(jù)組成的元組。

IMAP4.getacl(mailbox)?

獲取 mailboxACL。 此方法是非標準的,但是被 Cyrus 服務器所支持。

IMAP4.getannotation(mailbox, entry, attribute)?

提取 mailbox 的特定 ANNOTATION。 此方法是非標準的,但是被 Cyrus 服務器所支持。

IMAP4.getquota(root)?

獲取 quota root 的資源使用和限制。 此方法是 rfc2087 定義的 IMAP4 QUOTA 擴展的組成部分。

IMAP4.getquotaroot(mailbox)?

獲取指定 mailboxquota roots 列表。 此方法是 rfc2087 定義的 IMAP4 QUOTA 擴展的組成部分。

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

列出 directory 中與 pattern 相匹配的郵箱名稱。 directory 默認為最高層級的電郵文件夾,而 pattern 默認為匹配任何文本。 返回的數(shù)據(jù)包含 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 相匹配的郵箱。 directory 默認為最高層級目錄而 pattern 默認為匹配任何郵箱。 返回的數(shù)據(jù)為消息部分封包和數(shù)據(jù)的元組。

IMAP4.myrights(mailbox)?

顯示某個郵箱的本人 ACL (即本人在郵箱中的權限)。

IMAP4.namespace()?

返回 RFC 2342 中定義的 IMAP 命名空間。

IMAP4.noop()?

NOOP 發(fā)送給服務器。

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

打開連接 hostport 的套接字。 可選的 timeout 形參指定連接嘗試的超時秒數(shù)。 如果 timeout 未給出或為 None,則會使用全局默認的套接字超時。 另外請注意如果 timeout 形參被設為零,它將引發(fā) ValueError 以拒絕創(chuàng)建非阻塞套接字。 此方法會由 IMAP4 構造器隱式地調用。 此方法所建立的連接對象將在 IMAP4.read(), IMAP4.readline(), IMAP4.send()IMAP4.shutdown() 等方法中被使用。 你可以重載此方法。

引發(fā)一個 審計事件 imaplib.open,附帶參數(shù) self, host, port。

在 3.9 版更改: 加入 timeout 參數(shù)。

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

獲取消息被截斷的部分。 返回的數(shù)據(jù)是由消息部分封包和數(shù)據(jù)組成的元組。

IMAP4.proxyauth(user)?

作為 user 進行認證。 允許經(jīng)權限的管理員通過代理進入任意用戶的郵箱。

IMAP4.read(size)?

從遠程服務器讀取 size 字節(jié)。 你可以重載此方法。

IMAP4.readline()?

從遠程服務器讀取一行。 你可以重載此方法。

IMAP4.recent()?

提示服務器進行更新。 如果沒有新消息則返回的數(shù)據(jù)為 None,否則為 RECENT 響應的值。

IMAP4.rename(oldmailbox, newmailbox)?

將名為 oldmailbox 的郵箱重命名為 newmailbox。

IMAP4.response(code)?

如果收到響應 code 則返回其數(shù)據(jù),否則返回 None。 返回給定的代碼,而不是普通的類型。

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

在郵箱中搜索匹配的消息。 charset 可以為 None,在這種情況下在發(fā)給服務器的請求中將不指定 CHARSET。 IMAP 協(xié)議要求至少指定一個標準;當服務器返回錯誤時將會引發(fā)異常。 charsetNone 對應使用 enable() 命令啟用了 UTF8=ACCEPT 功能的情況。

示例:

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

選擇一個郵箱。 返回的數(shù)據(jù)是 mailbox 中消息的數(shù)量 (EXISTS 響應)。 默認的 mailbox'INBOX'。 如果設置了 readonly 旗標,則不允許修改該郵箱。

IMAP4.send(data)?

data 發(fā)送給遠程服務器。 你可以重載此方法。

引發(fā)一個 審計事件 imaplib.send,附帶參數(shù) self, data

IMAP4.setacl(mailbox, who, what)?

發(fā)送 mailboxACL。 此方法是非標準的,但是被 Cyrus 服務器所支持。

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

設置 mailboxANNOTATION。 此方法是非標準的,但是被 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 的變化形式,帶有結果排序語句。 返回的數(shù)據(jù)包含以空格分隔的匹配消息編號列表。

sort 命令在 search_criterion 參數(shù)之前還有兩個參數(shù);一個帶圓括號的 sort_criteria 列表,和搜索的 charset。 請注意不同于 search,搜索的 charset 參數(shù)是強制性的。 還有一個 uid sort 命令與 sort 對應,如同 uid searchsearch 對應一樣。 sort 命令首先在郵箱中搜索匹配給定搜索條件的消息,使用 charset 參數(shù)來解讀搜索條件中的字符串。 然后它將返回所匹配消息的編號。

這是一個 IMAP4rev1 擴展命令。

IMAP4.starttls(ssl_context=None)?

發(fā)送一個 STARTTLS 命令。 ssl_context 參數(shù)是可選的并且應為一個 ssl.SSLContext 對象。 這將在 IMAP 連接上啟用加密。 請閱讀 安全考量 來了解最佳實踐。

3.2 新版功能.

在 3.4 版更改: 此方法現(xiàn)在支持使用 ssl.SSLContext.check_hostname服務器名稱指示 (參見 ssl.HAS_SNI) 進行主機名檢查。

IMAP4.status(mailbox, names)?

針對 mailbox 請求指定的狀態(tài)條件。

IMAP4.store(message_set, command, flag_list)?

改變郵箱中消息的旗標處理。 commandRFC 2060 的 6.4.6 小節(jié)指明,應為 "FLAGS", "+FLAGS" 或 "-FLAGS" 之一,并可選擇附帶 ".SILENT" 后綴。

例如,要在所有消息上設置刪除旗標:

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

備注

創(chuàng)建包含 ']' 的旗標 (例如: "[test]") 會違反 RFC 3501 (IMAP 協(xié)議)。 但是,imaplib 在歷史上曾經(jīng)允許創(chuàng)建這樣的標簽,并且流行的 IMAP 服務器如 Gmail 都會接受并生成這樣的旗標。 有些非 Python 程序也會創(chuàng)建這樣的旗標。 雖然它違反 RFC 并且 IMAP 客戶端和服務器應當嚴格遵守規(guī)范,但是 imaplib 出于向下兼容的理由仍然繼續(xù)允許創(chuàng)建這樣的標簽,并且在 Python 3.6 中會在其被服務器所發(fā)送時處理它們,因為這能提升實際的兼容性。

IMAP4.subscribe(mailbox)?

訂閱新郵箱。

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

thread 命令是 search 的變化形式,帶有針對結果的消息串句法。 返回的數(shù)據(jù)包含以空格分隔的消息串成員列表。

消息串成員由零個或多個消息編號組成,以空格分隔,標示了連續(xù)的上下級關系。

thread 命令在 search_criterion 參數(shù)之前還有兩個參數(shù);一個 threading_algorithm,以及搜索使用的 charset。 請注意不同于 search,搜索使用的 charset 參數(shù)是強制性的。 還有一個 uid thread 命令與 thread 對應,如同 uid searchsearch 對應一個。 thread 命令首先在郵箱中搜索匹配給定搜索條件的消息,使用 charset 參數(shù)來解讀搜索條件中的字符串。 然后它將按照指定的消息串算法返回所匹配的消息串。

這是一個 IMAP4rev1 擴展命令。

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

執(zhí)行 command arg 并附帶用 UID 所標識的消息,而不是用消息編號。 返回與命令對應的響應。 必須至少提供一個參數(shù);如果不提供任何參數(shù),服務器將返回錯誤并引發(fā)異常。

IMAP4.unsubscribe(mailbox)?

取消訂閱原有郵箱。

IMAP4.unselect()?

imaplib.IMAP4.unselect() 會釋放關聯(lián)到選定郵箱的服務器資源并將服務器返回到已認證狀態(tài)。 此命令會執(zhí)行與 imaplib.IMAP4.close() 相同的動作,區(qū)別在于它不會從當前選定郵箱中永久性地移除消息。

3.9 新版功能.

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

允許服務器在 CAPABILITY 響應中通知簡單的擴展命令。

IMAP4 的實例上定義了下列屬性:

IMAP4.PROTOCOL_VERSION?

在服務器的 CAPABILITY 響應中最新的受支持協(xié)議。

IMAP4.debug?

控制調試輸出的整數(shù)值。 初始值會從模塊變量 Debug 中獲取。 大于三的值表示將追蹤每一條命令。

IMAP4.utf8_enabled?

通常為 False 的布爾值,但也可以被設為 True,如果成功地為 UTF8=ACCEPT 功能發(fā)送了 enable() 命令的話。

3.5 新版功能.

IMAP4 示例?

以下是一個最短示例(不帶錯誤檢查),該示例將打開郵箱,檢索并打印所有消息:

import getpass, imaplib

M = imaplib.IMAP4()
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()