imaplib — Клиент протокола IMAP4


Данный модуль определяет три класса, IMAP4, IMAP4_SSL и IMAP4_stream, которые инкапсулируют соединение с сервером IMAP4 и реализуют большое подмножество клиентского протокола IMAP4rev1, как определено в RFC 2060. Он обратно совместим с серверами IMAP4 (RFC 1730), но обратите внимание, что команда STATUS не поддерживается в IMAP4.

Модуль imaplib предоставляет три класса, IMAP4 — базовый класс:

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

Данный класс реализует фактический протокол IMAP4. Соединение создаётся и версия протокола (IMAP4 или IMAP4rev1) определяется при инициализации экземпляра. Если host не указан, используется '' (локальный хост). Если port пропущен, используется стандартный порт IMAP4 (143).

Класс 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.

Три исключения определены как атрибуты класса IMAP4:

exception IMAP4.error

Вызывается исключение при любых ошибках. Причина исключения передаётся конструктору в виде строки.

exception IMAP4.abort

Ошибки сервера IMAP4 вызывают это исключение. Это подкласс IMAP4.error. Обратите внимание, что закрытие экземпляра и создание нового экземпляра обычно позволяет восстановиться после этого исключения.

exception IMAP4.readonly

Вызывается исключение, когда сервер изменяет статус доступного для записи почтового ящика. Это подкласс IMAP4.error. У какого-то другого клиента теперь есть разрешение на запись, и почтовый ящик нужно будет повторно открыть, чтобы повторно получить разрешение на запись.

Также есть подкласс для безопасных соединений:

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

Подкласс, производный от IMAP4, который подключается через зашифрованный SSL сокет (для использования этого класса вам нужен модуль socket, скомпилированный с поддержкой SSL). Если host не указан, используется '' (локальный хост). Если port пропущен, используется стандартный порт IMAP4-over-SSL (993). ssl_context — это объект ssl.SSLContext, который позволяет объединять параметры конфигурации SSL, сертификаты и закрытые ключи в единую (потенциально долгоживущую) структуру. Ознакомьтесь с рекомендациями Соображения безопасности.

keyfile и certfile являются устаревшей альтернативой ssl_context — они могут указывать на закрытый ключ в формате PEM и файлы цепочки сертификатов для соединения SSL. Обратите внимание, что параметры keyfile/certfile являются взаимоисключающими с ssl_context, вызывается ValueError, если keyfile/certfile предоставляется вместе с ssl_context.

Изменено в версии 3.3: Добавлен параметр ssl_context.

Изменено в версии 3.4: Класс теперь поддерживает проверку имени хоста с помощью ssl.SSLContext.check_hostname и Индикации имени сервера (см. ssl.HAS_SNI).

Не рекомендуется, начиная с версии 3.6: keyfile и certfile устарели в пользу ssl_context. Вместо этого используйте ssl.SSLContext.load_cert_chain() или позвольте ssl.create_default_context() выбрать для вас доверенные сертификаты CA системы.

Второй подкласс допускает соединения, созданные дочерним процессом:

class imaplib.IMAP4_stream(command)

Это подкласс, производный от IMAP4, который подключается к файловым дескрипторам stdin/stdout, созданным путём передачи command в subprocess.Popen().

Определены следующие вспомогательные функции:

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 может быть числом (int или float), представляющим секунды с начала эпохи (как возвращается time.time()), 9-кортежем, представляющим местное время экземпляром time.struct_time (как возвращается time.localtime()), осведомлённым экземпляром datetime.datetime или строкой в двойных кавычках. В последнем случае предполагается, что он уже имеет правильный формат.

Обратите внимание, что номера сообщений IMAP4 меняются при изменении почтового ящика; в частности, после удаления командой EXPUNGE оставшиеся сообщения перенумеровываются. Поэтому настоятельно рекомендуется вместо этого использовать UID с помощью команды UID.

В конце модуля есть тестовый раздел, содержащий более развернутый пример использования.

См.также

Документы, документирующие протокол, источники реализующих его серверов. Информационного центра IMAP Вашингтонского университета можно найти по адресу исходного кода (Не поддерживается).

IMAP4-объекты

Все команды IMAP4rev1 представлены методами с одинаковыми именами в верхнем или нижнем регистре.

Все аргументы команд преобразуются в строки, за исключением AUTHENTICATE и последнего аргумента APPEND, который передаётся как литерал IMAP4. При необходимости (строка содержит символы, зависящие от протокола IMAP4, и не заключена ни в скобки, ни в двойные кавычки) каждая строка заключена в кавычки. Однако аргумент password команды LOGIN всегда заключён в кавычки. Если вы хотите, чтобы строка аргумента не заключалась в кавычки (например, аргумент от flags до STORE), заключите строку в круглые скобки (например: 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)

Удалить списки 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)

Получить ACL для mailbox. Способ нестандартный, но поддерживается сервером Cyrus.

IMAP4.getannotation(mailbox, entry, attribute)

Получить указанные ANNOTATIONs для mailbox. Способ нестандартный, но поддерживается сервером Cyrus.

IMAP4.getquota(root)

Получить сведения об использовании и ограничениях ресурсов quota root. Данный метод является частью расширения IMAP4 QUOTA, определенного в rfc2087.

IMAP4.getquotaroot(mailbox)

Получить список quota roots для имени mailbox. Данный метод является частью расширения IMAP4 QUOTA, определенного в rfc2087.

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.

IMAP4.logout()

Отключить соединение с сервером. Возвращает ответ сервера BYE.

Изменено в версии 3.8: Метод больше не игнорирует молча произвольные исключения.

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

Перечислите имена почтовых ящиков с подпиской в соответствии с шаблоном каталога. directory по умолчанию соответствует каталогу верхнего уровня, а pattern по умолчанию соответствует любому почтовому ящику. Возвращаемые данные представляют собой кортежи из конверта части сообщения и данных.

IMAP4.myrights(mailbox)

Показать мои ACL для почтового ящика (т.е. права, которые у меня есть на почтовый ящик).

IMAP4.namespace()

Возвращает пространства имён IMAP, как определено в RFC 2342.

IMAP4.noop()

Отправить NOOP на сервер.

IMAP4.open(host, port)

Открывает сокет на port по адресу host. Данный метод неявно вызывается конструктором IMAP4. Объекты соединений, установленные этим методом, будут использоваться в методах IMAP4.read(), IMAP4.readline(), IMAP4.send() и IMAP4.shutdown(). Вы можете переопределить данный метод.

Вызывает событие аудита imaplib.open с аргументами self, host, port.

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 требует указания хотя бы одного критерия; исключение будет вызвано, когда сервер вернёт ошибку. charset должен быть None, если возможность UTF8=ACCEPT была включена с помощью команды enable().

Пример:

# М - это подключенный экземпляр iMap4 ...
typ, msgnums = M.search(None, 'FROM', '"LDJ"')

# или:
typ, msgnums = M.search(None, '(FROM "LDJ")')
IMAP4.select(mailbox='INBOX', readonly=False)

Выбрать почтовый ящик. Возвращаемые данные — это количество сообщений в mailbox (ответ EXISTS). По умолчанию mailbox'INBOX'. Если установлен флаг readonly, изменения почтового ящика не разрешены.

IMAP4.send(data)

Отправляет data на удаленный сервер. Вы можете переопределить данный метод.

Вызывает событие аудита imaplib.send с аргументами self, data.

IMAP4.setacl(mailbox, who, what)

Устанавливает ACL для mailbox. Способ нестандартный, но поддерживается сервером Cyrus.

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

Устанавливает ANNOTATIONs вместо mailbox. Способ нестандартный, но поддерживается сервером Cyrus.

IMAP4.setquota(root, limits)

Устанавливает ресурс quota root limits. Данный метод является частью расширения IMAP4 QUOTA, определенного в rfc2087.

IMAP4.shutdown()

Тесное соединение установлено в open. Данный метод неявно вызывается IMAP4.logout(). Вы можете переопределить данный метод.

IMAP4.socket()

Возвращает экземпляр сокета, используемый для подключения к серверу.

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

Команда sort — это вариант search с семантикой сортировки результатов. Возвращаемые данные содержат список совпадающих номеров сообщений, разделённых пробелами.

Сортировка имеет два аргумента перед аргументом(ами) search_criterion; список в скобках sort_criteria и поиск charset. Обратите внимание, что в отличие от search, поисковый аргумент charset является обязательным. Существует также команда uid sort, которая соответствует sort так же, как uid search соответствует search. Команда 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)

Изменяет расположение флажков для сообщений в почтовом ящике. command указан в разделе 6.4.6 RFC 2060 как один из «FLAGS», «+FLAGS» или «-FLAGS», необязательно с суффиксом «.SILENT».

Например, установить флаг удаления на все сообщения:

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

Примечание

Создание флагов, содержащих «]» (например: «[тест]»), нарушает 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 с семантикой потоков для результатов. Возвращаемые данные содержат разделенный пробелами список членов потока.

Члены потока состоят из нуля или более номеров сообщений, разделённых пробелами, что указывает на последовательные родительский и дочерний элементы.

Поток имеет два аргумента перед аргументом(ами) search_criterion; a threading_algorithm и поиск charset. Обратите внимание, что в отличие от search, поисковый аргумент charset является обязательным. Существует также команда uid thread, которая соответствует thread так же, как uid search соответствует search. Команда thread сначала ищет в почтовом ящике сообщения, соответствующие заданным критериям поиска, используя аргумент charset для интерпретации строк в критериях поиска. Затем он возвращает совпадающие сообщения, объединенные в потоки в соответствии с указанным алгоритмом потоков.

Это команда расширения IMAP4rev1.

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

Аргументы команды выполнения с сообщениями, идентифицируемыми по UID, а не по номеру сообщения. Возвращает ответ, соответствующий команде. Должен быть указан хотя бы один аргумент; если ничего не указано, сервер вернёт ошибку и будет возбуждено исключение.

IMAP4.unsubscribe(mailbox)

Отписаться от старого почтового ящика.

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

Разрешить простые команды расширения, о которых сервер сообщает в ответе CAPABILITY.

Следующие атрибуты определены для экземпляров IMAP4:

IMAP4.PROTOCOL_VERSION

Самый последний поддерживаемый протокол в ответе CAPABILITY от сервера.

IMAP4.debug

Целочисленное значение для управления выводом отладки. Значение инициализации берётся из переменной модуля Debug. Значения больше трех трассируют каждую команду.

IMAP4.utf8_enabled

Логическое значение, которое обычно равно False, но устанавливается на True, если команда enable() успешно выполнена для возможности UTF8=ACCEPT.

Добавлено в версии 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()