Spec-Zone.ru › Python 3.14

smtplib — клиент протокола SMTP

Исходный код: Lib/smtplib.py

Модуль smtplib определяет объект сеанса SMTP-клиента, который можно использовать для отправки почты на любой компьютер в Интернете, на котором работает прослушивающий демон SMTP или ESMTP. Сведения о работе SMTP и ESMTP см. в RFC 821 (простой протокол передачи почты) и RFC 1869 (расширения службы SMTP).

Доступность: недоступен в WASI.

Этот модуль не работает или недоступен в WebAssembly. Подробнее см. в разделе Платформы WebAssembly.

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-порту источника. Он принимает 2-кортеж (host, port), к которому сокет привязывается в качестве адреса источника перед подключением. Если параметр не задан (или если host или port равны '' и/или 0 соответственно), используется поведение ОС по умолчанию.

В обычном случае вам понадобятся только методы инициализации/подключения, sendmail() и SMTP.quit(). Пример приведён ниже.

Класс SMTP поддерживает инструкцию with. При таком использовании команда QUIT SMTP автоматически отправляется при выходе из инструкции 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, *, [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 и позволяет настраивать различные параметры защищённого соединения. Рекомендации по обеспечению безопасности см. в разделе Рекомендации по безопасности.

Изменено в версии 3.3: Добавлен параметр context.

Изменено в версии 3.3: Добавлен аргумент source_address.

Изменено в версии 3.4: Теперь класс поддерживает проверку имени хоста с помощью ssl.SSLContext.check_hostname и индикацию имени сервера (см. 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() должен поддерживать их наряду с обычным сервером host:port. Необязательные аргументы 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 указывает, можно ли для поддерживающих это методов аутентификации отправить вместе с командой AUTH «начальный ответ», определённый в RFC 4954, вместо использования схемы запрос/ответ.

Изменено в версии 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 str «начального ответа» согласно RFC 4954; эти данные будут закодированы и отправлены вместе с командой AUTH, как описано ниже. Если authobject() не поддерживает начальный ответ (например, поскольку ему требуется запрос), при вызове с challenge=None он должен вернуть 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 (Transport Layer Security). Все последующие команды SMTP будут зашифрованы. После этого следует снова вызвать ehlo().

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

Необязательный параметр context — это объект ssl.SSLContext; он служит альтернативой использованию файлов ключа и сертификата. Если он указан, параметры 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

В mail_options указан SMTPUTF8, который сервер не поддерживает.

Если не указано иное, соединение остаётся открытым даже после вызова исключения.

Изменено в версии 3.2: msg может быть байтовой строкой.

Изменено в версии 3.5: Добавлена поддержка SMTPUTF8; если указан SMTPUTF8, но сервер его не поддерживает, может быть вызвано исключение SMTPNotSupportedError.

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; в mail_options добавляются SMTPUTF8 и BODY=8BITMIME.

Добавлено в версии 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().

Пример SMTP

В этом примере у пользователя запрашиваются адреса, необходимые для конверта сообщения (адреса «Кому» и «От»), и текст сообщения для отправки. Обратите внимание: заголовки, которые должны входить в сообщение, необходимо включить в текст сообщения при вводе; в этом примере обработка заголовков 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):")

# Add the From: and To: headers at the start!
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: примеры.

© 2001 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.14/library/smtplib.html

Spec-Zone.ru

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