smtplib
— Клиент протокола SMTP¶
Модуль smtplib
определяет объект сеанса клиента SMTP, который можно
использовать для отправки почты на любой компьютер в Интернете с помощью демона
прослушивателя SMTP или ESMTP. Подробные сведения о работе SMTP и ESMTP см. в
RFC 821 (простой протокол передачи почты) и RFC 1869 (расширения службы
SMTP).
-
class
smtplib.
SMTP
(host='', port=0, local_hostname=None, [timeout, ]source_address=None)¶ Экземпляр
SMTP
инкапсулирует соединение SMTP. В нем содержатся методы, поддерживающие полный набор SMTP и ESMTP операций. Если указаны необязательные параметры host и port, метод SMTPconnect()
вызывается с этими параметрами во время инициализации. Если указано, local_hostname используется как полное доменное имя локального хоста в команде HELO/EHLO. В противном случае имя локального хоста будет найдено с использованиемsocket.getfqdn()
. Если вызовconnect()
возвращает что-либо, кроме кода успеха, возникаетSMTPConnectError
. Необязательный параметр timeout указывает тайм-аут в секундах для блокирующих операций, таких как попытка подключения (если не указан, будет использоваться глобальная настройка тайм-аута по умолчанию). По истечении тайм-аута вызываетсяsocket.timeout
. Необязательный параметр source_address позволяет выполнить привязку к определенному адресу источника на машине с несколькими сетевыми интерфейсами и/или к определенному TCP- порту источника. Для подключения сокета в качестве адреса источника перед подключением требуется 2-кортеж (хост, порт). Если пропущено (или если у хоста или порта значение''
и/или 0 соответственно), будет использоваться поведение ОС по умолчанию.Для нормального использования вам потребуются только методы инициализации/подключения,
sendmail()
иSMTP.quit()
. Пример приведен ниже.Класс
SMTP
поддерживает операторwith
. При таком использовании команда SMTPQUIT
запускается автоматически при выходе из оператораwith
. Например.:>>> from smtplib import SMTP >>> with SMTP("domain.org") as smtp: ... smtp.noop() ... (250, b'Ok') >>>
Все команды будут вызывать событие аудита
smtplib.SMTP.send
с аргументамиself
иdata
, гдеdata
— байты, которые будут отправлены на удаленный хост.Изменено в версии 3.3: Добавлен оператор
with
.Изменено в версии 3.3: Добавлен аргумент source_address.
Добавлено в версии 3.5: Теперь поддерживается расширение SMTPUTF8 (RFC 6531).
-
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-через-SSL (465). У необязательных аргументов local_hostname, timeout и source_address то же значение, что и в классеSMTP
. context, также необязательный, может содержатьSSLContext
и позволяет настраивать различные аспекты безопасного соединения. Пожалуйста, прочтите Соображения безопасности, чтобы узнать о передовых методиках.keyfile и certfile являются устаревшей альтернативой context и могут указывать на закрытый ключ в формате PEM и файл цепочки сертификатов для SSL-соединения.
Изменено в версии 3.3: Был добавлен context.
Изменено в версии 3.3: Добавлен аргумент source_address.
Изменено в версии 3.4: Класс теперь поддерживает проверку имени хоста с
ssl.SSLContext.check_hostname
и Индикация имени сервера (SNI) (см.ssl.HAS_SNI
).Не рекомендуется, начиная с версии 3.6: keyfile и certfile устарели в пользу context. Вместо них используйте
ssl.SSLContext.load_cert_chain()
или позвольтеssl.create_default_context()
выбрать за вас доверенные сертификаты CA системы.
-
class
smtplib.
LMTP
(host='', port=LMTP_PORT, local_hostname=None, source_address=None)¶ Протокол LMTP, очень похожий на ESMTP, во многом основан на стандартном SMTP-клиенте. Обычно для LMTP используются сокеты Unix, поэтому наш метод
connect()
должен поддерживать его, а также обычный сервер host:port. У необязательных аргументов local_hostname и source_address то же значение, что и в классеSMTP
. Чтобы указать сокет Unix, вы должны использовать абсолютный путь для host, начиная с «/».Поддерживается аутентификация с использованием обычного механизма SMTP. При использовании сокета Unix LMTP обычно не поддерживает и не требует аутентификации, но ваш опыт может отличаться.
Также определен хороший набор исключений:
-
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: Added debuglevel 2.
-
SMTP.
docmd
(cmd, args='')¶ Отправить на сервер команду cmd. Необязательный аргумент args просто присоединяется к команде и разделяется пробелом.
Возвращает 2-кортеж, состоящий из числового кода ответа и фактической строки ответа (многострочные ответы объединяются в одну длинную строку)
При нормальной работе нет необходимости явно вызывать данный метод. Он используется для реализации других методов и может полезен для тестирования частных расширений.
Если соединение с сервером будет потеряно во время ожидания ответа, будет активирован
SMTPServerDisconnected
.
-
SMTP.
connect
(host='localhost', port=0)¶ Подключиться к хосту на заданном порту. По умолчанию установлено соединение с локальным хостом через стандартный порт SMTP (25). Если имя хоста заканчивается двоеточием (
':'
), за которым следует число, этот суффикс будет удален, а номер интерпретируется как номер порта для использования. Метод автоматически вызывается конструктором, если во время создания экземпляра указан host. Возвращает двухкортежный код ответа и сообщение, отправленное сервером в его ответе на соединение.Вызывает событие аудита
smtplib.connect
с аргументамиself
,host
,port
.
-
SMTP.
helo
(name='')¶ Поздороваться с SMTP-сервером, используя
HELO
. По умолчанию в качестве аргумента имени хоста используется полное доменное имя локального хоста. Сообщение, возвращаемое сервером, сохраняется как атрибутhelo_resp
объекта.При нормальной работе нет необходимости явно вызывать этот метод. Он будет неявно вызываться
sendmail()
при необходимости.
-
SMTP.
ehlo
(name='')¶ Поздороваться с сервером ESMTP, используя
EHLO
. По умолчанию в качестве аргумента имени хоста используется полное доменное имя локального хоста. Изучите ответ для параметра 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 и обработать ответ на запрос через authobject.mechanism указывает, какой механизм аутентификации должен использоваться в качестве аргумента для команды
AUTH
; допустимые значения перечислены в элементеauth
esmtp_features
.authobject должен быть вызываемым объектом, принимающим необязательный единственный аргумент:
data = authobject(challenge=None)Если у необязательного ключевого аргумента initial_response_ok истинное значение, сначала будет вызываться
authobject()
без аргумента. Он может вернуть RFC 4954 «начальный ответ» ASCIIstr
, который будет закодирован и отправлен с помощью командыAUTH
, как показано ниже. Еслиauthobject()
не поддерживает начальный ответ (например, потому что он требует запроса), он должен вернутьNone
при вызове сchallenge=None
. Если initial_response_ok ложно, тоauthobject()
не будет вызываться первым сNone
.Если проверка первоначального ответа возвращает
None
, или если initial_response_ok ложно, будет вызванauthobject()
для обработки ответа на запрос сервера; переданный аргумент challenge будетbytes
. Он должен вернуть ASCIIstr
data, который будет закодирован в 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 (Безопасность Транспортного Уровня). Все последующие команды SMTP будут зашифрованы. Затем вам следует снова вызвать
ehlo()
.Если предоставлены keyfile и certfile, они используются для создания
ssl.SSLContext
.Необязательный параметр context — объект
ssl.SSLContext
; является альтернативой использования ключевого файла и файла сертификата, и если указано, как keyfile, так и certfile должны бытьNone
.Если в сеансе не было предыдущей команды
EHLO
илиHELO
, данный метод сначала пытается выполнить ESMTPEHLO
.Не рекомендуется, начиная с версии 3.6: keyfile и certfile устарели в пользу context. Вместо этого используйте
ssl.SSLContext.load_cert_chain()
или позвольтеssl.create_default_context()
выбрать для вас доверенные сертификаты CA системы.SMTPHeloError
- Сервер не ответил должным образом на приветствие
HELO
. SMTPNotSupportedError
- Сервер не поддерживает расширение STARTTLS.
RuntimeError
- Поддержка SSL/TLS недоступна для вашего интерпретатора Python.
Изменено в версии 3.3: Был добавлен context.
Изменено в версии 3.4: Теперь метод поддерживает проверку имени хоста с помощью
SSLContext.check_hostname
и Индикатор имени сервера (SNI) (см.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¶
В данном примере пользователю предлагается ввести адреса, необходимые для конверта сообщения (адреса «To» и «From»), и сообщение, которое необходимо доставить. Обратите внимание, что заголовки, которые должны быть присутствовать в сообщении, должны быть включены в вводимое сообщение; в этом примере не выполняется обработка заголовков 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):")
# Добавить заголовки From: и To: в начало!
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: примеры.