smtplib.md
1> **Источник:** https://python-all.ru/3.16/library/smtplib.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `smtplib` – клиент протокола SMTP89**Исходный код:** [Lib/smtplib.py](https://python-all.ru/src/main/Lib/smtplib.py)1011---1213Модуль `smtplib` определяет объект сеанса клиента SMTP, который можно использовать для отправки почты на любой компьютер в сети с демоном-слушателем SMTP или ESMTP. Подробнее о работе SMTP и ESMTP см. в [**RFC 821**](https://python-all.ru/3.16/library/smtplib.html) (Simple Mail Transfer Protocol) и [**RFC 1869**](https://python-all.ru/3.16/library/smtplib.html) (SMTP Service Extensions).1415[Доступность](https://python-all.ru/3.16/library/intro.html#availability): не WASI.1617Этот модуль не работает или недоступен на WebAssembly. Подробнее см. [платформы WebAssembly](https://python-all.ru/3.16/library/intro.html#wasm-availability).1819#### `class smtplib.SMTP(host='', port=0, local_hostname=None, [timeout, ]source_address=None)`2021Экземпляр `SMTP` инкапсулирует SMTP-соединение. Он содержит методы, поддерживающие полный набор операций SMTP и ESMTP.2223Если параметр host задан истинным значением, [`SMTP.connect()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.connect) вызывается с host и port автоматически при создании объекта; в противном случае `connect()` необходимо вызывать вручную.2425Если указано, *local\_hostname* используется как полное доменное имя (FQDN) локального хоста в команде HELO/EHLO. В противном случае имя локального хоста определяется с помощью [`socket.getfqdn()`](https://python-all.ru/3.16/library/socket.html#socket.getfqdn). Если вызов [`connect()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.connect) возвращает код, отличный от успешного, возбуждается исключение [`SMTPConnectError`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPConnectError). Необязательный параметр *timeout* задаёт тайм-аут в секундах для блокирующих операций, таких как попытка подключения (если не указан, используется глобальная настройка тайм-аута по умолчанию). Если тайм-аут истекает, возбуждается [`TimeoutError`](https://python-all.ru/3.16/library/exceptions.html#TimeoutError). Необязательный параметр *source\_address* позволяет привязаться к определённому исходному адресу на машине с несколькими сетевыми интерфейсами и/или к определённому исходному TCP-порту. Он принимает кортеж из двух элементов `(host, port)`, к которому сокет должен привязаться как к своему исходному адресу перед подключением. Если параметр опущен (или если *host* или *port* равны `''` и/или `0` соответственно), будет использовано поведение ОС по умолчанию.2627Для обычного использования достаточно методов инициализации/подключения, [`sendmail()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.sendmail) и [`SMTP.quit()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.quit). Пример приведен ниже.2829Класс `SMTP` поддерживает оператор [`with`](https://python-all.ru/3.16/reference/compound_stmts.html#with). При таком использовании команда SMTP `QUIT` отправляется автоматически при выходе из оператора `with`. Например:3031```python32>>> from smtplib import SMTP33>>> with SMTP("domain.org") as smtp:34... smtp.noop()35...36(250, b'Ok')37>>>38```3940Все команды вызывают [событие аудита](https://python-all.ru/3.16/library/sys.html#auditing) `smtplib.SMTP.send` с аргументами `self` и `data`, где `data` – это байты, которые будут отправлены удалённому хосту.4142#### `default_port`4344Порт, используемый по умолчанию для SMTP-подключений (25).4546Изменено в версии 3.3: Добавлена поддержка оператора [`with`](https://python-all.ru/3.16/reference/compound_stmts.html#with).4748Изменено в версии 3.3: Добавлен аргумент *source\_address*.4950Добавлено в версии 3.5: Теперь поддерживается расширение SMTPUTF8 ([**RFC 6531**](https://python-all.ru/3.16/library/smtplib.html)).5152Изменено в версии 3.9: Если параметр *timeout* установлен в ноль, будет возбуждено исключение [`ValueError`](https://python-all.ru/3.16/library/exceptions.html#ValueError), чтобы предотвратить создание неблокирующего сокета.5354#### `class smtplib.SMTP_SSL(host='', port=0, local_hostname=None, *, [timeout, ]context=None, source_address=None)`5556Экземпляр `SMTP_SSL` ведёт себя точно так же, как экземпляры [`SMTP`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP). `SMTP_SSL` следует использовать в ситуациях, когда SSL требуется с самого начала соединения, а использование [`SMTP.starttls()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.starttls) не подходит.5758Если параметр host задан истинным значением, [`SMTP.connect()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.connect) вызывается с host и port автоматически при создании объекта; в противном случае `SMTP.connect()` необходимо вызывать вручную.5960Необязательные аргументы *local\_hostname*, *timeout* и *source\_address* имеют тот же смысл, что и в классе [`SMTP`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP). *context*, также необязательный, может содержать [`SSLContext`](https://python-all.ru/3.16/library/ssl.html#ssl.SSLContext) и позволяет настраивать различные аспекты безопасного соединения. Ознакомьтесь с разделом [Рекомендации по безопасности](https://python-all.ru/3.16/library/ssl.html#ssl-security) для получения передовых практик.6162#### `default_port`6364Порт по умолчанию для SMTP-соединений через SSL (465).6566Изменено в версии 3.3: был добавлен параметр *context*.6768Изменено в версии 3.3: Добавлен аргумент *source\_address*.6970Изменено в версии 3.4: Теперь класс поддерживает проверку имени хоста с помощью [`ssl.SSLContext.check_hostname`](https://python-all.ru/3.16/library/ssl.html#ssl.SSLContext.check_hostname) и *Server Name Indication* (см. [`ssl.HAS_SNI`](https://python-all.ru/3.16/library/ssl.html#ssl.HAS_SNI)).7172Изменено в версии 3.9: Если параметр *timeout* установлен в ноль, будет возбуждено [`ValueError`](https://python-all.ru/3.16/library/exceptions.html#ValueError), чтобы предотвратить создание неблокирующего сокета.7374Изменено в версии 3.12: Устаревшие параметры *keyfile* и *certfile* были удалены.7576#### `class smtplib.LMTP(host='', port=LMTP_PORT, local_hostname=None, source_address=None[, timeout])`7778Протокол LMTP, очень похожий на ESMTP, во многом основан на стандартном клиенте SMTP. Для LMTP часто используются Unix-сокеты, поэтому наш метод [`connect()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.connect) должен поддерживать как их, так и обычный сервер вида хост:порт. Необязательные аргументы *local\_hostname* и *source\_address* имеют то же значение, что и в классе [`SMTP`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP). Чтобы указать Unix-сокет, необходимо использовать абсолютный путь для *host*, начинающийся с '/'.7980Поддерживается аутентификация с использованием обычного механизма SMTP. При использовании Unix-сокета LMTP обычно не поддерживает и не требует аутентификации, но возможны исключения.8182Изменено в версии 3.9: Добавлен необязательный параметр *timeout*.8384Также определен неплохой набор исключений:8586#### `exception smtplib.SMTPException`8788Подкласс [`OSError`](https://python-all.ru/3.16/library/exceptions.html#OSError), который является базовым классом исключений для всех остальных исключений, предоставляемых этим модулем.8990Изменено в версии 3.4: SMTPException стал подклассом [`OSError`](https://python-all.ru/3.16/library/exceptions.html#OSError)9192#### `exception smtplib.SMTPServerDisconnected`9394Это исключение возбуждается, когда сервер неожиданно отключается или когда предпринимается попытка использовать экземпляр [`SMTP`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP) до подключения к серверу.9596#### `exception smtplib.SMTPResponseException`9798Базовый класс для всех исключений, содержащих код ошибки SMTP. Эти исключения генерируются в некоторых случаях, когда SMTP-сервер возвращает код ошибки.99100#### `smtp_code`101102Код ошибки.103104#### `smtp_error`105106Сообщение об ошибке.107108#### `exception smtplib.SMTPSenderRefused`109110Адрес отправителя отклонен. В дополнение к атрибутам, задаваемым для всех исключений [`SMTPResponseException`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPResponseException), здесь атрибут 'sender' устанавливается в строку, которую отклонил SMTP-сервер.111112#### `exception smtplib.SMTPRecipientsRefused`113114Все адреса получателей отклонены.115116#### `recipients`117118Словарь того же типа, что возвращается [`SMTP.sendmail()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.sendmail), содержащий ошибки для каждого получателя.119120#### `exception smtplib.SMTPDataError`121122Сервер SMTP отказался принимать данные сообщения.123124#### `exception smtplib.SMTPConnectError`125126Произошла ошибка при установке соединения с сервером.127128#### `exception smtplib.SMTPHeloError`129130Сервер отклонил наше сообщение `HELO`.131132#### `exception smtplib.SMTPNotSupportedError`133134Запрошенная команда или опция не поддерживается сервером.135136Добавлено в версии 3.5.137138#### `exception smtplib.SMTPAuthenticationError`139140Произошла ошибка аутентификации SMTP. Скорее всего, сервер не принял предоставленную комбинацию имени пользователя и пароля.141142> **См. также**143>144> **[**RFC 821**](https://python-all.ru/3.16/library/smtplib.html) – Простой протокол передачи почты**145>146> Определение протокола SMTP. Этот документ описывает модель, порядок работы и детали протокола SMTP.147>148> **[**RFC 1869**](https://python-all.ru/3.16/library/smtplib.html) – Расширения службы SMTP**149>150> Определение расширений ESMTP для SMTP. Описывается инфраструктура для расширения SMTP новыми командами, динамическое обнаружение команд, предоставляемых сервером, и определяются несколько дополнительных команд.151152## Объекты SMTP153154Экземпляр [`SMTP`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP) имеет следующие методы:155156#### `SMTP.set_debuglevel(level)`157158Устанавливает уровень отладочного вывода. Значение 1 или `True` для параметра *level* приводит к выводу отладочных сообщений о соединении и обо всех сообщениях, отправленных на сервер и полученных от него. Значение 2 для *level* добавляет к этим сообщениям временные метки.159160Изменено в версии 3.5: Добавлен отладочный уровень 2.161162#### `SMTP.docmd(cmd, args='')`163164Отправляет команду *cmd* серверу. Необязательный аргумент *args* просто дописывается к команде через пробел.165166Возвращает кортеж из двух элементов: числового кода ответа и собственно строки ответа (многострочные ответы объединяются в одну длинную строку).167168При обычной работе нет необходимости явно вызывать этот метод. Он используется для реализации других методов и может быть полезен при тестировании частных расширений.169170Если соединение с сервером потеряно во время ожидания ответа, будет возбуждено [`SMTPServerDisconnected`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPServerDisconnected).171172#### `SMTP.connect(host='localhost', port=0)`173174Подключается к хосту на указанном порту. По умолчанию подключается к локальному хосту на стандартном порту SMTP (25). Если имя хоста заканчивается на двоеточие (`':'`), за которым следует число, этот суффикс отбрасывается, а число интерпретируется как номер порта для использования. Этот метод автоматически вызывается конструктором, если хост указан при создании экземпляра. Возвращает кортеж из двух элементов: код ответа и сообщение, отправленное сервером в своём ответе на подключение.175176Если порт не изменён относительно значения по умолчанию 0, значение атрибута [`default_port`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.default_port) используется.177178Вызывает [событие аудита](https://python-all.ru/3.16/library/sys.html#auditing) `smtplib.connect` с аргументами `self`, `host`, `port`.179180#### `SMTP.helo(name='')`181182Идентифицирует себя перед SMTP-сервером с помощью `HELO`. Аргумент hostname по умолчанию равен полному доменному имени локального хоста. Сообщение, возвращённое сервером, сохраняется в атрибуте [`helo_resp`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.helo_resp) объекта.183184При обычной работе нет необходимости явно вызывать этот метод. Он будет неявно вызван [`sendmail()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.sendmail) при необходимости.185186#### `SMTP.ehlo(name='')`187188Идентифицирует себя на ESMTP-сервере с помощью команды `EHLO`. Аргумент hostname по умолчанию равен полному доменному имени локального хоста. Анализирует ответ на предмет опций ESMTP и сохраняет их для использования методом [`has_extn()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.has_extn). Также устанавливает несколько информационных атрибутов: сообщение, возвращённое сервером, сохраняется как атрибут [`ehlo_resp`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.ehlo_resp), [`does_esmtp`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.does_esmtp) устанавливается в `True` или `False` в зависимости от того, поддерживает ли сервер ESMTP, а [`esmtp_features`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.esmtp_features) будет словарём, содержащим имена расширений SMTP-сервиса, которые поддерживает этот сервер, и их параметры (если есть).189190Если не требуется использовать [`has_extn()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.has_extn) перед отправкой почты, явно вызывать этот метод необязательно. Он будет неявно вызван методом [`sendmail()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.sendmail) при необходимости.191192#### `SMTP.ehlo_or_helo_if_needed()`193194Этот метод вызывает [`ehlo()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.ehlo) и/или [`helo()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.helo), если в течение этого сеанса ещё не было выполнено команды `EHLO` или `HELO`. Сначала он пробует ESMTP `EHLO`.195196**[`SMTPHeloError`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPHeloError)**197198Сервер некорректно ответил на приветствие `HELO`.199200#### `SMTP.has_extn(name)`201202Возвращает [`True`](https://python-all.ru/3.16/library/constants.html#True), если *name* присутствует в наборе расширений SMTP-сервиса, возвращённых сервером, и [`False`](https://python-all.ru/3.16/library/constants.html#False) в противном случае. Регистр игнорируется.203204#### `SMTP.verify(address)`205206Проверяет корректность адреса на этом сервере с помощью SMTP `VRFY`. Возвращает кортеж, состоящий из кода 250 и полного адреса [**RFC 822**](https://python-all.ru/3.16/library/smtplib.html) (включая имя человека), если адрес пользователя действителен. В противном случае возвращает код ошибки SMTP 400 или больше и строку ошибки.207208> **Примечание**209>210> Многие сайты отключают SMTP `VRFY`, чтобы помешать спамерам.211212#### `SMTP.login(user, password, *, initial_response_ok=True)`213214Выполняет вход на SMTP-сервер, требующий аутентификации. Аргументами являются имя пользователя и пароль для аутентификации. Если в течение этого сеанса ещё не было выполнено команды `EHLO` или `HELO`, этот метод сначала пробует ESMTP `EHLO`. Этот метод завершается нормально, если аутентификация прошла успешно, или может возбудить следующие исключения:215216**[`SMTPHeloError`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPHeloError)**217218Сервер некорректно ответил на приветствие `HELO`.219220**[`SMTPAuthenticationError`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPAuthenticationError)**221222Сервер не принял комбинацию имя пользователя/пароль.223224**[`SMTPNotSupportedError`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPNotSupportedError)**225226Команда `AUTH` не поддерживается сервером.227228**[`SMTPException`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPException)**229230Не найден подходящий метод аутентификации.231232Каждый из методов аутентификации, поддерживаемых `smtplib`, перебирается по очереди, если сервер объявляет о их поддержке. Список поддерживаемых методов аутентификации см. в [`auth()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.auth). Параметр *initial\_response\_ok* передаётся в `auth()`.233234Необязательный именованный аргумент *initial\_response\_ok* определяет, можно ли для методов аутентификации, которые это поддерживают, отправлять «начальный ответ» (initial response), как указано в [**RFC 4954**](https://python-all.ru/3.16/library/smtplib.html), вместе с командой `AUTH`, а не требовать запроса/ответа (challenge/response).235236Изменено в версии 3.5: [`SMTPNotSupportedError`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPNotSupportedError) может быть возбуждено, и добавлен параметр *initial\_response\_ok*.237238#### `SMTP.auth(mechanism, authobject, *, initial_response_ok=True)`239240Отправляет команду `SMTP` `AUTH` для указанного механизма аутентификации *mechanism* и обрабатывает ответ на запрос (challenge response) через *authobject*.241242*mechanism* указывает, какой механизм аутентификации будет использоваться в качестве аргумента команды `AUTH`; допустимые значения перечислены в элементе `auth` словаря [`esmtp_features`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.esmtp_features).243244*authobject* должен быть вызываемым объектом, принимающим один необязательный аргумент:245246```python247data = authobject(challenge=None)248```249250Если необязательный именованный аргумент *initial\_response\_ok* равен true, сначала вызывается `authobject()` без аргументов. Он может вернуть «начальный ответ» [**RFC 4954**](https://python-all.ru/3.16/library/smtplib.html) в виде ASCII `str`, который будет закодирован и отправлен с командой `AUTH`, как описано ниже. Если `authobject()` не поддерживает начальный ответ (например, потому что требует запроса), он должен вернуть `None` при вызове с `challenge=None`. Если *initial\_response\_ok* равен false, то `authobject()` не будет сначала вызываться с `None`.251252Если проверка начального ответа возвращает `None` или если *initial\_response\_ok* равен false, вызывается `authobject()` для обработки ответа на запрос сервера; аргумент *challenge*, который ему передаётся, будет `bytes`. Он должен вернуть ASCII `str` *data*, который будет закодирован в base64 и отправлен на сервер.253254Класс `SMTP` предоставляет `authobjects` для механизмов `CRAM-MD5`, `PLAIN` и `LOGIN`; они называются `SMTP.auth_cram_md5`, `SMTP.auth_plain` и `SMTP.auth_login` соответственно. Все они требуют, чтобы свойства `user` и `password` экземпляра `SMTP` были установлены в соответствующие значения.255256Пользовательскому коду обычно не нужно вызывать `auth` напрямую; вместо этого можно вызвать метод [`login()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.login), который переберёт каждый из вышеперечисленных механизмов по порядку. `auth` предоставляется для упрощения реализации методов аутентификации, не поддерживаемых (пока) напрямую `smtplib`.257258Добавлено в версии 3.5.259260#### `SMTP.starttls(*, context=None)`261262Переводит SMTP-соединение в режим TLS (безопасность транспортного уровня). Все последующие SMTP-команды будут зашифрованы. После этого следует снова вызвать [`ehlo()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.ehlo).263264Если указаны *keyfile* и *certfile*, они используются для создания [`ssl.SSLContext`](https://python-all.ru/3.16/library/ssl.html#ssl.SSLContext).265266Необязательный параметр *context* – это объект [`ssl.SSLContext`](https://python-all.ru/3.16/library/ssl.html#ssl.SSLContext); это альтернатива использованию keyfile и certfile, и если он указан, то *keyfile* и *certfile* должны быть `None`.267268Если в течение этого сеанса ещё не выполнялась команда `EHLO` или `HELO`, метод сначала пытается выполнить ESMTP `EHLO`.269270Изменено в версии 3.12: Устаревшие параметры *keyfile* и *certfile* были удалены.271272**[`SMTPHeloError`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPHeloError)**273274Сервер некорректно ответил на приветствие `HELO`.275276**[`SMTPNotSupportedError`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPNotSupportedError)**277278Сервер не поддерживает расширение STARTTLS.279280**[`RuntimeError`](https://python-all.ru/3.16/library/exceptions.html#RuntimeError)**281282Интерпретатор Python не поддерживает SSL/TLS.283284Изменено в версии 3.3: был добавлен параметр *context*.285286Изменено в версии 3.4: Теперь метод поддерживает проверку имени хоста с помощью [`ssl.SSLContext.check_hostname`](https://python-all.ru/3.16/library/ssl.html#ssl.SSLContext.check_hostname) и *Server Name Indicator* (см. [`HAS_SNI`](https://python-all.ru/3.16/library/ssl.html#ssl.HAS_SNI)).287288Изменено в версии 3.5: Исключение, возбуждаемое при отсутствии поддержки STARTTLS, теперь является подклассом [`SMTPNotSupportedError`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPNotSupportedError) вместо базового [`SMTPException`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPException).289290#### `SMTP.sendmail(from_addr, to_addrs, msg, mail_options=(), rcpt_options=())`291292Отправляет почту. Обязательные аргументы: строка с обратным адресом [**RFC 822**](https://python-all.ru/3.16/library/smtplib.html), список строк с адресами получателей [**RFC 822**](https://python-all.ru/3.16/library/smtplib.html) (если передана просто строка, она будет считаться списком из одного адреса) и строка сообщения. Вызывающий код может передать список ESMTP-опций (например, `"8bitmime"`), которые будут использоваться в командах `MAIL FROM`, через параметр *mail\_options*. ESMTP-опции (например, команды `DSN`), которые должны применяться ко всем командам `RCPT`, можно передать через параметр *rcpt\_options*. Каждая опция должна быть передана в виде строки, содержащей полный текст опции, включая возможный ключ (например, `"NOTIFY=SUCCESS,FAILURE"`). (Если нужно использовать разные ESMTP-опции для разных получателей, придётся воспользоваться низкоуровневыми методами, такими как `mail()`, `rcpt()` и `data()` для отправки сообщения.)293294> **Примечание**295>296> Параметры *from\_addr* и *to\_addrs* используются для построения конверта сообщения, используемого транспортными агентами. `sendmail` никак не изменяет заголовки сообщения.297298*msg* может быть строкой, содержащей символы из диапазона ASCII, или байтовой строкой. Строка кодируется в байты с помощью кодека ascii, а одиночные символы `\r` и `\n` преобразуются в символы `\r\n`. Байтовая строка не изменяется.299300Если в течение этого сеанса ещё не выполнялась команда `EHLO` или `HELO`, данный метод сначала пытается выполнить ESMTP `EHLO`. Если сервер поддерживает ESMTP, ему будут переданы размер сообщения и каждая из указанных опций (если опция присутствует в наборе возможностей, объявленных сервером). Если `EHLO` не удаётся, будет выполнена попытка `HELO` и ESMTP-опции будут подавлены.301302Метод завершается нормально, если почта принята хотя бы одним получателем. В противном случае возбуждается исключение. То есть, если метод не возбуждает исключение, значит, кто-то должен получить ваше письмо. Если метод не возбуждает исключение, он возвращает словарь с одной записью для каждого получателя, которому было отказано. Каждая запись содержит кортеж из кода ошибки SMTP и соответствующего сообщения об ошибке, отправленного сервером.303304Если `SMTPUTF8` включён в *mail\_options* и сервер это поддерживает, *from\_addr* и *to\_addrs* могут содержать символы, не входящие в ASCII.305306Этот метод может возбуждать следующие исключения:307308**[`SMTPRecipientsRefused`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPRecipientsRefused)**309310Всем получателям было отказано. Письмо не доставлено никому.311312**[`SMTPHeloError`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPHeloError)**313314Сервер некорректно ответил на приветствие `HELO`.315316**[`SMTPSenderRefused`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPSenderRefused)**317318Сервер не принял адрес *from\_addr*.319320**[`SMTPDataError`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPDataError)**321322Сервер ответил неожиданным кодом ошибки (не связанным с отказом отдельному получателю).323324**[`SMTPNotSupportedError`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPNotSupportedError)**325326Параметр `SMTPUTF8` был указан в *mail\_options*, но не поддерживается сервером.327328Если не указано иное, соединение остаётся открытым даже после возбуждения исключения.329330Изменено в версии 3.2: *msg* может быть байтовой строкой.331332Изменено в версии 3.5: Добавлена поддержка `SMTPUTF8`, и может возбуждаться [`SMTPNotSupportedError`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPNotSupportedError), если указан `SMTPUTF8`, но сервер его не поддерживает.333334#### `SMTP.send_message(msg, from_addr=None, to_addrs=None, mail_options=(), rcpt_options=())`335336Это удобный метод для вызова [`sendmail()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.sendmail) с сообщением, представленным объектом [`email.message.Message`](https://python-all.ru/3.16/library/email.compat32-message.html#email.message.Message). Аргументы имеют тот же смысл, что и для `sendmail()`, за исключением того, что *msg* является объектом `Message`.337338Если *from\_addr* равно `None` или *to\_addrs* равно `None`, `send_message` заполняет эти аргументы адресами, извлечёнными из заголовков *msg* в соответствии с [**RFC 5322**](https://python-all.ru/3.16/library/smtplib.html): *from\_addr* устанавливается в поле *Sender*, если оно присутствует, иначе – в поле *From*. *to\_addrs* объединяет значения (если они есть) полей *To*, *Cc* и *Bcc* из *msg*. Если в сообщении присутствует ровно один набор заголовков *Resent-\**, обычные заголовки игнорируются, а используются заголовки *Resent-\**. Если сообщение содержит более одного набора заголовков *Resent-\**, возбуждается [`ValueError`](https://python-all.ru/3.16/library/exceptions.html#ValueError), поскольку нет способа однозначно определить самый последний набор заголовков *Resent-*.339340`send_message` сериализует *msg* с помощью [`BytesGenerator`](https://python-all.ru/3.16/library/email.generator.html#email.generator.BytesGenerator), используя `\r\n` в качестве *linesep*, и вызывает [`sendmail()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.sendmail) для передачи полученного сообщения. Независимо от значений *from\_addr* и *to\_addrs*, `send_message` не передаёт никакие заголовки *Bcc* или *Resent-Bcc*, которые могут присутствовать в *msg*. Если какой-либо из адресов в *from\_addr* и *to\_addrs* содержит не-ASCII символы и сервер не объявляет поддержку `SMTPUTF8`, возбуждается [`SMTPNotSupportedError`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTPNotSupportedError). В противном случае `Message` сериализуется с клоном своего [`policy`](https://python-all.ru/3.16/library/email.policy.html#module-email.policy), в котором атрибут [`utf8`](https://python-all.ru/3.16/library/email.policy.html#email.policy.EmailPolicy.utf8) установлен в `True`, и `SMTPUTF8` и `BODY=8BITMIME` добавляются в *mail\_options*.341342Добавлено в версии 3.2.343344Добавлено в версии 3.5: Поддержка интернационализированных адресов (`SMTPUTF8`).345346#### `SMTP.quit()`347348Завершает сеанс SMTP и закрывает соединение. Возвращает результат команды SMTP `QUIT`.349350Также поддерживаются низкоуровневые методы, соответствующие стандартным командам SMTP/ESMTP `HELP`, `RSET`, `NOOP`, `MAIL`, `RCPT` и `DATA`. Обычно их не нужно вызывать напрямую, поэтому они не документированы здесь. Подробнее см. в коде модуля.351352Кроме того, экземпляр SMTP имеет следующие атрибуты:353354#### `SMTP.helo_resp`355356Ответ на команду `HELO`, см. [`helo()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.helo).357358#### `SMTP.ehlo_resp`359360Ответ на команду `EHLO`, см. [`ehlo()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.ehlo).361362#### `SMTP.does_esmtp`363364Логическое значение, указывающее, поддерживает ли сервер ESMTP. См. [`ehlo()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.ehlo).365366#### `SMTP.esmtp_features`367368Словарь названий расширений службы SMTP, поддерживаемых сервером. См. [`ehlo()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.ehlo).369370## Пример SMTP371372Этот пример запрашивает у пользователя адреса, необходимые для конверта сообщения (адреса «Кому» и «От»), а также само сообщение для отправки. Обратите внимание, что заголовки, которые должны быть включены в сообщение, должны быть введены в самом сообщении; этот пример не выполняет никакой обработки заголовков [**RFC 822**](https://python-all.ru/3.16/library/smtplib.html). В частности, адреса «Кому» и «От» должны быть явно указаны в заголовках сообщения:373374```python375import smtplib376377def prompt(title):378 return input(title).strip()379380from_addr = prompt("From: ")381to_addrs = prompt("To: ").split()382print("Enter message, end with ^D (Unix) or ^Z (Windows):")383384# Добавьте заголовки From: и To: в начало!385lines = [f"From: {from_addr}", f"To: {', '.join(to_addrs)}", ""]386while True:387 try:388 line = input()389 except EOFError:390 break391 else:392 lines.append(line)393394msg = "\r\n".join(lines)395print("Message length is", len(msg))396397server = smtplib.SMTP("localhost")398server.set_debuglevel(1)399server.sendmail(from_addr, to_addrs, msg)400server.quit()401```402403> **Примечание**404>405> В общем случае рекомендуется использовать возможности пакета [`email`](https://python-all.ru/3.16/library/email.html#module-email) для создания сообщения электронной почты, которое затем можно отправить через [`send_message()`](https://python-all.ru/3.16/library/smtplib.html#smtplib.SMTP.send_message); см. [email: Примеры](https://python-all.ru/3.16/library/email.examples.html#email-examples).406