Документация Python неофициальный перевод

smtplib.md

313 строк · 31.6 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.4/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.4/library/smtplib.html#module-smtplib) – клиент протокола SMTP89**Исходный код:** [Lib/smtplib.py](https://python-all.ru/src/3.4/Lib/smtplib.py)1011---1213Модуль [`smtplib`](https://python-all.ru/3.4/library/smtplib.html#module-smtplib) определяет объект сеанса клиента SMTP, который можно использовать для отправки почты на любой компьютер в сети с демоном SMTP или ESMTP. Подробнее о работе SMTP и ESMTP см. в [**RFC 821**](https://python-all.ru/3.4/library/smtplib.html) (Протокол простой передачи почты) и [**RFC 1869**](https://python-all.ru/3.4/library/smtplib.html) (SMTP Service Extensions).1415#### `class smtplib.SMTP(host='', port=0, local_hostname=None, [timeout, ]source_address=None)`1617Экземпляр [`SMTP`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP) инкапсулирует SMTP-соединение. Он содержит методы, поддерживающие полный набор операций SMTP и ESMTP. Если указаны необязательные параметры host и port, метод [`connect()`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP.connect) вызывается с этими параметрами во время инициализации. Если задан параметр *local\_hostname*, он используется как FQDN локального хоста в команде HELO/EHLO. В противном случае имя локального хоста определяется с помощью [`socket.getfqdn()`](https://python-all.ru/3.4/library/socket.html#socket.getfqdn). Если вызов [`connect()`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP.connect) возвращает код, отличный от успешного, возбуждается исключение [`SMTPConnectError`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTPConnectError). Необязательный параметр *timeout* задаёт тайм-аут в секундах для блокирующих операций, таких как попытка подключения (если не указан, используется глобальная настройка тайм-аута по умолчанию). Если тайм-аут истекает, возбуждается исключение [`socket.timeout`](https://python-all.ru/3.4/library/socket.html#socket.timeout). Необязательный параметр source\_address позволяет привязаться к определённому исходному адресу на машине с несколькими сетевыми интерфейсами и/или к определённому исходному TCP-порту. Он принимает кортеж из двух элементов (host, port), к которому сокет привязывается как к своему исходному адресу перед подключением. Если параметр опущен (или host и port равны `''` и/или 0 соответственно), используется поведение ОС по умолчанию.1819Для обычного использования достаточно методов инициализации/подключения, [`sendmail()`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP.sendmail) и `quit()`. Пример приведён ниже.2021Класс [`SMTP`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP) поддерживает оператор [`with`](https://python-all.ru/3.4/reference/compound_stmts.html#with). При таком использовании команда SMTP `QUIT` отправляется автоматически при выходе из оператора [`with`](https://python-all.ru/3.4/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.4/reference/compound_stmts.html#with).3334Изменено в версии 3.3: добавлен аргумент source\_address.3536#### `class smtplib.SMTP_SSL(host='', port=0, local_hostname=None, keyfile=None, certfile=None, [timeout, ]context=None, source_address=None)`3738Экземпляр [`SMTP_SSL`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP_SSL) ведёт себя точно так же, как экземпляры [`SMTP`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP). [`SMTP_SSL`](https://python-all.ru/3.4/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.4/library/smtplib.html#smtplib.SMTP). Необязательный параметр *context* может содержать [`SSLContext`](https://python-all.ru/3.4/library/ssl.html#ssl.SSLContext) и позволяет настраивать различные аспекты безопасного соединения. Рекомендуется прочитать [*Рекомендации по безопасности*](https://python-all.ru/3.4/library/ssl.html#ssl-security) для наилучших практик.3940*файл ключа* и *файл сертификата* – устаревшая альтернатива *контексту*, и могут указывать на файл закрытого ключа и цепочки сертификатов в формате PEM для SSL-соединения.4142Изменено в версии 3.3: был добавлен параметр *context*.4344Изменено в версии 3.3: добавлен аргумент source\_address.4546Изменено в версии 3.4: Класс теперь поддерживает проверку имени хоста с помощью [`ssl.SSLContext.check_hostname`](https://python-all.ru/3.4/library/ssl.html#ssl.SSLContext.check_hostname) и *Server Name Indication* (см. [`ssl.HAS_SNI`](https://python-all.ru/3.4/library/ssl.html#ssl.HAS_SNI)).4748#### `class smtplib.LMTP(host='', port=LMTP_PORT, local_hostname=None, source_address=None)`4950Протокол LMTP, очень похожий на ESMTP, во многом основан на стандартном клиенте SMTP. Для LMTP обычно используются Unix-сокеты, поэтому наш метод `connect()` должен поддерживать как их, так и обычный сервер host:port. Необязательные аргументы local\_hostname и source\_address имеют то же значение, что и в классе [`SMTP`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP). Чтобы указать Unix-сокет, необходимо использовать абсолютный путь для *host*, начинающийся с '/'.5152Поддерживается аутентификация с использованием обычного механизма SMTP. При использовании Unix-сокета LMTP обычно не поддерживает и не требует аутентификации, но возможны исключения.5354Также определен неплохой набор исключений:5556#### `exception smtplib.SMTPException`5758Подкласс [`OSError`](https://python-all.ru/3.4/library/exceptions.html#OSError), являющийся базовым классом исключений для всех остальных исключений, предоставляемых этим модулем.5960Изменено в версии 3.4: SMTPException стал подклассом [`OSError`](https://python-all.ru/3.4/library/exceptions.html#OSError)6162#### `exception smtplib.SMTPServerDisconnected`6364Это исключение возбуждается, когда сервер неожиданно разрывает соединение или когда предпринимается попытка использовать экземпляр [`SMTP`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP) до подключения к серверу.6566#### `exception smtplib.SMTPResponseException`6768Базовый класс для всех исключений, включающих код ошибки SMTP. Эти исключения генерируются в некоторых случаях, когда сервер SMTP возвращает код ошибки. Код ошибки хранится в атрибуте `smtp_code` объекта исключения, а атрибут `smtp_error` содержит сообщение об ошибке.6970#### `exception smtplib.SMTPSenderRefused`7172Адрес отправителя отклонён. В дополнение к атрибутам, устанавливаемым для всех исключений [`SMTPResponseException`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTPResponseException), в этом исключении атрибут 'sender' принимает значение строки, которую сервер SMTP отклонил.7374#### `exception smtplib.SMTPRecipientsRefused`7576Все адреса получателей отклонены. Ошибки для каждого получателя доступны через атрибут `recipients`, который представляет собой словарь того же типа, что возвращает [`SMTP.sendmail()`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP.sendmail).7778#### `exception smtplib.SMTPDataError`7980Сервер SMTP отказался принимать данные сообщения.8182#### `exception smtplib.SMTPConnectError`8384Произошла ошибка при установке соединения с сервером.8586#### `exception smtplib.SMTPHeloError`8788Сервер отклонил наше сообщение `HELO`.8990#### `exception smtplib.SMTPAuthenticationError`9192Произошла ошибка аутентификации SMTP. Скорее всего, сервер не принял предоставленную комбинацию имени пользователя и пароля.9394> **См. также**95>96> **[**RFC 821**](https://python-all.ru/3.4/library/smtplib.html) – Простой протокол передачи почты**97>98> Определение протокола SMTP. Этот документ описывает модель, порядок работы и детали протокола SMTP.99>100> **[**RFC 1869**](https://python-all.ru/3.4/library/smtplib.html) – Расширения службы SMTP**101>102> Определение расширений ESMTP для SMTP. Описывается инфраструктура для расширения SMTP новыми командами, динамическое обнаружение команд, предоставляемых сервером, и определяются несколько дополнительных команд.103104## 21.17.1. Объекты SMTP105106Экземпляр [`SMTP`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP) имеет следующие методы:107108#### `SMTP.set_debuglevel(level)`109110Устанавливает уровень отладочного вывода. Значение *level*, равное истине, приводит к выводу отладочных сообщений для соединения и для всех сообщений, отправленных на сервер и полученных от него.111112#### `SMTP.docmd(cmd, args='')`113114Отправляет команду *cmd* серверу. Необязательный аргумент *args* просто дописывается к команде через пробел.115116Возвращает кортеж из двух элементов: числового кода ответа и собственно строки ответа (многострочные ответы объединяются в одну длинную строку).117118При обычной работе нет необходимости явно вызывать этот метод. Он используется для реализации других методов и может быть полезен при тестировании частных расширений.119120Если соединение с сервером теряется во время ожидания ответа, будет возбуждено исключение [`SMTPServerDisconnected`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTPServerDisconnected).121122#### `SMTP.connect(host='localhost', port=0)`123124Подключается к хосту на указанном порту. По умолчанию подключается к локальному хосту на стандартном порту SMTP (25). Если имя хоста заканчивается на двоеточие (`':'`), за которым следует число, этот суффикс отбрасывается, а число интерпретируется как номер порта для использования. Этот метод автоматически вызывается конструктором, если хост указан при создании экземпляра. Возвращает кортеж из двух элементов: код ответа и сообщение, отправленное сервером в своём ответе на подключение.125126#### `SMTP.helo(name='')`127128Идентификация на SMTP-сервере выполняется с помощью `HELO`. Аргумент hostname по умолчанию принимает полностью определённое доменное имя локального хоста. Сообщение, возвращаемое сервером, сохраняется в атрибуте `helo_resp` объекта.129130В обычной работе явно вызывать этот метод не требуется. Он будет вызван неявно методом [`sendmail()`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP.sendmail) при необходимости.131132#### `SMTP.ehlo(name='')`133134Идентификация на ESMTP-сервере выполняется с помощью `EHLO`. Аргумент hostname по умолчанию принимает полностью определённое доменное имя локального хоста. Проверить ответ на наличие опций ESMTP и сохранить их для использования методом [`has_extn()`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP.has_extn). Также устанавливаются несколько информационных атрибутов: сообщение, возвращаемое сервером, сохраняется в атрибуте `ehlo_resp`; атрибут `does_esmtp` устанавливается в true или false в зависимости от того, поддерживает ли сервер ESMTP, а `esmtp_features` будет словарём, содержащим имена расширений SMTP-сервиса, которые поддерживает этот сервер, и их параметры (если есть).135136Если нет необходимости использовать [`has_extn()`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP.has_extn) перед отправкой почты, вызывать этот метод явно не требуется. Он будет вызван неявно методом [`sendmail()`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP.sendmail) при необходимости.137138#### `SMTP.ehlo_or_helo_if_needed()`139140Этот метод вызывает [`ehlo()`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP.ehlo) и/или [`helo()`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP.helo), если за эту сессию ещё не было предыдущей команды `EHLO` или `HELO`. Он сначала пытается использовать ESMTP `EHLO`.141142**[`SMTPHeloError`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTPHeloError)**143144Сервер не ответил корректно на приветствие145146`HELO`147148.149150#### `SMTP.has_extn(name)`151152Возвращает [`True`](https://python-all.ru/3.4/library/constants.html#True), если *name* присутствует в наборе расширений SMTP-сервиса, возвращённых сервером, иначе [`False`](https://python-all.ru/3.4/library/constants.html#False). Регистр не учитывается.153154#### `SMTP.verify(address)`155156Check the validity of an address on this server using SMTP `VRFY`. Returns a tuple consisting of code 250 and a full [**RFC 822**](https://python-all.ru/3.4/library/smtplib.html) address (including human name) if the user address is valid. Otherwise returns an SMTP error code of 400 or greater and an error string.157158> **Примечание**159>160> Многие сайты отключают SMTP `VRFY`, чтобы помешать спамерам.161162#### `SMTP.login(user, password)`163164Выполнить вход на SMTP-сервер, требующий аутентификации. Аргументами являются имя пользователя и пароль для аутентификации. Если за эту сессию ещё не было предыдущей команды `EHLO` или `HELO`, этот метод сначала пытается использовать ESMTP `EHLO`. Этот метод завершится нормально, если аутентификация прошла успешно, или может вызвать следующие исключения:165166**[`SMTPHeloError`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTPHeloError)**167168Сервер не ответил корректно на приветствие169170`HELO`171172.173174**[`SMTPAuthenticationError`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTPAuthenticationError)**175176Сервер не принял комбинацию имя пользователя/пароль.177178**[`SMTPException`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTPException)**179180Не найден подходящий метод аутентификации.181182#### `SMTP.starttls(keyfile=None, certfile=None, context=None)`183184Перевести SMTP-соединение в режим TLS (безопасность транспортного уровня). Все последующие SMTP-команды будут зашифрованы. После этого следует снова вызвать [`ehlo()`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP.ehlo).185186Если указаны *keyfile* и *certfile*, они передаются функции [`ssl()`](https://python-all.ru/3.4/library/ssl.html#module-ssl) модуля [`socket`](https://python-all.ru/3.4/library/socket.html#module-socket).187188Необязательный параметр *context* – это объект [`ssl.SSLContext`](https://python-all.ru/3.4/library/ssl.html#ssl.SSLContext); это альтернатива использованию keyfile и certfile, и если он указан, оба *keyfile* и *certfile* должны быть None.189190Если за эту сессию ещё не было предыдущей команды `EHLO` или `HELO`, этот метод сначала пытается использовать ESMTP `EHLO`.191192**[`SMTPHeloError`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTPHeloError)**193194Сервер не ответил корректно на приветствие195196`HELO`197198.199200**[`SMTPException`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTPException)**201202Сервер не поддерживает расширение STARTTLS.203204**[`RuntimeError`](https://python-all.ru/3.4/library/exceptions.html#RuntimeError)**205206Интерпретатор Python не поддерживает SSL/TLS.207208Изменено в версии 3.3: был добавлен параметр *context*.209210Изменено в версии 3.4: Теперь метод поддерживает проверку имени хоста с помощью `SSLContext.check_hostname` и *Server Name Indicator* (см. [`HAS_SNI`](https://python-all.ru/3.4/library/ssl.html#ssl.HAS_SNI)).211212#### `SMTP.sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[])`213214Отправка почты. Обязательные аргументы: строка адреса отправителя в формате [**RFC 822**](https://python-all.ru/3.4/library/smtplib.html), список строк адресов получателей в формате [**RFC 822**](https://python-all.ru/3.4/library/smtplib.html) (отдельная строка будет рассматриваться как список с одним адресом) и строка сообщения. Вызывающий может передать список параметров ESMTP (например, `8bitmime`) для использования в командах `MAIL FROM` как *mail\_options*. Параметры ESMTP (например, команды `DSN`), которые следует использовать со всеми командами `RCPT`, можно передать как *rcpt\_options*. (Если нужно использовать разные параметры ESMTP для разных получателей, придётся использовать низкоуровневые методы, такие как `mail()`, `rcpt()` и `data()` для отправки сообщения.)215216> **Примечание**217>218> Параметры *from\_addr* и *to\_addrs* используются для построения конверта сообщения, используемого транспортными агентами. `sendmail` никак не изменяет заголовки сообщения.219220*msg* может быть строкой, содержащей символы в диапазоне ASCII, или байтовой строкой. Строка кодируется в байты с помощью кодека ascii, а отдельные символы `\r` и `\n` преобразуются в `\r\n`. Байтовая строка не изменяется.221222Если в этом сеансе ещё не было предыдущей команды `EHLO` или `HELO`, этот метод сначала пробует ESMTP `EHLO`. Если сервер поддерживает ESMTP, ему передаётся размер сообщения и каждый из указанных параметров (если параметр входит в набор возможностей, объявляемых сервером). Если `EHLO` не удаётся, предпринимается попытка `HELO`, а параметры ESMTP отбрасываются.223224Метод завершается нормально, если почта принята хотя бы одним получателем. В противном случае возбуждается исключение. То есть, если метод не возбуждает исключение, значит, кто-то должен получить ваше письмо. Если метод не возбуждает исключение, он возвращает словарь с одной записью для каждого получателя, которому было отказано. Каждая запись содержит кортеж из кода ошибки SMTP и соответствующего сообщения об ошибке, отправленного сервером.225226Этот метод может возбуждать следующие исключения:227228**[`SMTPRecipientsRefused`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTPRecipientsRefused)**229230Все получатели были отклонены. Почту не получил никто. Атрибут231232`recipients`233234объекта исключения представляет собой словарь с информацией об отклонённых получателях (аналогичный тому, который возвращается, когда был принят хотя бы один получатель).235236**[`SMTPHeloError`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTPHeloError)**237238Сервер не ответил должным образом на приветствие239240`HELO`241242.243244**[`SMTPSenderRefused`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTPSenderRefused)**245246Сервер не принял адрес247248*from\_addr*249250.251252**[`SMTPDataError`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTPDataError)**253254Сервер ответил неожиданным кодом ошибки (не связанным с отказом отдельному получателю).255256Если не указано иное, соединение остаётся открытым даже после возбуждения исключения.257258Изменено в версии 3.2: *msg* может быть байтовой строкой.259260#### `SMTP.send_message(msg, from_addr=None, to_addrs=None, mail_options=[], rcpt_options=[])`261262Это удобный метод для вызова [`sendmail()`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP.sendmail) с сообщением, представленным объектом [`email.message.Message`](https://python-all.ru/3.4/library/email.message.html#email.message.Message). Аргументы имеют то же значение, что и для [`sendmail()`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP.sendmail), за исключением того, что *msg* является объектом `Message`.263264Если *from\_addr* равно `None` или *to\_addrs* равно `None`, `send_message` заполняет эти аргументы адресами, извлечёнными из заголовков *msg* в соответствии с [**RFC 2822**](https://python-all.ru/3.4/library/smtplib.html): *from\_addr* устанавливается в поле *Sender* (если оно присутствует), в противном случае – в поле *From*. *to\_adresses* объединяет значения (если они есть) полей *To*, *Cc* и *Bcc* из *msg*. Если в сообщении встречается ровно один набор заголовков *Resent-\**, обычные заголовки игнорируются и используются заголовки *Resent-\**. Если сообщение содержит более одного набора заголовков *Resent-\**, возбуждается [`ValueError`](https://python-all.ru/3.4/library/exceptions.html#ValueError), поскольку нет способа однозначно определить самый последний набор заголовков *Resent-*.265266`send_message` сериализует *msg* с помощью [`BytesGenerator`](https://python-all.ru/3.4/library/email.generator.html#email.generator.BytesGenerator) с `\r\n` в качестве *linesep* и вызывает [`sendmail()`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP.sendmail) для передачи полученного сообщения. Независимо от значений *from\_addr* и *to\_addrs*, `send_message` не передаёт никакие заголовки *Bcc* или *Resent-Bcc*, которые могут присутствовать в *msg*.267268Новое в версии 3.2.269270#### `SMTP.quit()`271272Завершает сеанс SMTP и закрывает соединение. Возвращает результат команды SMTP `QUIT`.273274Также поддерживаются низкоуровневые методы, соответствующие стандартным командам SMTP/ESMTP: `HELP`, `RSET`, `NOOP`, `MAIL`, `RCPT` и `DATA`. Обычно их не нужно вызывать напрямую, поэтому они здесь не документируются. Подробности см. в коде модуля.275276## 21.17.2. Пример SMTP277278Этот пример запрашивает у пользователя адреса, необходимые в конверте сообщения (адреса ‘To’\\nи ‘From’), а также само сообщение для отправки. Обратите внимание, что заголовки,\\nкоторые должны быть включены в сообщение, должны быть включены в сообщение при вводе; этот\\nпример не выполняет никакой обработки заголовков [**RFC 822**](https://python-all.ru/3.4/library/smtplib.html). В частности,\\nадреса ‘To’ и ‘From’ должны быть явно включены в заголовки сообщения.279280```python281import smtplib282283def prompt(prompt):284    return input(prompt).strip()285286fromaddr = prompt("From: ")287toaddrs  = prompt("To: ").split()288print("Enter message, end with ^D (Unix) or ^Z (Windows):")289290# Добавьте заголовки From: и To: в начало!291msg = ("From: %s\r\nTo: %s\r\n\r\n"292       % (fromaddr, ", ".join(toaddrs)))293while True:294    try:295        line = input()296    except EOFError:297        break298    if not line:299        break300    msg = msg + line301302print("Message length is", len(msg))303304server = smtplib.SMTP('localhost')305server.set_debuglevel(1)306server.sendmail(fromaddr, toaddrs, msg)307server.quit()308```309310> **Примечание**311>312> В целом рекомендуется использовать возможности пакета [`email`](https://python-all.ru/3.4/library/email.html#module-email) для создания сообщения электронной почты, которое затем можно отправить с помощью [`send_message()`](https://python-all.ru/3.4/library/smtplib.html#smtplib.SMTP.send_message); см. [*email: Примеры*](https://python-all.ru/3.4/library/email-examples.html#email-examples).313