Spec-Zone.ru › Python 3.8

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, метод SMTP connect() вызывается с этими параметрами во время инициализации. Если указано, 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. При использовании таким образом, команда SMTP QUIT автоматически выполняется при завершении оператора 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. Он сначала пытается использовать ESMTP EHLO.

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, этот метод сначала пытается использовать ESMTP EHLO. Этот метод вернет стандартное значение, если аутентификация прошла успешно, или может вызвать следующие исключения:

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)

Выполняет команду SMTP AUTH для указанного механизма аутентификации mechanism и обрабатывает ответ на запрос через authobject.

mechanism указывает механизм аутентификации, который будет аргументом команды AUTH; допустимые значения указаны в элементе auth в esmtp_features.

authobject должен быть вызываемым объектом, принимающим необязательный одиночный аргумент:

data = authobject(challenge=None)

Если необязательный ключевой аргумент initial_response_ok равен true, authobject() будет вызван первым без аргументов. Он может вернуть ASCII-строку «начального ответа» RFC 4954 str, которая будет закодирована и отправлена вместе с командой AUTH как указано ниже. Если сервер не поддерживает начальный ответ (например, потому что требует вызов), он должен вернуть None при вызове с challenge=None. Если initial_response_ok равен false, тогда authobject() не будет вызван с None.

Если проверка начального ответа вернула None, или если initial_response_ok равен false, authobject() будет вызван для обработки ответа сервера на вызов; аргумент challenge, который ему передается, будет bytes. Он должен вернуть ASCII-строку str 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 (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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API