smtplib
— Клиент протокола SMTP¶
Исходный код: Lib/smtplib.py.
Модуль smtplib
определяет объект клиентской сессии SMTP, который можно использовать для отправки почты на любую машину в Интернете с демоном SMTP или ESMTP listener. Подробности работы SMTP и ESMTP смотрите в RFC 821 (Simple Mail Transfer Protocol) и RFC 1869 (SMTP Service Extensions).
-
class
smtplib.
SMTP
(host='', port=0, local_hostname=None, [timeout, ]source_address=None)¶ Экземпляр
SMTP
инкапсулирует SMTP-соединение. Он имеет методы, поддерживающие полный набор операций SMTP и ESMTP. Если указаны необязательные параметры хоста и порта, то при инициализации вызывается метод SMTPconnect()
с этими параметрами. Если указано, local_hostname используется в качестве FQDN локального хоста в команде HELO/EHLO. В противном случае, имя локального хоста находится с помощьюsocket.getfqdn()
. Если вызовconnect()
возвращает что-либо, кроме кода успеха, выдается предупреждениеSMTPConnectError
. Необязательный параметр timeout задает таймаут в секундах для блокировки операций, таких как попытка соединения (если он не указан, будет использован глобальный таймаут по умолчанию). Если тайм-аут истекает, выдается сообщениеTimeoutError
. Необязательный параметр source_address позволяет привязываться к определенному адресу источника на машине с несколькими сетевыми интерфейсами и/или к определенному порту TCP источника. Он принимает кортеж (хост, порт), к которому сокет должен привязаться в качестве адреса источника перед подключением. Если значение опущено (или если host или port равны''
и/или 0 соответственно), будет использоваться поведение ОС по умолчанию.Для обычного использования вам понадобятся только методы инициализации/подключения,
sendmail()
иSMTP.quit()
. Пример приведен ниже.Класс
SMTP
поддерживает операторwith
. При его использовании команда SMTPQUIT
выдается автоматически при выходе из оператораwith
. Например:>>> from smtplib import SMTP >>> with SMTP("domain.org") as smtp: ... smtp.noop() ... (250, b'Ok') >>>
Вызывает auditing event
smtplib.send
с аргументамиself
,data
.Изменено в версии 3.3: Добавлена поддержка оператора
with
.Изменено в версии 3.3: добавлен аргумент source_address.
Добавлено в версии 3.5: Теперь поддерживается расширение SMTPUTF8 (RFC 6531).
Изменено в версии 3.9: Если параметр timeout установлен равным нулю, то будет вызван сигнал
ValueError
для предотвращения создания неблокирующего сокета
-
class
smtplib.
SMTP_SSL
(host='', port=0, local_hostname=None, keyfile=None, certfile=None, [timeout, ]context=None, source_address=None)¶ Экземпляр
SMTP_SSL
ведет себя точно так же, как и экземплярSMTP
.SMTP_SSL
следует использовать в ситуациях, когда SSL требуется с самого начала соединения и использованиеstarttls()
не подходит. Если host не указан, используется локальный хост. Если port равен нулю, используется стандартный порт SMTP-over-SSL (465). Необязательные аргументы local_hostname, timeout и source_address имеют то же значение, что и в классеSMTP
. context, также необязательный, может содержатьSSLContext
и позволяет настраивать различные аспекты безопасного соединения. Пожалуйста, прочитайте Соображения безопасности о лучших практиках.keyfile и certfile являются устаревшей альтернативой context и могут указывать на файл закрытого ключа и цепочки сертификатов в формате PEM для SSL-соединения.
Изменено в версии 3.3: Был добавлен контекст.
Изменено в версии 3.3: добавлен аргумент source_address.
Изменено в версии 3.4: Класс теперь поддерживает проверку имени хоста с помощью
ssl.SSLContext.check_hostname
и Server Name Indication (см.ssl.HAS_SNI
).Не рекомендуется, начиная с версии 3.6: keyfile и certfile устарели в пользу context. Вместо них используйте
ssl.SSLContext.load_cert_chain()
или позвольтеssl.create_default_context()
выбрать для вас сертификаты доверенных центров сертификации системы.Изменено в версии 3.9: Если параметр timeout установлен равным нулю, то будет вызван сигнал
ValueError
для предотвращения создания неблокирующего сокета
-
class
smtplib.
LMTP
(host='', port=LMTP_PORT, local_hostname=None, source_address=None[, timeout])¶ Протокол LMTP, который очень похож на ESMTP, в значительной степени основан на стандартном клиенте SMTP. Обычно для LMTP используются сокеты Unix, поэтому наш метод
connect()
должен поддерживать их, а также обычный сервер host:port. Необязательные аргументы local_hostname и source_address имеют то же значение, что и в классеSMTP
. Чтобы указать сокет Unix, вы должны использовать абсолютный путь для host, начинающийся с „/“.Аутентификация поддерживается, используя обычный механизм SMTP. При использовании сокета Unix, LMTP обычно не поддерживает или не требует аутентификации, но ваш пробег может быть разным.
Изменено в версии 3.9: Добавлен необязательный параметр timeout.
Также определена хорошая подборка исключений:
-
exception
smtplib.
SMTPException
¶ Подкласс
OSError
, который является базовым классом исключений для всех других исключений, предоставляемых этим модулем.Изменено в версии 3.4: SMTPException стал подклассом
OSError
.
-
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.
SMTPNotSupportedError
¶ Команда или опция не поддерживается сервером.
Добавлено в версии 3.5.
-
exception
smtplib.
SMTPAuthenticationError
¶ Аутентификация SMTP прошла неправильно. Скорее всего, сервер не принял предоставленную комбинацию имя пользователя/пароль.
См.также
- RFC 821 - Простой протокол передачи почты
Определение протокола для SMTP. Этот документ охватывает модель, порядок работы и детали протокола для SMTP.
- RFC 1869 - Расширения службы SMTP
Определение расширений ESMTP для SMTP. Здесь описывается структура для расширения SMTP новыми командами, поддерживается динамическое обнаружение команд, предоставляемых сервером, и определяется несколько дополнительных команд.
Объекты SMTP¶
Экземпляр SMTP
имеет следующие методы:
-
SMTP.
set_debuglevel
(level)¶ Установите уровень вывода отладочных сообщений. Значение 1 или
True
для level приводит к появлению отладочных сообщений для соединения и для всех сообщений, отправленных на сервер и полученных от него. Значение 2 для level приводит к тому, что эти сообщения маркируются по времени.Изменено в версии 3.5: Добавлен уровень отладки 2.
-
SMTP.
docmd
(cmd, args='')¶ Отправить команду cmd на сервер. Необязательный аргумент args просто конкатенируется с командой, разделяясь пробелом.
Возвращается кортеж, состоящий из числового кода ответа и фактической строки ответа (многострочные ответы объединяются в одну длинную строку).
При нормальной работе не должно быть необходимости в явном вызове этого метода. Он используется для реализации других методов и может быть полезен для тестирования частных расширений.
Если соединение с сервером будет потеряно во время ожидания ответа, будет выдано сообщение
SMTPServerDisconnected
.
-
SMTP.
connect
(host='localhost', port=0)¶ Подключение к хосту на заданном порту. По умолчанию используется стандартный SMTP-порт (25) для подключения к локальному хосту. Если имя хоста заканчивается двоеточием (
':'
), за которым следует число, этот суффикс будет удален, а число будет интерпретировано как номер порта, который нужно использовать. Этот метод автоматически вызывается конструктором, если при инстанцировании указан хост. Возвращает кортеж из кода ответа и сообщения, отправленного сервером в ответе на соединение.Вызывает auditing event
smtplib.connect
с аргументамиself
,host
,port
.
-
SMTP.
helo
(name='')¶ Идентифицируйте себя на SMTP-сервере с помощью
HELO
. Аргумент hostname по умолчанию означает полное доменное имя локального хоста. Сообщение, возвращаемое сервером, хранится как атрибутhelo_resp
объекта.При нормальной работе не должно быть необходимости в явном вызове этого метода. Он будет неявно вызываться
sendmail()
при необходимости.
-
SMTP.
ehlo
(name='')¶ Идентифицируйте себя для сервера 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
.
-
SMTP.
has_extn
(name)¶ Возвращает
True
, если name находится в наборе расширений служб SMTP, возвращаемых сервером,False
в противном случае. Регистр игнорируется.
-
SMTP.
verify
(address)¶ Проверка действительности адреса на данном сервере с помощью SMTP
VRFY
. Возвращает кортеж, состоящий из кода 250 и полного RFC 822 адреса (включая имя человека), если адрес пользователя действителен. В противном случае возвращается код ошибки SMTP 400 или выше и строка ошибки.Примечание
Многие сайты отключают SMTP
VRFY
для борьбы со спамерами.
-
SMTP.
login
(user, password, *, initial_response_ok=True)¶ Вход на SMTP-сервер, требующий аутентификации. Аргументами являются имя пользователя и пароль для аутентификации. Если в этой сессии не было предыдущей команды
EHLO
илиHELO
, этот метод сначала попробует ESMTPEHLO
. Этот метод вернется нормально, если аутентификация прошла успешно, или может вызвать следующие исключения:SMTPHeloError
Сервер не ответил должным образом на приветствие
HELO
.SMTPAuthenticationError
Сервер не принял комбинацию имя пользователя/пароль.
SMTPNotSupportedError
Команда
AUTH
не поддерживается сервером.SMTPException
Не найден подходящий метод аутентификации.
Каждый из методов аутентификации, поддерживаемых
smtplib
, пробуются по очереди, если они объявлены как поддерживаемые сервером. Список поддерживаемых методов аутентификации см. вauth()
. initial_response_ok передается вauth()
.Необязательный ключевой аргумент initial_response_ok определяет, может ли для методов аутентификации, которые его поддерживают, «начальный ответ», как указано в RFC 4954, быть отправлен вместе с командой
AUTH
, а не требовать вызова/ответа.Изменено в версии 3.5:
SMTPNotSupportedError
может быть поднят, и был добавлен параметр initial_response_ok.
-
SMTP.
auth
(mechanism, authobject, *, initial_response_ok=True)¶ Выдать команду
SMTP
AUTH
для указанного механизма аутентификации, и обработать ответ вызова через автообъект.mechanism указывает, какой механизм аутентификации должен использоваться в качестве аргумента команды
AUTH
; допустимыми значениями являются те, которые перечислены в элементеauth
командыesmtp_features
.authobject должен быть вызываемым объектом, принимающим необязательный единственный аргумент:
data = authobject(challenge=None)
Если необязательный ключевой аргумент initial_response_ok равен true,
authobject()
будет вызван первым без аргумента. Он может вернуть RFC 4954 «начальный ответ» ASCIIstr
, который будет закодирован и отправлен с командойAUTH
, как показано ниже. Еслиauthobject()
не поддерживает начальный ответ (например, потому что он требует вызова), он должен вернутьNone
при вызове с помощьюchallenge=None
. Если initial_response_ok равно false, тоauthobject()
не будет вызван первым с помощьюNone
.Если проверка начального ответа возвращает
None
, или если initial_response_ok ложно, будет вызванauthobject()
для обработки ответа вызова сервера; передаваемый ему аргумент challenge будетbytes
. Он должен вернуть ASCIIstr
данные, которые будут закодированы в base64 и отправлены на сервер.Класс
SMTP
предоставляетauthobjects
для механизмовCRAM-MD5
,PLAIN
иLOGIN
; они называютсяSMTP.auth_cram_md5
,SMTP.auth_plain
иSMTP.auth_login
соответственно. Все они требуют, чтобы свойстваuser
иpassword
экземпляраSMTP
были установлены в соответствующие значения.Пользовательский код обычно не требует прямого вызова
auth
, а может вместо этого вызвать методlogin()
, который по очереди опробует каждый из перечисленных механизмов в указанном порядке.auth
используется для облегчения реализации методов аутентификации, которые не поддерживаются (или еще не поддерживаются) непосредственноsmtplib
.Добавлено в версии 3.5.
-
SMTP.
starttls
(keyfile=None, certfile=None, context=None)¶ Переведите SMTP-соединение в режим TLS (Transport Layer Security). Все последующие команды SMTP будут зашифрованы. Затем следует снова вызвать
ehlo()
.Если предоставлены keyfile и certfile, они используются для создания
ssl.SSLContext
.Необязательный параметр context представляет собой объект
ssl.SSLContext
; Это альтернатива использованию keyfile и certfile, и если указаны keyfile и certfile, то они должны бытьNone
.Если в этом сеансе не было предыдущей команды
EHLO
илиHELO
, этот метод сначала пробует ESMTPEHLO
.Не рекомендуется, начиная с версии 3.6: keyfile и certfile устарели в пользу context. Вместо них используйте
ssl.SSLContext.load_cert_chain()
или позвольтеssl.create_default_context()
выбрать для вас сертификаты доверенных центров сертификации системы.SMTPHeloError
Сервер не ответил должным образом на приветствие
HELO
.SMTPNotSupportedError
Сервер не поддерживает расширение STARTTLS.
RuntimeError
Поддержка SSL/TLS недоступна вашему интерпретатору Python.
Изменено в версии 3.3: Был добавлен контекст.
Изменено в версии 3.4: Метод теперь поддерживает проверку имени хоста с помощью
SSLContext.check_hostname
и Server Name Indicator (см.HAS_SNI
).Изменено в версии 3.5: Ошибка, возникающая из-за отсутствия поддержки STARTTLS, теперь относится к подклассу
SMTPNotSupportedError
вместо базовогоSMTPException
.
-
SMTP.
sendmail
(from_addr, to_addrs, msg, mail_options=(), rcpt_options=())¶ Отправить почту. Необходимыми аргументами являются строка RFC 822 с адресом, список строк RFC 822 с адресами (пустая строка будет рассматриваться как список с 1 адресом) и строка сообщения. Вызывающая сторона может передать список опций ESMTP (таких как
8bitmime
) для использования в командахMAIL FROM
в качестве mail_options. Опции ESMTP (такие как командыDSN
), которые должны использоваться со всеми командамиRCPT
, могут быть переданы как rcpt_options. (Если вам нужно использовать разные опции ESMTP для разных получателей, вам придется использовать для отправки сообщения низкоуровневые методы, такие какmail()
,rcpt()
иdata()
).Примечание
Параметры from_addr и to_addrs используются для построения конверта сообщения, используемого транспортными агентами.
sendmail
никак не изменяет заголовки сообщений.msg может быть строкой, содержащей символы в диапазоне ASCII, или байтовой строкой. Строка кодируется в байты с помощью кодека ascii, а одиночные символы
\r
и\n
преобразуются в символы\r\n
. Байтовая строка не модифицируется.Если в этом сеансе не было предыдущей команды
EHLO
илиHELO
, этот метод сначала пробует ESMTPEHLO
. Если сервер выполняет ESMTP, ему будет передан размер сообщения и каждая из указанных опций (если опция входит в набор функций, рекламируемых сервером). ЕслиEHLO
не удается, будет выполнена попыткаHELO
и опции ESMTP будут подавлены.Этот метод вернется нормально, если почта принята хотя бы для одного получателя. В противном случае он вызовет исключение. То есть, если этот метод не вызывает исключения, то кто-то должен получить вашу почту. Если этот метод не вызывает исключения, он возвращает словарь с одной записью для каждого получателя, которому было отказано. Каждая запись содержит кортеж из кода ошибки SMTP и сопроводительного сообщения об ошибке, отправленного сервером.
Если
SMTPUTF8
включен в mail_options, и сервер поддерживает его, from_addr и to_addrs могут содержать символы, отличные от ASCII.Этот метод может вызвать следующие исключения:
SMTPRecipientsRefused
Всем получателям было отказано. Никто не получил почту. Атрибут
recipients
объекта исключения представляет собой словарь с информацией об отказавшихся получателях (подобный тому, который возвращается, когда хотя бы один получатель был принят).SMTPHeloError
Сервер не ответил должным образом на приветствие
HELO
.SMTPSenderRefused
Сервер не принял from_addr.
SMTPDataError
Сервер ответил с неожиданным кодом ошибки (кроме отказа получателя).
SMTPNotSupportedError
SMTPUTF8
было задано в mail_options, но не поддерживается сервером.
Если не указано иное, соединение будет открыто даже после возникновения исключения.
Изменено в версии 3.2: msg может быть байтовой строкой.
Изменено в версии 3.5: Добавлена поддержка
SMTPUTF8
, иSMTPNotSupportedError
может быть поднят вопрос, если указаноSMTPUTF8
, но сервер его не поддерживает.
-
SMTP.
send_message
(msg, from_addr=None, to_addrs=None, mail_options=(), rcpt_options=())¶ Это удобный метод для вызова
sendmail()
с сообщением, представленным объектомemail.message.Message
. Аргументы имеют то же значение, что и дляsendmail()
, за исключением того, что msg является объектомMessage
.Если from_addr равно
None
или to_addrs равноNone
,send_message
заполняет эти аргументы адресами, извлеченными из заголовков msg, как указано в RFC 5322: from_addr устанавливается в поле Sender, если оно присутствует, а в противном случае в поле From. to_addrs объединяет значения (если они есть) полей To, Cc и Bcc из msg. Если в сообщении присутствует ровно один набор заголовков Resent-*, обычные заголовки игнорируются, а вместо них используются заголовки Resent-*. Если сообщение содержит более одного набора заголовков Resent-*, возникает ошибкаValueError
, поскольку нет способа однозначно определить самый последний набор заголовков Resent-.send_message
сериализует msg, используяBytesGenerator
с\r\n
в качестве linesep, и вызываетsendmail()
для передачи полученного сообщения. Независимо от значений from_addr и to_addrs,send_message
не передает никаких Bcc или Resent-Bcc заголовков, которые могут появиться в msg. Если любой из адресов в from_addr и to_addrs содержит символы, не являющиеся символами ASCII, и сервер не рекламирует поддержкуSMTPUTF8
, возникает ошибкаSMTPNotSupported
. В противном случаеMessage
сериализуется с клоном своегоpolicy
с атрибутомutf8
установленным вTrue
, аSMTPUTF8
иBODY=8BITMIME
добавляются в mail_options.Добавлено в версии 3.2.
Добавлено в версии 3.5: Поддержка интернационализированных адресов (
SMTPUTF8
).
-
SMTP.
quit
()¶ Завершить сеанс SMTP и закрыть соединение. Верните результат команды SMTP
QUIT
.
Также поддерживаются низкоуровневые методы, соответствующие стандартным командам SMTP/ESMTP HELP
, RSET
, NOOP
, MAIL
, RCPT
и DATA
. Обычно их не нужно вызывать напрямую, поэтому они здесь не документируются. За подробностями обращайтесь к коду модуля.
Пример SMTP¶
Этот пример запрашивает у пользователя адреса, необходимые для конверта сообщения (адреса «Кому» и «От»), и сообщение, которое должно быть доставлено. Обратите внимание, что заголовки, которые должны быть включены в сообщение, должны быть включены в сообщение в том виде, в котором они введены; этот пример не выполняет никакой обработки заголовков RFC 822. В частности, адреса „To“ и „From“ должны быть включены в заголовки сообщения в явном виде.
import smtplib
def prompt(prompt):
return input(prompt).strip()
fromaddr = prompt("From: ")
toaddrs = prompt("To: ").split()
print("Enter message, end with ^D (Unix) or ^Z (Windows):")
# Add the From: and To: headers at the start!
msg = ("From: %s\r\nTo: %s\r\n\r\n"
% (fromaddr, ", ".join(toaddrs)))
while True:
try:
line = input()
except EOFError:
break
if not line:
break
msg = msg + line
print("Message length is", len(msg))
server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
Примечание
В общем, вы захотите использовать возможности пакета email
для создания почтового сообщения, которое затем можно отправить через send_message()
; см. email: Примеры.