Содержание страницы
20.12. smtplib – клиент протокола SMTP¶smtplib – SMTP protocol client
Исходный код: Lib/smtplib.py
Модуль smtplib определяет объект сессии SMTP-клиента, который можно использовать для отправки почты на любую машину в Интернете с демоном, прослушивающим SMTP или ESMTP. Подробнее о работе SMTP и ESMTP см. в RFC 821 (Простой протокол передачи почты) и RFC 1869 (Расширения службы SMTP).
-
class
smtplib.SMTP([host[, port[, local_hostname[, timeout]]]])¶ Экземпляр
SMTPинкапсулирует SMTP-соединение. Он предоставляет методы для полного набора операций SMTP и ESMTP. Если указаны необязательные параметры host и port, во время инициализации вызывается методconnect(). Если он задан, local_hostname используется как FQDN локального хоста в команде HELO/EHLO. В противном случае имя локального хоста определяется с помощьюsocket.getfqdn(). Если вызовconnect()возвращает что-то отличное от кода успеха, возбуждается исключениеSMTPConnectError. Необязательный параметр timeout задаёт тайм-аут в секундах для блокирующих операций, таких как попытка соединения (если не указан, используется глобальная настройка тайм-аута по умолчанию). Если время тайм-аута истекает, возбуждаетсяsocket.timeout.Для обычного использования достаточно методов инициализации/подключения,
sendmail()иSMTP.quit(). Пример приведен ниже.Изменено в версии 2.6: добавлен параметр timeout.
-
class
smtplib.SMTP_SSL([host[, port[, local_hostname[, keyfile[, certfile[, timeout]]]]]])¶ Экземпляр
SMTP_SSLведёт себя точно так же, как экземплярыSMTP.SMTP_SSLследует использовать, если SSL необходим с самого начала соединения, а использованиеstarttls()не подходит. Если host не указан, используется локальный хост. Если port опущен, используется стандартный порт SMTP через SSL (465). local_hostname имеет тот же смысл, что и для классаSMTP. keyfile и certfile также необязательны; они могут содержать закрытый ключ в формате PEM и файл цепочки сертификатов для SSL-соединения. Необязательный параметр timeout задаёт тайм-аут в секундах для блокирующих операций, таких как попытка соединения (если не указан, используется глобальная настройка тайм-аута по умолчанию). Если время тайм-аута истекает, возбуждаетсяsocket.timeout.Новое в версии 2.6.
-
class
smtplib.LMTP([host[, port[, local_hostname]]])¶ Протокол LMTP, очень похожий на ESMTP, во многом основан на стандартном SMTP-клиенте. Для LMTP часто используются Unix-сокеты, поэтому наш метод
connect()должен поддерживать их наравне с обычными серверами вида host:port. local_hostname имеет тот же смысл, что и для классаSMTP. Чтобы указать Unix-сокет, нужно использовать абсолютный путь для host, начинающийся с '/'.Поддерживается аутентификация с использованием обычного механизма SMTP. При использовании Unix-сокета LMTP обычно не поддерживает и не требует аутентификации, но возможны исключения.
Новое в версии 2.6.
Также определен неплохой набор исключений:
-
exception
smtplib.SMTPException¶ Базовый класс исключения для всех остальных исключений, предоставляемых этим модулем.
-
exception
smtplib.SMTPServerDisconnected¶ Это исключение возбуждается, когда сервер неожиданно отключается или когда предпринимается попытка использовать экземпляр
SMTPдо подключения к серверу.
-
exception
smtplib.SMTPResponseException¶ Базовый класс для всех исключений, содержащих код ошибки SMTP. Эти исключения генерируются в некоторых случаях, когда SMTP-сервер возвращает код ошибки. Код ошибки хранится в атрибуте
smtp_codeисключения, а атрибутsmtp_errorсодержит сообщение об ошибке.
-
exception
smtplib.SMTPSenderRefused¶ Адрес отправителя отклонен. В дополнение к атрибутам, задаваемым для всех исключений
SMTPResponseException, здесь атрибут 'sender' устанавливается в строку, которую отклонил SMTP-сервер.
-
exception
smtplib.SMTPRecipientsRefused¶ Все адреса получателей отклонены. Ошибки для каждого получателя доступны через атрибут
recipients, который представляет собой словарь точно такого же типа, какой возвращаетSMTP.sendmail().
-
exception
smtplib.SMTPDataError¶ Сервер SMTP отказался принимать данные сообщения.
-
exception
smtplib.SMTPConnectError¶ Произошла ошибка при установке соединения с сервером.
-
exception
smtplib.SMTPHeloError¶ Сервер отклонил наше сообщение
HELO.
-
exception
smtplib.SMTPAuthenticationError¶ Произошла ошибка аутентификации SMTP. Скорее всего, сервер не принял предоставленную комбинацию имени пользователя и пароля.
См. также
- RFC 821 – Простой протокол передачи почты
Определение протокола SMTP. Этот документ описывает модель, порядок работы и детали протокола SMTP.
- RFC 1869 – Расширения службы SMTP
Определение расширений ESMTP для SMTP. Описывается инфраструктура для расширения SMTP новыми командами, динамическое обнаружение команд, предоставляемых сервером, и определяются несколько дополнительных команд.
20.12.1. Объекты SMTP¶SMTP Objects
Экземпляр SMTP имеет следующие методы:
-
SMTP.set_debuglevel(level)¶ Устанавливает уровень отладочного вывода. Значение level, равное истине, приводит к выводу отладочных сообщений для соединения и для всех сообщений, отправленных на сервер и полученных от него.
-
SMTP.docmd(cmd[, argstring])¶ Отправляет команду cmd серверу. Необязательный аргумент argstring просто добавляется к команде через пробел.
Возвращает кортеж из двух элементов: числового кода ответа и собственно строки ответа (многострочные ответы объединяются в одну длинную строку).
При обычной работе нет необходимости явно вызывать этот метод. Он используется для реализации других методов и может быть полезен при тестировании частных расширений.
Если соединение с сервером потеряно во время ожидания ответа, будет возбуждено
SMTPServerDisconnected.
-
SMTP.connect([host[, port]])¶ Подключается к хосту на указанном порту. По умолчанию подключается к локальному хосту на стандартном порту SMTP (25). Если имя хоста заканчивается на двоеточие (
':'), за которым следует число, этот суффикс отбрасывается, а число интерпретируется как номер порта для использования. Этот метод автоматически вызывается конструктором, если хост указан при создании экземпляра. Возвращает кортеж из двух элементов: код ответа и сообщение, отправленное сервером в своём ответе на подключение.
-
SMTP.helo([hostname])¶ Идентифицирует себя перед SMTP-сервером с помощью
HELO. Аргумент hostname по умолчанию равен полному доменному имени локального хоста. Сообщение, возвращённое сервером, сохраняется в атрибутеhelo_respобъекта.При обычной работе нет необходимости явно вызывать этот метод. Он будет неявно вызван
sendmail()при необходимости.
-
SMTP.ehlo([hostname])¶ Идентификация перед ESMTP-сервером выполняется с помощью
EHLO. Аргумент hostname по умолчанию принимает полное доменное имя локального хоста. Анализирует ответ на предмет возможностей ESMTP и сохраняет их для использования методомhas_extn(). Также устанавливает несколько информационных атрибутов: сообщение, возвращённое сервером, сохраняется в атрибутеehlo_resp;does_esmtpпринимает значение true или false в зависимости от того, поддерживает ли сервер ESMTP; аesmtp_featuresпредставляет собой словарь, содержащий имена расширений SMTP, поддерживаемых данным сервером, и их параметры (если они есть).Если не требуется использовать
has_extn()перед отправкой почты, явно вызывать этот метод необязательно. Он будет неявно вызван методомsendmail()при необходимости.
-
SMTP.ehlo_or_helo_if_needed()¶ Этот метод вызывает
ehlo()и/илиhelo(), если в этом сеансе не было предыдущей командыEHLOилиHELO. Сначала он пытается использовать ESMTPEHLO.SMTPHeloErrorСервер некорректно ответил на приветствие
HELO.
Новое в версии 2.6.
-
SMTP.has_extn(name)¶ Возвращает
True, если name присутствует в наборе расширений SMTP-сервиса, возвращённых сервером, иFalseв противном случае. Регистр игнорируется.
-
SMTP.verify(address)¶ Проверяет корректность адреса на этом сервере с помощью SMTP
VRFY. Возвращает кортеж, состоящий из кода 250 и полного адреса RFC 822 (включая имя человека), если адрес пользователя действителен. В противном случае возвращает код ошибки SMTP 400 или больше и строку ошибки.Примечание
Многие сайты отключают SMTP
VRFY, чтобы помешать спамерам.
-
SMTP.login(user, password)¶ Выполняет вход на SMTP-сервер, требующий аутентификации. Аргументами являются имя пользователя и пароль для аутентификации. Если в течение этого сеанса ещё не было выполнено команды
EHLOилиHELO, этот метод сначала пробует ESMTPEHLO. Этот метод завершается нормально, если аутентификация прошла успешно, или может возбудить следующие исключения:SMTPHeloErrorСервер некорректно ответил на приветствие
HELO.SMTPAuthenticationErrorСервер не принял комбинацию имя пользователя/пароль.
SMTPExceptionНе найден подходящий метод аутентификации.
-
SMTP.starttls([keyfile[, certfile]])¶ Переводит SMTP-соединение в режим TLS (безопасность транспортного уровня). Все последующие SMTP-команды будут зашифрованы. После этого следует снова вызвать
ehlo().Если указаны keyfile и certfile, они передаются функции
ssl()модуляsocket.Если в течение этого сеанса ещё не выполнялась команда
EHLOилиHELO, метод сначала пытается выполнить ESMTPEHLO.Изменено в версии 2.6.
SMTPHeloErrorСервер некорректно ответил на приветствие
HELO.SMTPExceptionСервер не поддерживает расширение STARTTLS.
Изменено в версии 2.6.
RuntimeErrorИнтерпретатор Python не поддерживает SSL/TLS.
-
SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])¶ Отправляет почту. Обязательными аргументами являются строка обратного адреса RFC 822, список строк адресов получателей RFC 822 (простая строка будет рассматриваться как список с одним адресом) и строка сообщения. Вызывающий может передать список параметров ESMTP (например,
8bitmime) для использования в командахMAIL FROMв качестве mail_options. Параметры ESMTP (например, командыDSN), которые должны использоваться со всеми командамиRCPT, могут быть переданы как rcpt_options. (Если необходимо использовать разные параметры ESMTP для разных получателей, нужно использовать низкоуровневые методы, такие какmail(),rcpt()иdata(), для отправки сообщения.)Примечание
Параметры from_addr и to_addrs используются для построения конверта сообщения, используемого транспортными агентами.
SMTPникак не изменяет заголовки сообщения.Если в течение этого сеанса ещё не выполнялась команда
EHLOилиHELO, данный метод сначала пытается выполнить ESMTPEHLO. Если сервер поддерживает ESMTP, ему будут переданы размер сообщения и каждая из указанных опций (если опция присутствует в наборе возможностей, объявленных сервером). ЕслиEHLOне удаётся, будет выполнена попыткаHELOи ESMTP-опции будут подавлены.Метод завершается нормально, если почта принята хотя бы одним получателем. В противном случае возбуждается исключение. То есть, если метод не возбуждает исключение, значит, кто-то должен получить ваше письмо. Если метод не возбуждает исключение, он возвращает словарь с одной записью для каждого получателя, которому было отказано. Каждая запись содержит кортеж из кода ошибки SMTP и соответствующего сообщения об ошибке, отправленного сервером.
Этот метод может возбуждать следующие исключения:
SMTPRecipientsRefusedВсе получатели были отклонены. Почта не была доставлена. Атрибут
recipientsобъекта исключения представляет собой словарь с информацией об отклонённых получателях (такой же, как возвращается, когда хотя бы один получатель был принят).SMTPHeloErrorСервер некорректно ответил на приветствие
HELO.SMTPSenderRefusedСервер не принял адрес from_addr.
SMTPDataErrorСервер ответил неожиданным кодом ошибки (не связанным с отказом отдельному получателю).
Если не указано иное, соединение остаётся открытым даже после возбуждения исключения.
-
SMTP.quit()¶ Завершает сеанс SMTP и закрывает соединение. Возвращает результат команды SMTP
QUIT.Изменено в версии 2.6: Возвращает значение.
Также поддерживаются низкоуровневые методы, соответствующие стандартным командам SMTP/ESMTP HELP,
RSET, NOOP, MAIL, RCPT и DATA.
Обычно их не нужно вызывать напрямую, поэтому они не документированы
здесь. Подробнее см. в коде модуля.
20.12.2. Пример SMTP¶SMTP Example
Этот пример запрашивает у пользователя адреса, необходимые в конверте сообщения (адреса ‘To’\nи ‘From’), а также само сообщение для отправки. Обратите внимание, что заголовки,\nкоторые должны быть включены в сообщение, должны быть включены в сообщение при вводе; этот\nпример не выполняет никакой обработки заголовков RFC 822. В частности,\nадреса ‘To’ и ‘From’ должны быть явно включены в заголовки сообщения.
import smtplib
def prompt(prompt):
return raw_input(prompt).strip()
fromaddr = prompt("From: ")
toaddrs = prompt("To: ").split()
print "Enter message, end with ^D (Unix) or ^Z (Windows):"
# Добавьте заголовки From: и To: в начало!
msg = ("From: %s\r\nTo: %s\r\n\r\n"
% (fromaddr, ", ".join(toaddrs)))
while 1:
try:
line = raw_input()
except EOFError:
break
if not line:
break
msg = msg + line
print "Message length is " + repr(len(msg))
server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
Примечание
В целом рекомендуется использовать возможности пакета email для создания email-сообщения, которое затем можно преобразовать в строку и отправить через sendmail(); см. примеры email.