Spec-Zone.ru › Python 3.10

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 задает таймаут в секундах для блокирующих операций, таких как попытка подключения (если не указан, используется глобальное значение таймаута по умолчанию). Если таймаут истекает, генерируется TimeoutError. Необязательный параметр source_address позволяет привязаться к определённому адресу источника в машине с несколькими сетевыми интерфейсами и/или к определённому TCP-порту источника. Он принимает пару (хост, порт) для сокета, к которому нужно привязаться, как адрес источника перед подключением. Если он опущен (или если хост или порт равны '' и/или 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).

Изменено в версии 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. Он сначала пробует 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

Не был найден подходящий метод аутентификации.

Каждый из методов аутентификации, поддерживаемых 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)

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

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

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

data = authobject(challenge=None)

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

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

END_OF_DOCUMENT_MARKER

Методы низкого уровня, соответствующие стандартным командам 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

Spec-Zone.ru

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