Документация Python неофициальный перевод
Содержание страницы

smtplib – клиент протокола SMTPsmtplib – 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. При таком использовании команда SMTP QUIT отправляется автоматически при выходе из оператора 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 новыми командами, динамическое обнаружение команд, предоставляемых сервером, и определяются несколько дополнительных команд.

Объекты SMTPSMTP 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. Сначала он пробует 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 определяет, можно ли для методов аутентификации, которые это поддерживают, отправлять «начальный ответ» (initial response), как указано в RFC 4954, вместе с командой AUTH, а не требовать запроса/ответа (challenge/response).

Изменено в версии 3.5: SMTPNotSupportedError может быть возбуждено, и добавлен параметр initial_response_ok.

SMTP.auth(mechanism, authobject, *, initial_response_ok=True)

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

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

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

data = authobject(challenge=None)

Если необязательный именованный аргумент initial_response_ok равен true, сначала вызывается authobject() без аргументов. Он может вернуть «начальный ответ» RFC 4954 в виде ASCII str, который будет закодирован и отправлен с командой AUTH, как описано ниже. Если authobject() не поддерживает начальный ответ (например, потому что требует запроса), он должен вернуть 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(*, context=None)

Переводит SMTP-соединение в режим TLS (безопасность транспортного уровня). Все последующие SMTP-команды будут зашифрованы. После этого следует снова вызвать ehlo().

Если указаны keyfile и certfile, они используются для создания ssl.SSLContext.

Необязательный параметр context – это объект ssl.SSLContext; это альтернатива использованию keyfile и certfile, и если он указан, то keyfile и certfile должны быть None.

Если в течение этого сеанса ещё не выполнялась команда EHLO или HELO, метод сначала пытается выполнить ESMTP EHLO.

Изменено в версии 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, данный метод сначала пытается выполнить ESMTP EHLO. Если сервер поддерживает 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.helo_resp

Ответ на команду HELO, см. helo().

SMTP.ehlo_resp

Ответ на команду EHLO, см. ehlo().

SMTP.does_esmtp

Логическое значение, указывающее, поддерживает ли сервер ESMTP. См. ehlo().

SMTP.esmtp_features

Словарь названий расширений службы SMTP, поддерживаемых сервером. См. ehlo().

Пример SMTPSMTP 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: Примеры.