Spec-Zone.ru › Python 3.13

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, он используется как полное доменное имя локального узла в команде 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 — байты, которые собираются отправить на удалённый узел.

Изменено в версии 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. Если он указан, значения 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 и индикатора имени сервера (см. 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, а SMTPUTF8 и BODY=8BITMIME добавляются в mail_options.

Добавлено в версии 3.2.

Добавлено в версии 3.5: Поддержка интернационализированных адресов (SMTPUTF8).

SMTP.quit()

Завершить сеанс SMTP и закрыть соединение. Возвращает результат команды SMTP QUIT.

Также поддерживаются низкоуровневые методы, соответствующие стандартным командам SMTP/ESMTP HELP, RSET, NOOP, MAIL, RCPT и DATA. Обычно их не требуется вызывать напрямую, поэтому здесь они не описаны. Подробности см. в коде модуля.

Пример SMTP

В этом примере пользователю предлагается ввести адреса, необходимые для конверта сообщения (адреса «To» и «From»), а также сообщение для доставки. Обратите внимание: заголовки, которые должны быть включены в сообщение, необходимо добавить в сообщение при вводе; этот пример не обрабатывает заголовки RFC 822. В частности, адреса «To» и «From» необходимо явно включить в заголовки сообщения:

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–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/smtplib.html

Spec-Zone.ru

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