Spec-Zone.ru › Python 3.12

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

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

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

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

Этот модуль не работает или недоступен на платформах WebAssembly wasm32-emscripten и wasm32-wasi. Дополнительные сведения см. в разделе Платформы 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. При таком использовании команда 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, *, [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 — Simple Mail Transfer Protocol

Определение протокола 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

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

Все методы аутентификации, поддерживаемые 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; если он указан, оба параметра keyfile и certfile должны иметь значение None.

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

Изменено в версии 3.12: Устаревшие параметры keyfile и certfile удалены.

SMTPHeloError

Сервер некорректно ответил на приветствие HELO.

SMTPNotSupportedError

Сервер не поддерживает расширение STARTTLS.

RuntimeError

Интерпретатор Python не поддерживает SSL/TLS.

Изменено в версии 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; если указан 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

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

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

Spec-Zone.ru

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