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-порту. Он принимает пару (хост, порт) для сокета, к которому нужно привязаться в качестве исходного адреса до подключения. Если опущено (или если 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).
Изменено в версии 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 через 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()выбрать доверенные сертификаты ЦС системы.Изменено в версии 3.9: Если параметр timeout установлен в ноль, будет поднято исключение
ValueErrorдля предотвращения создания неблокирующего сокета.
-
class smtplib.LMTP(host='', port=LMTP_PORT, local_hostname=None, source_address=None[, timeout]) -
Протокол LMTP, очень похожий на ESMTP, в значительной степени основан на стандартном клиенте SMTP. Для LMTP часто используются Unix-сокеты, поэтому наш метод
connect()должен поддерживать это, а также обычный хост:порт сервер. Необязательные аргументы 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, это устанавливает «отправитель» в строку, которую 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). Если имя хоста заканчивается двоеточием (
':') и числом, этот суффикс будет удален, а число будет интерпретировано как номер порта. Этот метод автоматически вызывается конструктором, если при инициализации был указан хост. Возвращает кортеж из двух элементов: код ответа и сообщение, отправленное сервером в ответ на подключение.Вызывает событие аудита
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) -
Выполнить команду
SMTPAUTHдля указанного механизма аутентификации mechanism и обработать ответ на вызов с помощью authobject.mechanism указывает, какой механизм аутентификации использовать в качестве аргумента для команды
AUTH; допустимые значения перечислены в элементеauthотesmtp_features.authobject должен быть вызываемым объектом, принимающим необязательный единственный аргумент:
data = authobject(challenge=None)
Если необязательный ключевой аргумент initial_response_ok равен true,
authobject()будет вызван первым без аргументов. Он может вернуть ASCII «начальный ответ» RFC 4954str, который будет закодирован и отправлен с командойAUTHниже. Еслиauthobject()не поддерживает начальный ответ (например, потому что требует вызова), он должен вернутьNoneпри вызове сchallenge=None. Если initial_response_ok равен false,authobject()не будет вызван первым сNone.Если проверка начального ответа возвращает
None, или если initial_response_ok равен false,authobject()будет вызван для обработки ответа сервера на вызов; аргумент challenge, который ему передаётся, будетbytes. Он должен вернуть ASCIIstrdata, который будет закодирован в 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()выбрать доверенные сертификаты 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, этот метод сначала попробует использовать 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. В частности, адреса «Кому» и «От» должны быть явно указаны в заголовках сообщения.
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.9/library/smtplib.html