Содержание страницы
smtplib – клиент протокола SMTP¶smtplib – SMTP protocol client
Исходный код: Lib/smtplib.py
Модуль smtplib определяет объект сеанса клиента SMTP, который можно использовать для отправки почты на любой компьютер в сети с демоном-слушателем SMTP или ESMTP. Подробнее о работе SMTP и ESMTP см. в RFC 821 (Simple Mail Transfer Protocol) и RFC 1869 (SMTP Service Extensions).
Доступность: не WASI.
Этот модуль не работает или недоступен на WebAssembly. Подробнее см. платформы WebAssembly.
- class smtplib.SMTP(host='', port=0, local_hostname=None, [timeout, ]source_address=None)¶
Экземпляр
SMTPинкапсулирует SMTP-соединение. Он содержит методы, поддерживающие полный набор операций SMTP и ESMTP.Если параметр host задан истинным значением,
SMTP.connect()вызывается с host и port автоматически при создании объекта; в противном случаеconnect()необходимо вызывать вручную.Если указано, local_hostname используется как полное доменное имя (FQDN) локального хоста в команде HELO/EHLO. В противном случае имя локального хоста определяется с помощью
socket.getfqdn(). Если вызовconnect()возвращает код, отличный от успешного, возбуждается исключениеSMTPConnectError. Необязательный параметр timeout задаёт тайм-аут в секундах для блокирующих операций, таких как попытка подключения (если не указан, используется глобальная настройка тайм-аута по умолчанию). Если тайм-аут истекает, возбуждаетсяTimeoutError. Необязательный параметр source_address позволяет привязаться к определённому исходному адресу на машине с несколькими сетевыми интерфейсами и/или к определённому исходному TCP-порту. Он принимает кортеж из двух элементов(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– это байты, которые будут отправлены удалённому хосту.- default_port¶
Порт, используемый по умолчанию для SMTP-подключений (25).
Изменено в версии 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, *, [timeout, ]context=None, source_address=None)¶
Экземпляр
SMTP_SSLведёт себя точно так же, как экземплярыSMTP.SMTP_SSLследует использовать в ситуациях, когда SSL требуется с самого начала соединения, а использованиеSMTP.starttls()не подходит.Если параметр host задан истинным значением,
SMTP.connect()вызывается с host и port автоматически при создании объекта; в противном случаеSMTP.connect()необходимо вызывать вручную.Необязательные аргументы local_hostname, timeout и source_address имеют тот же смысл, что и в классе
SMTP. context, также необязательный, может содержатьSSLContextи позволяет настраивать различные аспекты безопасного соединения. Ознакомьтесь с разделом Рекомендации по безопасности для получения передовых практик.- default_port¶
Порт по умолчанию для SMTP-соединений через SSL (465).
Изменено в версии 3.3: был добавлен параметр context.
Изменено в версии 3.3: Добавлен аргумент source_address.
Изменено в версии 3.4: Теперь класс поддерживает проверку имени хоста с помощью
ssl.SSLContext.check_hostnameи Server Name Indication (см.ssl.HAS_SNI).Изменено в версии 3.9: Если параметр timeout установлен в ноль, будет возбуждено
ValueError, чтобы предотвратить создание неблокирующего сокета.Изменено в версии 3.12: Устаревшие параметры keyfile и certfile были удалены.
- 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, здесь атрибут '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 Objects
Экземпляр 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). Если имя хоста заканчивается на двоеточие (
':'), за которым следует число, этот суффикс отбрасывается, а число интерпретируется как номер порта для использования. Этот метод автоматически вызывается конструктором, если хост указан при создании экземпляра. Возвращает кортеж из двух элементов: код ответа и сообщение, отправленное сервером в своём ответе на подключение.Если порт не изменён относительно значения по умолчанию 0, значение атрибута
default_portиспользуется.Вызывает событие аудита
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 определяет, можно ли для методов аутентификации, которые это поддерживают, отправлять «начальный ответ» (initial response), как указано в RFC 4954, вместе с командой
AUTH, а не требовать запроса/ответа (challenge/response).Изменено в версии 3.5:
SMTPNotSupportedErrorможет быть возбуждено, и добавлен параметр initial_response_ok.
- SMTP.auth(mechanism, authobject, *, initial_response_ok=True)¶
Отправляет команду
SMTPAUTHдля указанного механизма аутентификации mechanism и обрабатывает ответ на запрос (challenge response) через authobject.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 равен 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(*, context=None)¶
Переводит SMTP-соединение в режим TLS (безопасность транспортного уровня). Все последующие SMTP-команды будут зашифрованы. После этого следует снова вызвать
ehlo().Если указаны keyfile и certfile, они используются для создания
ssl.SSLContext.Необязательный параметр context – это объект
ssl.SSLContext; это альтернатива использованию keyfile и certfile, и если он указан, то keyfile и certfile должны бытьNone.Если в течение этого сеанса ещё не выполнялась команда
EHLOилиHELO, метод сначала пытается выполнить ESMTPEHLO.Изменено в версии 3.12: Устаревшие параметры keyfile и certfile были удалены.
SMTPHeloErrorСервер некорректно ответил на приветствие
HELO.SMTPNotSupportedErrorСервер не поддерживает расширение STARTTLS.
RuntimeErrorИнтерпретатор Python не поддерживает SSL/TLS.
Изменено в версии 3.3: был добавлен параметр context.
Изменено в версии 3.4: Теперь метод поддерживает проверку имени хоста с помощью
ssl.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 (если передана просто строка, она будет считаться списком из одного адреса) и строка сообщения. Вызывающий код может передать список ESMTP-опций (например,
"8bitmime"), которые будут использоваться в командахMAIL FROM, через параметр mail_options. ESMTP-опции (например, командыDSN), которые должны применяться ко всем командамRCPT, можно передать через параметр rcpt_options. Каждая опция должна быть передана в виде строки, содержащей полный текст опции, включая возможный ключ (например,"NOTIFY=SUCCESS,FAILURE"). (Если нужно использовать разные 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Всем получателям было отказано. Письмо не доставлено никому.
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, возбуждаетсяSMTPNotSupportedError. В противном случае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 имеет следующие атрибуты:
Пример SMTP¶SMTP Example
Этот пример запрашивает у пользователя адреса, необходимые для конверта сообщения (адреса «Кому» и «От»), а также само сообщение для отправки. Обратите внимание, что заголовки, которые должны быть включены в сообщение, должны быть введены в самом сообщении; этот пример не выполняет никакой обработки заголовков RFC 822. В частности, адреса «Кому» и «От» должны быть явно указаны в заголовках сообщения:
import smtplib
def prompt(title):
return input(title).strip()
from_addr = prompt("From: ")
to_addrs = prompt("To: ").split()
print("Enter message, end with ^D (Unix) or ^Z (Windows):")
# Добавьте заголовки From: и To: в начало!
lines = [f"From: {from_addr}", f"To: {', '.join(to_addrs)}", ""]
while True:
try:
line = input()
except EOFError:
break
else:
lines.append(line)
msg = "\r\n".join(lines)
print("Message length is", len(msg))
server = smtplib.SMTP("localhost")
server.set_debuglevel(1)
server.sendmail(from_addr, to_addrs, msg)
server.quit()
Примечание
В общем случае рекомендуется использовать возможности пакета email для создания сообщения электронной почты, которое затем можно отправить через send_message(); см. email: Примеры.