smtplib.md
1> **Источник:** https://python-all.ru/2.7/library/smtplib.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 20.12. [`smtplib`](https://python-all.ru/2.7/library/smtplib.html#module-smtplib) – клиент протокола SMTP89**Исходный код:** [Lib/smtplib.py](https://python-all.ru/src/2.7/Lib/smtplib.py)1011---1213Модуль [`smtplib`](https://python-all.ru/2.7/library/smtplib.html#module-smtplib) определяет объект сессии SMTP-клиента, который можно использовать для отправки почты на любую машину в Интернете с демоном, прослушивающим SMTP или ESMTP. Подробнее о работе SMTP и ESMTP см. в [**RFC 821**](https://python-all.ru/2.7/library/smtplib.html) (Простой протокол передачи почты) и [**RFC 1869**](https://python-all.ru/2.7/library/smtplib.html) (Расширения службы SMTP).1415#### `class smtplib.SMTP([host[, port[, local_hostname[, timeout]]]])`1617Экземпляр [`SMTP`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP) инкапсулирует SMTP-соединение. Он предоставляет методы для полного набора операций SMTP и ESMTP. Если указаны необязательные параметры host и port, во время инициализации вызывается метод [`connect()`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP.connect). Если он задан, *local\_hostname* используется как FQDN локального хоста в команде HELO/EHLO. В противном случае имя локального хоста определяется с помощью [`socket.getfqdn()`](https://python-all.ru/2.7/library/socket.html#socket.getfqdn). Если вызов [`connect()`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP.connect) возвращает что-то отличное от кода успеха, возбуждается исключение [`SMTPConnectError`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTPConnectError). Необязательный параметр *timeout* задаёт тайм-аут в секундах для блокирующих операций, таких как попытка соединения (если не указан, используется глобальная настройка тайм-аута по умолчанию). Если время тайм-аута истекает, возбуждается [`socket.timeout`](https://python-all.ru/2.7/library/socket.html#socket.timeout).1819Для обычного использования достаточно методов инициализации/подключения, [`sendmail()`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP.sendmail) и [`SMTP.quit()`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP.quit). Пример приведен ниже.2021Изменено в версии 2.6: добавлен параметр *timeout*.2223#### `class smtplib.SMTP_SSL([host[, port[, local_hostname[, keyfile[, certfile[, timeout]]]]]])`2425Экземпляр [`SMTP_SSL`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP_SSL) ведёт себя точно так же, как экземпляры [`SMTP`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP). [`SMTP_SSL`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP_SSL) следует использовать, если SSL необходим с самого начала соединения, а использование `starttls()` не подходит. Если *host* не указан, используется локальный хост. Если *port* опущен, используется стандартный порт SMTP через SSL (465). *local\_hostname* имеет тот же смысл, что и для класса [`SMTP`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP). *keyfile* и *certfile* также необязательны; они могут содержать закрытый ключ в формате PEM и файл цепочки сертификатов для SSL-соединения. Необязательный параметр *timeout* задаёт тайм-аут в секундах для блокирующих операций, таких как попытка соединения (если не указан, используется глобальная настройка тайм-аута по умолчанию). Если время тайм-аута истекает, возбуждается [`socket.timeout`](https://python-all.ru/2.7/library/socket.html#socket.timeout).2627Новое в версии 2.6.2829#### `class smtplib.LMTP([host[, port[, local_hostname]]])`3031Протокол LMTP, очень похожий на ESMTP, во многом основан на стандартном SMTP-клиенте. Для LMTP часто используются Unix-сокеты, поэтому наш метод `connect()` должен поддерживать их наравне с обычными серверами вида host:port. *local\_hostname* имеет тот же смысл, что и для класса [`SMTP`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP). Чтобы указать Unix-сокет, нужно использовать абсолютный путь для *host*, начинающийся с '/'.3233Поддерживается аутентификация с использованием обычного механизма SMTP. При использовании Unix-сокета LMTP обычно не поддерживает и не требует аутентификации, но возможны исключения.3435Новое в версии 2.6.3637Также определен неплохой набор исключений:3839#### `exception smtplib.SMTPException`4041Базовый класс исключения для всех остальных исключений, предоставляемых этим модулем.4243#### `exception smtplib.SMTPServerDisconnected`4445Это исключение возбуждается, когда сервер неожиданно отключается или когда предпринимается попытка использовать экземпляр [`SMTP`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP) до подключения к серверу.4647#### `exception smtplib.SMTPResponseException`4849Базовый класс для всех исключений, содержащих код ошибки SMTP. Эти исключения генерируются в некоторых случаях, когда SMTP-сервер возвращает код ошибки. Код ошибки хранится в атрибуте `smtp_code` исключения, а атрибут `smtp_error` содержит сообщение об ошибке.5051#### `exception smtplib.SMTPSenderRefused`5253Адрес отправителя отклонен. В дополнение к атрибутам, задаваемым для всех исключений [`SMTPResponseException`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTPResponseException), здесь атрибут 'sender' устанавливается в строку, которую отклонил SMTP-сервер.5455#### `exception smtplib.SMTPRecipientsRefused`5657Все адреса получателей отклонены. Ошибки для каждого получателя доступны через атрибут `recipients`, который представляет собой словарь точно такого же типа, какой возвращает [`SMTP.sendmail()`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP.sendmail).5859#### `exception smtplib.SMTPDataError`6061Сервер SMTP отказался принимать данные сообщения.6263#### `exception smtplib.SMTPConnectError`6465Произошла ошибка при установке соединения с сервером.6667#### `exception smtplib.SMTPHeloError`6869Сервер отклонил наше сообщение `HELO`.7071#### `exception smtplib.SMTPAuthenticationError`7273Произошла ошибка аутентификации SMTP. Скорее всего, сервер не принял предоставленную комбинацию имени пользователя и пароля.7475> **См. также**76>77> **[**RFC 821**](https://python-all.ru/2.7/library/smtplib.html) – Простой протокол передачи почты**78>79> Определение протокола SMTP. Этот документ описывает модель, порядок работы и детали протокола SMTP.80>81> **[**RFC 1869**](https://python-all.ru/2.7/library/smtplib.html) – Расширения службы SMTP**82>83> Определение расширений ESMTP для SMTP. Описывается инфраструктура для расширения SMTP новыми командами, динамическое обнаружение команд, предоставляемых сервером, и определяются несколько дополнительных команд.8485## 20.12.1. Объекты SMTP8687Экземпляр [`SMTP`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP) имеет следующие методы:8889#### `SMTP.set_debuglevel(level)`9091Устанавливает уровень отладочного вывода. Значение *level*, равное истине, приводит к выводу отладочных сообщений для соединения и для всех сообщений, отправленных на сервер и полученных от него.9293#### `SMTP.docmd(cmd[, argstring])`9495Отправляет команду *cmd* серверу. Необязательный аргумент *argstring* просто добавляется к команде через пробел.9697Возвращает кортеж из двух элементов: числового кода ответа и собственно строки ответа (многострочные ответы объединяются в одну длинную строку).9899При обычной работе нет необходимости явно вызывать этот метод. Он используется для реализации других методов и может быть полезен при тестировании частных расширений.100101Если соединение с сервером потеряно во время ожидания ответа, будет возбуждено [`SMTPServerDisconnected`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTPServerDisconnected).102103#### `SMTP.connect([host[, port]])`104105Подключается к хосту на указанном порту. По умолчанию подключается к локальному хосту на стандартном порту SMTP (25). Если имя хоста заканчивается на двоеточие (`':'`), за которым следует число, этот суффикс отбрасывается, а число интерпретируется как номер порта для использования. Этот метод автоматически вызывается конструктором, если хост указан при создании экземпляра. Возвращает кортеж из двух элементов: код ответа и сообщение, отправленное сервером в своём ответе на подключение.106107#### `SMTP.helo([hostname])`108109Идентифицирует себя перед SMTP-сервером с помощью `HELO`. Аргумент hostname по умолчанию равен полному доменному имени локального хоста. Сообщение, возвращённое сервером, сохраняется в атрибуте `helo_resp` объекта.110111При обычной работе нет необходимости явно вызывать этот метод. Он будет неявно вызван [`sendmail()`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP.sendmail) при необходимости.112113#### `SMTP.ehlo([hostname])`114115Идентификация перед ESMTP-сервером выполняется с помощью `EHLO`. Аргумент hostname по умолчанию принимает полное доменное имя локального хоста. Анализирует ответ на предмет возможностей ESMTP и сохраняет их для использования методом [`has_extn()`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP.has_extn). Также устанавливает несколько информационных атрибутов: сообщение, возвращённое сервером, сохраняется в атрибуте `ehlo_resp`; `does_esmtp` принимает значение true или false в зависимости от того, поддерживает ли сервер ESMTP; а `esmtp_features` представляет собой словарь, содержащий имена расширений SMTP, поддерживаемых данным сервером, и их параметры (если они есть).116117Если не требуется использовать [`has_extn()`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP.has_extn) перед отправкой почты, явно вызывать этот метод необязательно. Он будет неявно вызван методом [`sendmail()`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP.sendmail) при необходимости.118119#### `SMTP.ehlo_or_helo_if_needed()`120121Этот метод вызывает [`ehlo()`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP.ehlo) и/или [`helo()`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP.helo), если в этом сеансе не было предыдущей команды `EHLO` или `HELO`. Сначала он пытается использовать ESMTP `EHLO`.122123**[`SMTPHeloError`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTPHeloError)**124125Сервер некорректно ответил на приветствие `HELO`.126127Новое в версии 2.6.128129#### `SMTP.has_extn(name)`130131Возвращает [`True`](https://python-all.ru/2.7/library/constants.html#True), если *name* присутствует в наборе расширений SMTP-сервиса, возвращённых сервером, и [`False`](https://python-all.ru/2.7/library/constants.html#False) в противном случае. Регистр игнорируется.132133#### `SMTP.verify(address)`134135Проверяет корректность адреса на этом сервере с помощью SMTP `VRFY`. Возвращает кортеж, состоящий из кода 250 и полного адреса [**RFC 822**](https://python-all.ru/2.7/library/smtplib.html) (включая имя человека), если адрес пользователя действителен. В противном случае возвращает код ошибки SMTP 400 или больше и строку ошибки.136137> **Примечание**138>139> Многие сайты отключают SMTP `VRFY`, чтобы помешать спамерам.140141#### `SMTP.login(user, password)`142143Выполняет вход на SMTP-сервер, требующий аутентификации. Аргументами являются имя пользователя и пароль для аутентификации. Если в течение этого сеанса ещё не было выполнено команды `EHLO` или `HELO`, этот метод сначала пробует ESMTP `EHLO`. Этот метод завершается нормально, если аутентификация прошла успешно, или может возбудить следующие исключения:144145**[`SMTPHeloError`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTPHeloError)**146147Сервер некорректно ответил на приветствие `HELO`.148149**[`SMTPAuthenticationError`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTPAuthenticationError)**150151Сервер не принял комбинацию имя пользователя/пароль.152153**[`SMTPException`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTPException)**154155Не найден подходящий метод аутентификации.156157#### `SMTP.starttls([keyfile[, certfile]])`158159Переводит SMTP-соединение в режим TLS (безопасность транспортного уровня). Все последующие SMTP-команды будут зашифрованы. После этого следует снова вызвать [`ehlo()`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP.ehlo).160161Если указаны *keyfile* и *certfile*, они передаются функции [`ssl()`](https://python-all.ru/2.7/library/ssl.html#module-ssl) модуля [`socket`](https://python-all.ru/2.7/library/socket.html#module-socket).162163Если в течение этого сеанса ещё не выполнялась команда `EHLO` или `HELO`, метод сначала пытается выполнить ESMTP `EHLO`.164165Изменено в версии 2.6.166167**[`SMTPHeloError`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTPHeloError)**168169Сервер некорректно ответил на приветствие `HELO`.170171**[`SMTPException`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTPException)**172173Сервер не поддерживает расширение STARTTLS.174175Изменено в версии 2.6.176177**[`RuntimeError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.RuntimeError)**178179Интерпретатор Python не поддерживает SSL/TLS.180181#### `SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])`182183Отправляет почту. Обязательными аргументами являются строка обратного адреса [**RFC 822**](https://python-all.ru/2.7/library/smtplib.html), список строк адресов получателей [**RFC 822**](https://python-all.ru/2.7/library/smtplib.html) (простая строка будет рассматриваться как список с одним адресом) и строка сообщения. Вызывающий может передать список параметров ESMTP (например, `8bitmime`) для использования в командах `MAIL FROM` в качестве *mail\_options*. Параметры ESMTP (например, команды `DSN`), которые должны использоваться со всеми командами `RCPT`, могут быть переданы как *rcpt\_options*. (Если необходимо использовать разные параметры ESMTP для разных получателей, нужно использовать низкоуровневые методы, такие как `mail()`, `rcpt()` и `data()`, для отправки сообщения.)184185> **Примечание**186>187> Параметры *from\_addr* и *to\_addrs* используются для построения конверта сообщения, используемого транспортными агентами. [`SMTP`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTP) никак не изменяет заголовки сообщения.188189Если в течение этого сеанса ещё не выполнялась команда `EHLO` или `HELO`, данный метод сначала пытается выполнить ESMTP `EHLO`. Если сервер поддерживает ESMTP, ему будут переданы размер сообщения и каждая из указанных опций (если опция присутствует в наборе возможностей, объявленных сервером). Если `EHLO` не удаётся, будет выполнена попытка `HELO` и ESMTP-опции будут подавлены.190191Метод завершается нормально, если почта принята хотя бы одним получателем. В противном случае возбуждается исключение. То есть, если метод не возбуждает исключение, значит, кто-то должен получить ваше письмо. Если метод не возбуждает исключение, он возвращает словарь с одной записью для каждого получателя, которому было отказано. Каждая запись содержит кортеж из кода ошибки SMTP и соответствующего сообщения об ошибке, отправленного сервером.192193Этот метод может возбуждать следующие исключения:194195**[`SMTPRecipientsRefused`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTPRecipientsRefused)**196197Все получатели были отклонены. Почта не была доставлена. Атрибут `recipients` объекта исключения представляет собой словарь с информацией об отклонённых получателях (такой же, как возвращается, когда хотя бы один получатель был принят).198199**[`SMTPHeloError`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTPHeloError)**200201Сервер некорректно ответил на приветствие `HELO`.202203**[`SMTPSenderRefused`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTPSenderRefused)**204205Сервер не принял адрес *from\_addr*.206207**[`SMTPDataError`](https://python-all.ru/2.7/library/smtplib.html#smtplib.SMTPDataError)**208209Сервер ответил неожиданным кодом ошибки (не связанным с отказом отдельному получателю).210211Если не указано иное, соединение остаётся открытым даже после возбуждения исключения.212213#### `SMTP.quit()`214215Завершает сеанс SMTP и закрывает соединение. Возвращает результат команды SMTP `QUIT`.216217Изменено в версии 2.6: Возвращает значение.218219Также поддерживаются низкоуровневые методы, соответствующие стандартным командам SMTP/ESMTP `HELP`, `RSET`, `NOOP`, `MAIL`, `RCPT` и `DATA`. Обычно их не нужно вызывать напрямую, поэтому они не документированы здесь. Подробнее см. в коде модуля.220221## 20.12.2. Пример SMTP222223Этот пример запрашивает у пользователя адреса, необходимые в конверте сообщения (адреса ‘To’\\nи ‘From’), а также само сообщение для отправки. Обратите внимание, что заголовки,\\nкоторые должны быть включены в сообщение, должны быть включены в сообщение при вводе; этот\\nпример не выполняет никакой обработки заголовков [**RFC 822**](https://python-all.ru/2.7/library/smtplib.html). В частности,\\nадреса ‘To’ и ‘From’ должны быть явно включены в заголовки сообщения.224225```python226import smtplib227228def prompt(prompt):229 return raw_input(prompt).strip()230231fromaddr = prompt("From: ")232toaddrs = prompt("To: ").split()233print "Enter message, end with ^D (Unix) or ^Z (Windows):"234235# Добавьте заголовки From: и To: в начало!236msg = ("From: %s\r\nTo: %s\r\n\r\n"237 % (fromaddr, ", ".join(toaddrs)))238while 1:239 try:240 line = raw_input()241 except EOFError:242 break243 if not line:244 break245 msg = msg + line246247print "Message length is " + repr(len(msg))248249server = smtplib.SMTP('localhost')250server.set_debuglevel(1)251server.sendmail(fromaddr, toaddrs, msg)252server.quit()253```254255> **Примечание**256>257> В целом рекомендуется использовать возможности пакета [`email`](https://python-all.ru/2.7/library/email.html#module-email) для создания email-сообщения, которое затем можно преобразовать в строку и отправить через `sendmail()`; см. [примеры email](https://python-all.ru/2.7/library/email-examples.html#email-examples).258