smtplib.md
1> **Источник:** https://python-all.ru/3.5/library/smtplib.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 21.17. [`smtplib`](https://python-all.ru/3.5/library/smtplib.html#module-smtplib) – клиент протокола SMTP89**Исходный код:** [Lib/smtplib.py](https://python-all.ru/src/3.5/Lib/smtplib.py)1011---1213Модуль [`smtplib`](https://python-all.ru/3.5/library/smtplib.html#module-smtplib) определяет объект сессии SMTP-клиента, который можно использовать для отправки почты на любую машину в Интернете с демоном, прослушивающим SMTP или ESMTP. Подробнее о работе SMTP и ESMTP см. в [**RFC 821**](https://python-all.ru/3.5/library/smtplib.html) (Простой протокол передачи почты) и [**RFC 1869**](https://python-all.ru/3.5/library/smtplib.html) (Расширения службы SMTP).1415#### `class smtplib.SMTP(host='', port=0, local_hostname=None, [timeout, ]source_address=None)`1617Экземпляр [`SMTP`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP) инкапсулирует SMTP-соединение. Он содержит методы, поддерживающие полный набор операций SMTP и ESMTP. Если указаны необязательные параметры host и port, метод SMTP [`connect()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.connect) вызывается с этими параметрами во время инициализации. Если задан, *local\_hostname* используется как полное доменное имя локального хоста в команде HELO/EHLO. В противном случае локальное имя хоста находится с помощью [`socket.getfqdn()`](https://python-all.ru/3.5/library/socket.html#socket.getfqdn). Если вызов [`connect()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.connect) возвращает что-то, отличное от кода успеха, генерируется исключение [`SMTPConnectError`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPConnectError). Необязательный параметр *timeout* задаёт тайм-аут в секундах для блокирующих операций, таких как попытка соединения (если не указан, используется глобальный тайм-аут по умолчанию). Если тайм-аут истекает, возбуждается [`socket.timeout`](https://python-all.ru/3.5/library/socket.html#socket.timeout). Необязательный параметр source\_address позволяет выполнить привязку к определённому исходному адресу на машине с несколькими сетевыми интерфейсами и/или к определённому исходному TCP-порту. Он принимает кортеж из двух элементов (host, port), к которому сокет привязывается как к своему исходному адресу перед установкой соединения. Если параметр опущен (или host и port равны `''` и/или 0 соответственно), будет использовано поведение ОС по умолчанию.1819Для обычного использования достаточно методов инициализации/подключения, [`sendmail()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.sendmail) и `quit()`. Пример приведен ниже.2021Класс [`SMTP`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP) поддерживает оператор [`with`](https://python-all.ru/3.5/reference/compound_stmts.html#with). При таком использовании команда SMTP `QUIT` отправляется автоматически при выходе из оператора [`with`](https://python-all.ru/3.5/reference/compound_stmts.html#with). Например:2223```python24>>> from smtplib import SMTP25>>> with SMTP("domain.org") as smtp:26... smtp.noop()27...28(250, b'Ok')29>>>30```3132Изменено в версии 3.3: Добавлена поддержка оператора [`with`](https://python-all.ru/3.5/reference/compound_stmts.html#with).3334Изменено в версии 3.3: добавлен аргумент source\_address.3536Новое в версии 3.5: Теперь поддерживается расширение SMTPUTF8 ([**RFC 6531**](https://python-all.ru/3.5/library/smtplib.html)).3738#### `class smtplib.SMTP_SSL(host='', port=0, local_hostname=None, keyfile=None, certfile=None, [timeout, ]context=None, source_address=None)`3940Экземпляр [`SMTP_SSL`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP_SSL) ведёт себя точно так же, как экземпляры [`SMTP`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP). [`SMTP_SSL`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP_SSL) следует использовать в ситуациях, когда SSL требуется с самого начала соединения и использование `starttls()` неуместно. Если *host* не указан, используется локальный хост. Если *port* равен нулю, используется стандартный порт SMTP-over-SSL (465). Необязательные аргументы *local\_hostname*, *timeout* и *source\_address* имеют те же значения, что и в классе [`SMTP`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP). *context*, также необязательный, может содержать [`SSLContext`](https://python-all.ru/3.5/library/ssl.html#ssl.SSLContext) и позволяет настраивать различные аспекты защищённого соединения. Пожалуйста, прочитайте [Рекомендации по безопасности](https://python-all.ru/3.5/library/ssl.html#ssl-security) для получения лучших практик.4142*файл ключа* и *файл сертификата* – устаревшая альтернатива *контексту*, и могут указывать на файл закрытого ключа и цепочки сертификатов в формате PEM для SSL-соединения.4344Изменено в версии 3.3: был добавлен параметр *context*.4546Изменено в версии 3.3: добавлен аргумент source\_address.4748Изменено в версии 3.4: Теперь класс поддерживает проверку имени хоста с помощью [`ssl.SSLContext.check_hostname`](https://python-all.ru/3.5/library/ssl.html#ssl.SSLContext.check_hostname) и *Server Name Indication* (см. [`ssl.HAS_SNI`](https://python-all.ru/3.5/library/ssl.html#ssl.HAS_SNI)).4950#### `class smtplib.LMTP(host='', port=LMTP_PORT, local_hostname=None, source_address=None)`5152Протокол LMTP, очень похожий на ESMTP, во многом основан на\\nстандартном SMTP-клиенте. Для LMTP обычно используются Unix-сокеты, поэтому наш\\nметод `connect()` должен поддерживать как обычный сервер host:port, так и Unix-сокеты.\\nНеобязательные аргументы local\_hostname и source\_address имеют тот же\\nсмысл, что и в классе [`SMTP`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP). Чтобы указать Unix-сокет, необходимо использовать абсолютный путь для *host*, начинающийся с '/'.5354Поддерживается аутентификация с использованием обычного механизма SMTP. При использовании Unix-сокета LMTP обычно не поддерживает и не требует аутентификации, но возможны исключения.5556Также определен неплохой набор исключений:5758#### `exception smtplib.SMTPException`5960Подкласс [`OSError`](https://python-all.ru/3.5/library/exceptions.html#OSError), который является базовым классом исключений для всех остальных исключений, предоставляемых этим модулем.6162Изменено в версии 3.4: SMTPException стал подклассом [`OSError`](https://python-all.ru/3.5/library/exceptions.html#OSError)6364#### `exception smtplib.SMTPServerDisconnected`6566Это исключение возбуждается, когда сервер неожиданно отключается или когда предпринимается попытка использовать экземпляр [`SMTP`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP) до подключения к серверу.6768#### `exception smtplib.SMTPResponseException`6970Базовый класс для всех исключений, содержащих код ошибки SMTP. Эти исключения генерируются в некоторых случаях, когда SMTP-сервер возвращает код ошибки. Код ошибки хранится в атрибуте `smtp_code` исключения, а атрибут `smtp_error` содержит сообщение об ошибке.7172#### `exception smtplib.SMTPSenderRefused`7374Адрес отправителя отклонен. В дополнение к атрибутам, задаваемым для всех исключений [`SMTPResponseException`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPResponseException), здесь атрибут 'sender' устанавливается в строку, которую отклонил SMTP-сервер.7576#### `exception smtplib.SMTPRecipientsRefused`7778Все адреса получателей отклонены. Ошибки для каждого получателя доступны через атрибут `recipients`, который представляет собой словарь точно такого же типа, какой возвращает [`SMTP.sendmail()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.sendmail).7980#### `exception smtplib.SMTPDataError`8182Сервер SMTP отказался принимать данные сообщения.8384#### `exception smtplib.SMTPConnectError`8586Произошла ошибка при установке соединения с сервером.8788#### `exception smtplib.SMTPHeloError`8990Сервер отклонил наше сообщение `HELO`.9192#### `exception smtplib.SMTPNotSupportedError`9394Запрошенная команда или опция не поддерживается сервером.9596Новое в версии 3.5.9798#### `exception smtplib.SMTPAuthenticationError`99100Произошла ошибка аутентификации SMTP. Скорее всего, сервер не принял предоставленную комбинацию имени пользователя и пароля.101102> **См. также**103>104> **[**RFC 821**](https://python-all.ru/3.5/library/smtplib.html) – Простой протокол передачи почты**105>106> Определение протокола SMTP. Этот документ описывает модель, порядок работы и детали протокола SMTP.107>108> **[**RFC 1869**](https://python-all.ru/3.5/library/smtplib.html) – Расширения службы SMTP**109>110> Определение расширений ESMTP для SMTP. Описывается инфраструктура для расширения SMTP новыми командами, динамическое обнаружение команд, предоставляемых сервером, и определяются несколько дополнительных команд.111112## 21.17.1. Объекты SMTP113114Экземпляр [`SMTP`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP) имеет следующие методы:115116#### `SMTP.set_debuglevel(level)`117118Устанавливает уровень отладочного вывода. Значение 1 или `True` для параметра *level* приводит к выводу отладочных сообщений о соединении и обо всех сообщениях, отправленных на сервер и полученных от него. Значение 2 для *level* добавляет к этим сообщениям временные метки.119120Изменено в версии 3.5: Добавлен отладочный уровень 2.121122#### `SMTP.docmd(cmd, args='')`123124Отправляет команду *cmd* серверу. Необязательный аргумент *args* просто дописывается к команде через пробел.125126Возвращает кортеж из двух элементов: числового кода ответа и собственно строки ответа (многострочные ответы объединяются в одну длинную строку).127128При обычной работе нет необходимости явно вызывать этот метод. Он используется для реализации других методов и может быть полезен при тестировании частных расширений.129130Если соединение с сервером потеряно во время ожидания ответа, будет возбуждено [`SMTPServerDisconnected`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPServerDisconnected).131132#### `SMTP.connect(host='localhost', port=0)`133134Подключается к хосту на указанном порту. По умолчанию подключается к локальному хосту на стандартном порту SMTP (25). Если имя хоста заканчивается на двоеточие (`':'`), за которым следует число, этот суффикс отбрасывается, а число интерпретируется как номер порта для использования. Этот метод автоматически вызывается конструктором, если хост указан при создании экземпляра. Возвращает кортеж из двух элементов: код ответа и сообщение, отправленное сервером в своём ответе на подключение.135136#### `SMTP.helo(name='')`137138Идентифицирует себя перед SMTP-сервером с помощью `HELO`. Аргумент hostname по умолчанию равен полному доменному имени локального хоста. Сообщение, возвращённое сервером, сохраняется в атрибуте `helo_resp` объекта.139140При обычной работе нет необходимости явно вызывать этот метод. Он будет неявно вызван [`sendmail()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.sendmail) при необходимости.141142#### `SMTP.ehlo(name='')`143144Идентификация на ESMTP-сервере выполняется с помощью `EHLO`. Аргумент hostname по умолчанию равен полному доменному имени локального хоста. Ответ проверяется на наличие опции ESMTP, и они сохраняются для использования [`has_extn()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.has_extn). Также устанавливаются несколько информационных атрибутов: сообщение, возвращённое сервером, сохраняется как атрибут `ehlo_resp`; `does_esmtp` устанавливается в true или false в зависимости от того, поддерживает ли сервер ESMTP; а `esmtp_features` будет словарём, содержащим имена расширений службы SMTP, которые поддерживает этот сервер, и их параметры (если они есть).145146Если не требуется использовать [`has_extn()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.has_extn) перед отправкой почты, явно вызывать этот метод необязательно. Он будет неявно вызван методом [`sendmail()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.sendmail) при необходимости.147148#### `SMTP.ehlo_or_helo_if_needed()`149150Этот метод вызывает [`ehlo()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.ehlo) и/или [`helo()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.helo), если в этом сеансе не было предыдущей команды `EHLO` или `HELO`. Сначала он пытается использовать ESMTP `EHLO`.151152**[`SMTPHeloError`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPHeloError)**153154Сервер некорректно ответил на приветствие155156`HELO`157158.159160#### `SMTP.has_extn(name)`161162Возвращает [`True`](https://python-all.ru/3.5/library/constants.html#True), если *name* присутствует в наборе расширений SMTP-сервиса, возвращённых сервером, и [`False`](https://python-all.ru/3.5/library/constants.html#False) в противном случае. Регистр игнорируется.163164#### `SMTP.verify(address)`165166Проверяет корректность адреса на этом сервере с помощью SMTP `VRFY`. Возвращает кортеж, состоящий из кода 250 и полного адреса [**RFC 822**](https://python-all.ru/3.5/library/smtplib.html) (включая имя человека), если адрес пользователя действителен. В противном случае возвращает код ошибки SMTP 400 или больше и строку ошибки.167168> **Примечание**169>170> Многие сайты отключают SMTP `VRFY`, чтобы помешать спамерам.171172#### `SMTP.login(user, password, *, initial_response_ok=True)`173174Выполняет вход на SMTP-сервер, требующий аутентификации. Аргументами являются имя пользователя и пароль для аутентификации. Если в течение этого сеанса ещё не было выполнено команды `EHLO` или `HELO`, этот метод сначала пробует ESMTP `EHLO`. Этот метод завершается нормально, если аутентификация прошла успешно, или может возбудить следующие исключения:175176**[`SMTPHeloError`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPHeloError)**177178Сервер некорректно ответил на приветствие179180`HELO`181182.183184**[`SMTPAuthenticationError`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPAuthenticationError)**185186Сервер не принял комбинацию имя пользователя/пароль.187188**[`SMTPNotSupportedError`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPNotSupportedError)**189190Команда191192`AUTH`193194не поддерживается сервером.195196**[`SMTPException`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPException)**197198Не найден подходящий метод аутентификации.199200Каждый из методов аутентификации, поддерживаемых [`smtplib`](https://python-all.ru/3.5/library/smtplib.html#module-smtplib), перебирается по очереди, если сервер объявляет о их поддержке. Список поддерживаемых методов аутентификации см. в [`auth()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.auth). Параметр *initial\_response\_ok* передаётся в [`auth()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.auth).201202Необязательный именованный аргумент *initial\_response\_ok* определяет, можно ли для методов аутентификации, которые это поддерживают, отправлять «начальный ответ» (initial response), как указано в [**RFC 4954**](https://python-all.ru/3.5/library/smtplib.html), вместе с командой `AUTH`, а не требовать запроса/ответа (challenge/response).203204Изменено в версии 3.5: [`SMTPNotSupportedError`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPNotSupportedError) может быть возбуждено, и добавлен параметр *initial\_response\_ok*.205206#### `SMTP.auth(mechanism, authobject, *, initial_response_ok=True)`207208Отправляет команду `SMTP` `AUTH` для указанного механизма аутентификации *mechanism* и обрабатывает ответ на запрос (challenge response) через *authobject*.209210*mechanism* указывает, какой механизм аутентификации будет использоваться в качестве аргумента команды `AUTH`; допустимые значения перечислены в элементе `auth` словаря `esmtp_features`.211212*authobject* должен быть вызываемым объектом, принимающим один необязательный аргумент:213214> data = authobject(challenge=None)215216Если необязательный именованный аргумент *initial\_response\_ok* истинен, `authobject()` сначала будет вызван без аргументов. Он может вернуть байты «начального ответа» [**RFC 4954**](https://python-all.ru/3.5/library/smtplib.html), которые будут закодированы и отправлены с командой `AUTH`, как показано ниже. Если `authobject()` не поддерживает начальный ответ (например, потому что требуется запрос (challenge)), он должен вернуть `None` при вызове с `challenge=None`. Если *initial\_response\_ok* ложен, то `authobject()` не будет вызван сначала с `None`.217218Если проверка начального ответа возвращает `None`, или если *initial\_response\_ok* ложен, `authobject()` будет вызван для обработки ответа сервера на запрос; аргумент *challenge*, который ему передается, будет `bytes`. Он должен вернуть `bytes` *data*, которые будут закодированы в base64 и отправлены серверу.219220Класс `SMTP` предоставляет `authobjects` для механизмов `CRAM-MD5`, `PLAIN` и `LOGIN`; они называются `SMTP.auth_cram_md5`, `SMTP.auth_plain` и `SMTP.auth_login` соответственно. Все они требуют, чтобы свойства `user` и `password` экземпляра `SMTP` были установлены в соответствующие значения.221222Пользовательскому коду обычно не нужно вызывать `auth` напрямую; вместо этого можно вызвать метод [`login()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.login), который переберёт каждый из вышеперечисленных механизмов по порядку. `auth` предоставляется для упрощения реализации методов аутентификации, не поддерживаемых (пока) напрямую [`smtplib`](https://python-all.ru/3.5/library/smtplib.html#module-smtplib).223224Новое в версии 3.5.225226#### `SMTP.starttls(keyfile=None, certfile=None, context=None)`227228Переводит SMTP-соединение в режим TLS (безопасность транспортного уровня). Все последующие SMTP-команды будут зашифрованы. После этого следует снова вызвать [`ehlo()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.ehlo).229230Если указаны *keyfile* и *certfile*, они передаются функции [`ssl()`](https://python-all.ru/3.5/library/ssl.html#module-ssl) модуля [`socket`](https://python-all.ru/3.5/library/socket.html#module-socket).231232Необязательный параметр *context* является объектом [`ssl.SSLContext`](https://python-all.ru/3.5/library/ssl.html#ssl.SSLContext); Это альтернатива использованию keyfile и certfile, и если он указан, оба *keyfile* и *certfile* должны быть `None`.233234Если в течение этого сеанса ещё не выполнялась команда `EHLO` или `HELO`, метод сначала пытается выполнить ESMTP `EHLO`.235236**[`SMTPHeloError`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPHeloError)**237238Сервер некорректно ответил на приветствие239240`HELO`241242.243244**[`SMTPNotSupportedError`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPNotSupportedError)**245246Сервер не поддерживает расширение STARTTLS.247248**[`RuntimeError`](https://python-all.ru/3.5/library/exceptions.html#RuntimeError)**249250Интерпретатор Python не поддерживает SSL/TLS.251252Изменено в версии 3.3: был добавлен параметр *context*.253254Изменено в версии 3.4: Теперь метод поддерживает проверку имени хоста с помощью `SSLContext.check_hostname` и *Server Name Indicator* (см. [`HAS_SNI`](https://python-all.ru/3.5/library/ssl.html#ssl.HAS_SNI)).255256Изменено в версии 3.5: Исключение, возбуждаемое при отсутствии поддержки STARTTLS, теперь является подклассом [`SMTPNotSupportedError`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPNotSupportedError) вместо базового [`SMTPException`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPException).257258#### `SMTP.sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[])`259260Отправляет почту. Обязательными аргументами являются строка обратного адреса [**RFC 822**](https://python-all.ru/3.5/library/smtplib.html), список строк адресов получателей [**RFC 822**](https://python-all.ru/3.5/library/smtplib.html) (простая строка будет рассматриваться как список с одним адресом) и строка сообщения. Вызывающий может передать список параметров ESMTP (например, `8bitmime`) для использования в командах `MAIL FROM` в качестве *mail\_options*. Параметры ESMTP (например, команды `DSN`), которые должны использоваться со всеми командами `RCPT`, могут быть переданы как *rcpt\_options*. (Если необходимо использовать разные параметры ESMTP для разных получателей, нужно использовать низкоуровневые методы, такие как `mail()`, `rcpt()` и `data()`, для отправки сообщения.)261262> **Примечание**263>264> Параметры *from\_addr* и *to\_addrs* используются для построения конверта сообщения, используемого транспортными агентами. `sendmail` никак не изменяет заголовки сообщения.265266*msg* может быть строкой, содержащей символы из диапазона ASCII, или байтовой строкой. Строка кодируется в байты с помощью кодека ascii, а одиночные символы `\r` и `\n` преобразуются в символы `\r\n`. Байтовая строка не изменяется.267268Если в течение этого сеанса ещё не выполнялась команда `EHLO` или `HELO`, данный метод сначала пытается выполнить ESMTP `EHLO`. Если сервер поддерживает ESMTP, ему будут переданы размер сообщения и каждая из указанных опций (если опция присутствует в наборе возможностей, объявленных сервером). Если `EHLO` не удаётся, будет выполнена попытка `HELO` и ESMTP-опции будут подавлены.269270Метод завершается нормально, если почта принята хотя бы одним получателем. В противном случае возбуждается исключение. То есть, если метод не возбуждает исключение, значит, кто-то должен получить ваше письмо. Если метод не возбуждает исключение, он возвращает словарь с одной записью для каждого получателя, которому было отказано. Каждая запись содержит кортеж из кода ошибки SMTP и соответствующего сообщения об ошибке, отправленного сервером.271272Если `SMTPUTF8` включён в *mail\_options* и сервер это поддерживает, *from\_addr* и *to\_addrs* могут содержать символы, не входящие в ASCII.273274Этот метод может возбуждать следующие исключения:275276**[`SMTPRecipientsRefused`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPRecipientsRefused)**277278Все получатели были отклонены. Почта не была доставлена. Атрибут279280`recipients`281282объекта исключения представляет собой словарь с информацией об отклонённых получателях (такой же, как возвращается, когда хотя бы один получатель был принят).283284**[`SMTPHeloError`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPHeloError)**285286Сервер некорректно ответил на приветствие287288`HELO`289290.291292**[`SMTPSenderRefused`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPSenderRefused)**293294Сервер не принял адрес295296*from\_addr*297298.299300**[`SMTPDataError`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPDataError)**301302Сервер ответил неожиданным кодом ошибки (не связанным с отказом отдельному получателю).303304**[`SMTPNotSupportedError`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPNotSupportedError)**305306Параметр307308`SMTPUTF8`309310был указан в311312*mail\_options*313314, но не поддерживается сервером.315316Если не указано иное, соединение остаётся открытым даже после возбуждения исключения.317318Изменено в версии 3.2: *msg* может быть байтовой строкой.319320Изменено в версии 3.5: Добавлена поддержка `SMTPUTF8`, и может возбуждаться [`SMTPNotSupportedError`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTPNotSupportedError), если указан `SMTPUTF8`, но сервер его не поддерживает.321322#### `SMTP.send_message(msg, from_addr=None, to_addrs=None, mail_options=[], rcpt_options=[])`323324Это удобный метод для вызова [`sendmail()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.sendmail) с сообщением, представленным объектом [`email.message.Message`](https://python-all.ru/3.5/library/email.message.html#email.message.Message). Аргументы имеют тот же смысл, что и для [`sendmail()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.sendmail), за исключением того, что *msg* является объектом `Message`.325326Если *from\_addr* равно `None` или *to\_addrs* равно `None`, `send_message` заполняет эти аргументы адресами, извлечёнными из заголовков *msg* в соответствии с [**RFC 5322**](https://python-all.ru/3.5/library/smtplib.html): *from\_addr* устанавливается в поле *Sender*, если оно присутствует, иначе – в поле *From*. *to\_addrs* объединяет значения (если они есть) полей *To*, *Cc* и *Bcc* из *msg*. Если в сообщении присутствует ровно один набор заголовков *Resent-\**, обычные заголовки игнорируются, а используются заголовки *Resent-\**. Если сообщение содержит более одного набора заголовков *Resent-\**, возбуждается [`ValueError`](https://python-all.ru/3.5/library/exceptions.html#ValueError), поскольку нет способа однозначно определить самый последний набор заголовков *Resent-*.327328`send_message` сериализует *msg* с помощью\\n[`BytesGenerator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.BytesGenerator), используя `\r\n` в качестве *linesep*, и\\nвызывает [`sendmail()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.sendmail) для передачи результирующего сообщения. Независимо от\\nзначений *from\_addr* и *to\_addrs*, `send_message` не передаёт никакие\\nзаголовки *Bcc* или *Resent-Bcc*, которые могут присутствовать\\nв *msg*. Если какой-либо из адресов в *from\_addr* и *to\_addrs* содержит\\nсимволы, отличные от ASCII, и сервер не объявляет поддержку `SMTPUTF8`,\\nвозникает ошибка `SMTPNotSupported`. В противном случае `Message`\\nсериализуется с клоном своего [`policy`](https://python-all.ru/3.5/library/email.policy.html#module-email.policy), у которого\\nатрибут [`utf8`](https://python-all.ru/3.5/library/email.policy.html#email.policy.EmailPolicy.utf8) установлен в `True`, а\\n`SMTPUTF8` и `BODY=8BITMIME` добавляются к *mail\_options*.329330Новое в версии 3.2.331332Новое в версии 3.5: Поддержка интернационализированных адресов (`SMTPUTF8`).333334#### `SMTP.quit()`335336Завершает сеанс SMTP и закрывает соединение. Возвращает результат команды SMTP `QUIT`.337338Также поддерживаются низкоуровневые методы, соответствующие стандартным командам SMTP/ESMTP `HELP`, `RSET`, `NOOP`, `MAIL`, `RCPT` и `DATA`. Обычно их не нужно вызывать напрямую, поэтому они не документированы здесь. Подробнее см. в коде модуля.339340## 21.17.2. Пример SMTP341342Этот пример запрашивает у пользователя адреса, необходимые в конверте сообщения (адреса ‘To’\\nи ‘From’), а также само сообщение для отправки. Обратите внимание, что заголовки,\\nкоторые должны быть включены в сообщение, должны быть включены в сообщение при вводе; этот\\nпример не выполняет никакой обработки заголовков [**RFC 822**](https://python-all.ru/3.5/library/smtplib.html). В частности,\\nадреса ‘To’ и ‘From’ должны быть явно включены в заголовки сообщения.343344```python345import smtplib346347def prompt(prompt):348 return input(prompt).strip()349350fromaddr = prompt("From: ")351toaddrs = prompt("To: ").split()352print("Enter message, end with ^D (Unix) or ^Z (Windows):")353354# Добавьте заголовки From: и To: в начало!355msg = ("From: %s\r\nTo: %s\r\n\r\n"356 % (fromaddr, ", ".join(toaddrs)))357while True:358 try:359 line = input()360 except EOFError:361 break362 if not line:363 break364 msg = msg + line365366print("Message length is", len(msg))367368server = smtplib.SMTP('localhost')369server.set_debuglevel(1)370server.sendmail(fromaddr, toaddrs, msg)371server.quit()372```373374> **Примечание**375>376> В общем случае рекомендуется использовать возможности пакета [`email`](https://python-all.ru/3.5/library/email.html#module-email) для создания сообщения электронной почты, которое затем можно отправить через [`send_message()`](https://python-all.ru/3.5/library/smtplib.html#smtplib.SMTP.send_message); см. [email: Примеры](https://python-all.ru/3.5/library/email-examples.html#email-examples).377