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 задает таймаут в секундах для блокирующих операций, таких как попытка подключения (если не указан, используется глобальное значение таймаута по умолчанию). Если таймаут истекает, генерируетсяTimeoutError. Необязательный параметр source_address позволяет привязаться к определённому адресу источника в машине с несколькими сетевыми интерфейсами и/или к определённому TCP-порту источника. Он принимает пару (хост, порт) для сокета, к которому нужно привязаться, как адрес источника перед подключением. Если он опущен (или если хост или порт равны''и/или 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()выбрать доверенные сертификаты CA системы.Изменено в версии 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, это устанавливает ‘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). Если имя хоста оканчивается двоеточием (
':') и числом, этот суффикс будет удален, а число интерпретировано как номер порта для использования. Этот метод автоматически вызывается конструктором, если имя хоста указано во время создания экземпляра. Возвращает кортеж из двух элементов: код ответа и сообщение, отправленное сервером в ответ на подключение.Вызывает событие аудита аудита
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, вместо того, чтобы требовать вызов challenge/response.Изменено в версии 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как указано ниже. Если сервер не поддерживает начальный ответ (например, потому что требует вызов challenge), он должен вернутьNoneпри вызове сchallenge=None. Если initial_response_ok имеет значение false,authobject()не будет вызван первым сNone.Если проверка начального ответа возвращает
None, или если initial_response_ok имеет значение false,authobject()будет вызван для обработки ответа сервера на вызов; аргумент challenge, который ему передается, будетbytes. Он должен вернуть ASCIIstrdata, который будет закодирован в base64 и отправлен на сервер.Класс
SMTPпредоставляет реализацию для механизмов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 (одиночная строка будет обработана как список с одним адресом) и строка сообщения. Вызывающий может передать список параметров 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_addrsNone,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–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.10/library/smtplib.html