smtplib — Клиент протокола SMTP
Исходный код: Lib/smtplib.py
Модуль 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 используется в качестве полного доменного имени (FQDN) хоста в команде HELO/EHLO. В противном случае полное доменное имя хоста находится с помощьюsocket.getfqdn(). Если вызовconnect()возвращает что-либо кроме кода успеха, генерируется исключениеSMTPConnectError. Необязательный параметр timeout задаёт таймаут в секундах для блокирующих операций, таких как попытка подключения (если не указан, используется глобальная настройка таймаута по умолчанию). Если таймаут истечёт, будет выброшено исключениеsocket.timeout. Необязательный параметр source_address позволяет привязаться к определённому адреса источника в машине с несколькими сетевыми интерфейсами и/или к определённому порту TCP источника. Он принимает кортеж из 2 элементов (host, port) для сокета, к которому необходимо привязаться в качестве адреса источника перед подключением. Если опущен (или если 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') >>>Все команды сгенерируют событие аудита событие аудита
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-over-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и Server Name Indication (см.ssl.HAS_SNI).Устарело начиная с версии 3.6: keyfile и certfile устарели в пользу context. Используйте
ssl.SSLContext.load_cert_chain()вместо этого или позвольтеssl.create_default_context()выбрать доверенные сертификаты ЦС системы для вас.
-
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-сокетa 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: Добавлен уровень отладки 2.
-
SMTP.docmd(cmd, args='') -
Отправляет команду cmd на сервер. Дополнительный аргумент args просто добавляется к команде, отделяясь пробелом.
Возвращает кортеж из 2 элементов: числовой код ответа и строку фактического ответа (многострочные ответы объединяются в одну длинную строку).
В нормальном режиме явно вызывать этот метод не нужно. Он используется для реализации других методов и может быть полезен для тестирования частных расширений.
Если соединение с сервером теряется во время ожидания ответа, будет поднято исключение
SMTPServerDisconnected.
-
SMTP.connect(host='localhost', port=0) -
Подключается к хосту на указанном порту. По умолчанию подключается к локальному хосту на стандартном порте SMTP (25). Если имя хоста оканчивается двоеточием (
':') и числом, этот суффикс будет удален, а число интерпретируется как номер порта для использования. Этот метод автоматически вызывается конструктором, если хост указан во время создания экземпляра. Возвращает кортеж из 2 элементов: код ответа и сообщение, отправленное сервером в ответ на подключение.Вызывает событие аудита аудита
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 -
Не был найден подходящий метод аутентификации.
Если сервер рекламирует поддержку нескольких методов аутентификации, они будут перепробованы в определенном порядке. Список поддерживаемых методов аутентификации см. в
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) -
Выполняет команду
SMTPAUTHдля указанного механизма аутентификации mechanism и обрабатывает ответ на запрос через authobject.mechanism указывает механизм аутентификации, который будет аргументом команды
AUTH; допустимые значения указаны в элементеauthвesmtp_features.authobject должен быть вызываемым объектом, принимающим необязательный одиночный аргумент:
data = authobject(challenge=None)
Если необязательный ключевой аргумент initial_response_ok равен true,
authobject()будет вызван первым без аргументов. Он может вернуть ASCII-строку «начального ответа» RFC 4954str, которая будет закодирована и отправлена вместе с командойAUTHкак указано ниже. Если сервер не поддерживает начальный ответ (например, потому что требует вызов), он должен вернутьNoneпри вызове сchallenge=None. Если initial_response_ok равен false, тогдаauthobject()не будет вызван сNone.Если проверка начального ответа вернула
None, или если initial_response_ok равен false,authobject()будет вызван для обработки ответа сервера на вызов; аргумент challenge, который ему передается, будетbytes. Он должен вернуть ASCII-строкуstrdata, которая будет закодирована в 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, метод сначала попытается использовать расширенный SMTP (EHLO).Устарело начиная с версии 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и 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, этот метод сначала попытается использовать расширенный SMTP (EHLO). Если сервер поддерживает 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. В частности, адреса «Кому» и «От» должны быть явно указаны в заголовках сообщения.
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: Примеры.
© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.8/library/smtplib.html