Spec-Zone.ru › Python 3.6

smtplib — Клиент протокола SMTP

Исходный код: Lib/smtplib.py

Модуль smtplib определяет объект сеанса SMTP-клиента, который можно использовать для отправки почты на любой интернет-машине с SMTP или ESMTP-сервером. Для получения подробной информации об операциях SMTP и ESMTP обратитесь к RFC 821 (Простой протокол передачи почты) и RFC 1869 (Расширения службы SMTP).

class smtplib.SMTP(host='', port=0, local_hostname=None, [timeout, ]source_address=None)

Экземпляр SMTP инкапсулирует SMTP-соединение. Он имеет методы, которые поддерживают полный набор операций SMTP и ESMTP. Если заданы необязательные параметры host и port, метод SMTP connect() вызывается с этими параметрами во время инициализации. Если указано, local_hostname используется в качестве FQDN локального узла в команде HELO/EHLO. В противном случае имя локального узла находится с помощью socket.getfqdn(). Если вызов connect() возвращает что-либо помимо кода успешного выполнения, генерируется SMTPConnectError. Необязательный параметр timeout задает таймаут в секундах для блокирующих операций, таких как попытка подключения (если не указано, используется глобальное значение таймаута по умолчанию). Если таймаут истечет, будет генерироваться socket.timeout. Необязательный параметр source_address позволяет привязываться к определенному исходному адресу в машине с несколькими сетевыми интерфейсами и/или к определенному исходному TCP-порту. Он принимает пару из двух элементов (хост, порт) для того, чтобы сокет привязался к ней как к исходному адресу перед подключением. Если он опущен (или если хост или порт являются '' и/или 0 соответственно), будет использоваться поведение по умолчанию ОС.

Для обычного использования вам потребуются только методы инициализации/подключения, sendmail() и SMTP.quit(). Пример приведен ниже.

Класс SMTP поддерживает оператор with. При использовании таким образом, команда SMTP QUIT выполняется автоматически при выходе из оператора with. Например:

>>> from smtplib import SMTP
>>> with SMTP("domain.org") as smtp:
...     smtp.noop()
...
(250, b'Ok')
>>>

Изменено в версии 3.3: Добавлена поддержка оператора with.

Изменено в версии 3.3: Добавлен аргумент source_address.

Добавлена в версии 3.5: Теперь поддерживается расширение SMTPUTF8 (RFC 6531).

class smtplib.SMTP_SSL(host='', port=0, local_hostname=None, keyfile=None, certfile=None, [timeout, ]context=None, source_address=None)

Экземпляр SMTP_SSL ведет себя точно так же, как экземпляры SMTP. SMTP_SSL следует использовать в ситуациях, когда SSL требуется с самого начала подключения и использование starttls() не подходит. Если host не указан, используется локальный хост. Если port равен нулю, используется стандартный порт SMTP по SSL (465). Необязательные аргументы local_hostname, timeout и source_address имеют то же значение, что и в классе SMTP. Необязательный параметр context может содержать SSLContext и позволяет настроить различные аспекты защищенного подключения. Для получения рекомендаций по лучшей практике обратитесь к Рекомендации по безопасности.

keyfile и certfile — это устаревший альтернативный способ передаче context и могут указывать на файл с открытым ключом и цепочкой сертификатов PEM для SSL-соединения.

Изменено в версии 3.3: Добавлен параметр context.

Изменено в версии 3.3: Добавлен аргумент source_address.

Изменено в версии 3.4: Класс теперь поддерживает проверку хоста с помощью ssl.SSLContext.check_hostname и Server Name Indication (см. ssl.HAS_SNI).

Устарело начиная с версии 3.6: keyfile и certfile устарели в пользу context. Используйте ssl.SSLContext.load_cert_chain() вместо этого или позвольте ssl.create_default_context() выбрать доверенные сертификаты CA системы для вас.

class smtplib.LMTP(host='', port=LMTP_PORT, local_hostname=None, source_address=None)

Протокол LMTP, который очень похож на ESMTP, в значительной степени основан на стандартном клиенте SMTP. Для LMTP часто используют Unix-сокеты, поэтому наш метод connect() должен также поддерживать их, а также обычный хост:порт сервера. Необязательные аргументы local_hostname и source_address имеют то же значение, что и в классе SMTP. Для указания Unix-сокет необходимо использовать абсолютный путь для host, начинающийся с '/'.

Поддерживается аутентификация, используя обычный механизм SMTP. При использовании Unix-сокеты LMTP, как правило, не поддерживает и не требует аутентификации, но ваш опыт может отличаться.

Также определен ряд исключений:

exception smtplib.SMTPException

Подкласс OSError, являющийся базовым классом исключений для всех других исключений, предоставляемых данным модулем.

Изменено в версии 3.4: SMTPException стал подклассом OSError

exception smtplib.SMTPServerDisconnected

Это исключение генерируется, когда сервер неожиданно отключается или когда попытка использовать экземпляр SMTP выполняется до его подключения к серверу.

exception smtplib.SMTPResponseException

Базовый класс для всех исключений, которые включают код ошибки SMTP. Эти исключения генерируются в некоторых случаях, когда SMTP-сервер возвращает код ошибки. Код ошибки хранится в атрибуте smtp_code ошибки, а атрибут smtp_error устанавливается на сообщение об ошибке.

exception smtplib.SMTPSenderRefused

Отклонен адрес отправителя. В дополнение к атрибутам, установленным всеми исключениями SMTPResponseException, устанавливается ‘sender’ со строкой, которую SMTP-сервер отклонил.

exception smtplib.SMTPRecipientsRefused

Все адреса получателей отклонены. Ошибки для каждого получателя доступны через атрибут recipients, который представляет собой словарь того же типа, что и возвращает SMTP.sendmail().

exception smtplib.SMTPDataError

SMTP-сервер отказался принять данные сообщения.

exception smtplib.SMTPConnectError

Во время установления подключения к серверу произошла ошибка.

exception smtplib.SMTPHeloError

Сервер отклонил наше сообщение HELO.

exception smtplib.SMTPNotSupportedError

Попытка использовать команду или параметр не поддерживается сервером.

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

exception smtplib.SMTPAuthenticationError

Произошла ошибка аутентификации SMTP. Вероятно, сервер не принял предоставленную комбинацию имени пользователя/пароля.

См. также

RFC 821 - Простой протокол передачи почты

Определение протокола SMTP. Этот документ охватывает модель, порядок работы и детали протокола SMTP.

RFC 1869 - Расширения службы SMTP

Определение расширений ESMTP для SMTP. Этот документ описывает механизм расширения SMTP новыми командами, поддержку динамического обнаружения поддерживаемых сервером команд и определяет несколько дополнительных команд.

21.17.1. Объекты SMTP

У экземпляра SMTP есть следующие методы:

SMTP.set_debuglevel(level)

Устанавливает уровень отладки вывода. Значение 1 или True для level приводит к отображению сообщений отладки для соединения и для всех сообщений, отправленных и полученных от сервера. Значение 2 для level приводит к тому, что эти сообщения будут содержать отметки времени.

Изменено в версии 3.5: Добавлен уровень отладки 2.

SMTP.docmd(cmd, args='')

Отправляет команду cmd на сервер. Необязательный аргумент args просто добавляется к команде, разделенный пробелом.

Возвращает кортеж из двух элементов: числовой код ответа и строку ответа (многострочные ответы объединяются в одну длинную строку).

В обычной работе явно вызывать этот метод не требуется. Он используется для реализации других методов и может быть полезен для тестирования закрытых расширений.

Если соединение с сервером прерывается во время ожидания ответа, будет возбуждено исключение SMTPServerDisconnected.

SMTP.connect(host='localhost', port=0)

Подключается к хосту по указанному порту. По умолчанию подключается к локальному хосту на стандартном порту SMTP (25). Если имя хоста заканчивается двоеточием (':') и числом, этот суффикс будет удален, а число будет интерпретировано как порт для использования. Этот метод автоматически вызывается конструктором, если имя хоста указано при инициализации. Возвращает кортеж из двух элементов: код ответа и сообщение, отправленное сервером в ответ на подключение.

SMTP.helo(name='')

Представляет себя серверу SMTP с использованием HELO. Аргумент hostname по умолчанию — полностью квалифицированное имя домена локального хоста. Сообщение, возвращенное сервером, хранится в атрибуте helo_resp объекта.

В обычной работе явно вызывать этот метод не требуется. Он будет неявно вызываться методом sendmail() при необходимости.

SMTP.ehlo(name='')

Представляет себя серверу ESMTP с использованием EHLO. Аргумент hostname по умолчанию — полностью квалифицированное имя домена локального хоста. Проверяет ответ на наличие расширений ESMTP и сохраняет их для использования методом has_extn(). Также устанавливает несколько информационных атрибутов: сообщение, возвращенное сервером, хранится в атрибуте ehlo_resp, does_esmtp устанавливается в true или false в зависимости от поддержки сервером ESMTP, а esmtp_features будет словарем, содержащим имена расширений службы SMTP, поддерживаемых этим сервером, и их параметры (если таковые имеются).

Если вы не хотите использовать has_extn() до отправки почты, явно вызывать этот метод не требуется. Он будет неявно вызываться методом sendmail() при необходимости.

SMTP.ehlo_or_helo_if_needed()

Этот метод вызывает ehlo() и/или helo(), если до этого в этом сеансе не было команды EHLO или HELO. Попытка использовать ESMTP EHLO в первую очередь.

SMTPHeloError

Сервер некорректно ответил на приветствие HELO.

SMTP.has_extn(name)

Возвращает True, если name присутствует в наборе расширений SMTP, возвращенных сервером, и False в противном случае. Регистр игнорируется.

SMTP.verify(address)

Проверяет корректность адреса на данном сервере, используя SMTP VRFY. Возвращает кортеж, состоящий из кода 250 и полного адреса RFC 822 (включая имя получателя), если адрес пользователя корректен. В противном случае возвращает код SMTP ошибки 400 или выше и сообщение об ошибке.

Примечание

Многие сайты отключают SMTP VRFY для противодействия спамерам.

SMTP.login(user, password, *, initial_response_ok=True)

Вход на SMTP-сервер, требующий аутентификации. В качестве аргументов используются имя пользователя и пароль для аутентификации. Если до этого в этом сеансе не было команды EHLO или HELO, этот метод сначала попробует ESMTP EHLO. Этот метод вернет обычное значение, если аутентификация прошла успешно, или может вызвать следующие исключения:

SMTPHeloError

Сервер некорректно ответил на приветствие HELO.

SMTPAuthenticationError

Сервер не принял сочетание имя пользователя/пароль.

SMTPNotSupportedError

Команда AUTH не поддерживается сервером.

SMTPException

Не был найден подходящий метод аутентификации.

Каждый из методов аутентификации, поддерживаемых smtplib, будет опробован по очереди, если они объявлены поддерживаемыми сервером. См. auth() для списка поддерживаемых методов аутентификации. initial_response_ok передается в auth().

Необязательный ключевой аргумент initial_response_ok указывает, можно ли, для методов аутентификации, которые её поддерживают, отправить «начальный ответ», как указано в RFC 4954 вместе с командой AUTH, а не требуя ответа на запрос/ответ.

Изменено в версии 3.5: SMTPNotSupportedError может быть возбуждено, и был добавлен параметр initial_response_ok.

SMTP.auth(mechanism, authobject, *, initial_response_ok=True)

Выполните команду SMTP AUTH для указанного механизма аутентификации и обработайте ответ на вызов с помощью authobject.

mechanism указывает, какой механизм аутентификации использовать в качестве аргумента команды AUTH; допустимые значения перечислены в элементе auth элемента esmtp_features.

authobject должен быть вызываемым объектом, принимающим необязательный единственный аргумент:

data = authobject(challenge=None)

Если необязательный ключевой аргумент initial_response_ok имеет значение true, сначала будет вызван authobject() без аргументов. Он может вернуть ASCII «начальный ответ» RFC 4954 str, который будет закодирован и отправлен с командой AUTH следующим образом. Если authobject() не поддерживает начальный ответ (например, потому что требуется вызов), он должен вернуть None при вызове с challenge=None. Если initial_response_ok имеет значение false, то authobject() не будет вызван вначале с None.

Если проверка начального ответа возвращает None, или если initial_response_ok имеет значение false, authobject() будет вызван для обработки ответа сервера на вызов; переданный аргумент challenge будет bytes. Он должен вернуть ASCII str data, который будет закодирован в base64 и отправлен на сервер.

Класс SMTP предоставляет аутентификацию для механизмов CRAM-MD5, PLAIN и LOGIN; они называются SMTP.auth_cram_md5, SMTP.auth_plain и SMTP.auth_login соответственно. Все они требуют, чтобы свойства user и password экземпляра SMTP были установлены в соответствующие значения.

Код пользователя обычно не должен вызывать auth напрямую, но может вместо этого вызвать метод login(), который будет поочерёдно пытаться использовать каждый из вышеперечисленных механизмов в указанном порядке. auth предоставляет возможность реализации методов аутентификации, которые не (или ещё не) поддерживаются напрямую модулем smtplib.

Новое в версии 3.5.

SMTP.starttls(keyfile=None, certfile=None, context=None)

Переводит соединение SMTP в режим TLS (Transport Layer Security). Все последующие команды SMTP будут зашифрованы. Затем вы должны снова вызвать ehlo().

Если указаны keyfile и certfile, они используются для создания ssl.SSLContext.

Необязательный параметр context — это объект ssl.SSLContext; это альтернатива использованию keyfile и certfile, и если он указан, то keyfile и certfile должны быть None.

Если до этого в этом сеансе не было команды EHLO или HELO, этот метод сначала попытается использовать ESMTP EHLO.

Устарело начиная с версии 3.6: keyfile и certfile устарели в пользу context. Пожалуйста, используйте ssl.SSLContext.load_cert_chain() вместо этого или позвольте ssl.create_default_context() выбрать доверенные сертификаты CA вашей системы.

SMTPHeloError

Сервер некорректно ответил на приветствие HELO.

SMTPNotSupportedError

Сервер не поддерживает расширение STARTTLS.

RuntimeError

Поддержка SSL/TLS недоступна для вашего интерпретатора Python.

Изменено в версии 3.3: был добавлен параметр context.

Изменено в версии 3.4: теперь метод поддерживает проверку имени хоста с помощью SSLContext.check_hostname и Server Name Indicator (см. HAS_SNI).

Изменено в версии 3.5: ошибка, возникающая из-за отсутствия поддержки STARTTLS, теперь является подклассом SMTPNotSupportedError вместо базового класса SMTPException.

SMTP.sendmail(from_addr, to_addrs, msg, mail_options=(), rcpt_options=())

Отправка письма. Требуемые аргументы — строка адреса отправителя RFC 822, список строк адресов получателей RFC 822 (простая строка будет обработана как список с 1 адресом) и строка сообщения. Вызывающий код может передать список опций ESMTP (таких как 8bitmime) для использования в командах MAIL FROM в качестве mail_options. Опции ESMTP (такие как команды DSN), которые должны использоваться со всеми командами RCPT, можно передать в качестве rcpt_options. (Если вам нужно использовать различные опции ESMTP для разных получателей, вам нужно использовать низкоуровневые методы, такие как mail(), rcpt() и data() для отправки сообщения.)

Примечание

Параметры from_addr и to_addrs используются для построения оболочки сообщения, используемой транспортными агентами. sendmail никак не изменяет заголовки сообщения.

msg может быть строкой, содержащей символы в диапазоне ASCII, или байтовой строкой. Строка кодируется в байты с помощью кодека ascii, и одиночные символы \r и \n преобразуются в символы \r\n. Байтовая строка не изменяется.

Если до этого в этом сеансе не было команды EHLO или HELO , этот метод сначала попытается использовать ESMTP EHLO. Если сервер поддерживает ESMTP, размер сообщения и все указанные опции будут переданы ему (если опция присутствует в наборе функций, объявленных сервером). Если EHLO не удастся, будет использоваться HELO, и опции ESMTP будут подавлены.

Этот метод вернёт нормальное значение, если письмо будет принято хотя бы для одного получателя. В противном случае будет возбуждено исключение. То есть, если этот метод не возбуждает исключение, то кому-то должно прийти ваше письмо. Если этот метод не возбуждает исключение, он возвращает словарь с одним элементом для каждого отказанного получателя. Каждый элемент содержит кортеж из кода ошибки SMTP и сопровождающего сообщения об ошибке, отправленного сервером.

Если SMTPUTF8 включено в mail_options и сервер его поддерживает, from_addr и to_addrs могут содержать символы, не являющиеся ASCII.

Этот метод может вызывать следующие исключения:

SMTPRecipientsRefused

Все получатели были отклонены. Письмо никому не доставлено. Атрибут recipients объекта исключения — это словарь с информацией об отклоненных получателях (похожий на тот, который возвращается, когда хотя бы один получатель был принят).

SMTPHeloError

Сервер некорректно ответил на приветствие HELO.

SMTPSenderRefused

Сервер не принял адрес from_addr.

SMTPDataError

Сервер ответил с неожиданным кодом ошибки (кроме отказа получателя).

SMTPNotSupportedError

SMTPUTF8 был указан в mail_options, но не поддерживается сервером.

Если не указано иное, соединение будет открыто даже после возбуждения исключения.

Изменено в версии 3.2: msg может быть байтовой строкой.

Изменено в версии 3.5: добавлена поддержка SMTPUTF8, и SMTPNotSupportedError может быть возбуждено, если SMTPUTF8 указан, но не поддерживается сервером.

SMTP.send_message(msg, from_addr=None, to_addrs=None, mail_options=(), rcpt_options=())

Это вспомогательный метод для вызова sendmail() с сообщением, представленным объектом email.message.Message. Аргументы имеют то же значение, что и для sendmail(), за исключением того, что msg — это объект Message.

Если from_addr None или to_addrs None, send_message заполняет эти аргументы адресами, извлечёнными из заголовков msg, как указано в RFC 5322: from_addr устанавливается в поле Sender, если оно присутствует, а в противном случае — в поле From. to_addrs объединяет значения (если есть) полей To, Cc и Bcc из msg. Если в сообщении появляется ровно один набор заголовков Resent-*, обычные заголовки игнорируются, и вместо них используются заголовки Resent-*. Если сообщение содержит более одного набора заголовков Resent-*, генерируется исключение ValueError, так как нет однозначного способа определить наиболее актуальный набор заголовков Resent-.

send_message сериализует msg с помощью BytesGenerator с \r\n в качестве linesep и вызывает sendmail() для передачи полученного сообщения. Независимо от значений from_addr и to_addrs, send_message не передает заголовки Bcc или Resent-Bcc, которые могут появиться в msg. Если какие-либо адреса в from_addr и to_addrs содержат символы, не входящие в ASCII, а сервер не поддерживает SMTPUTF8 поддержку, возникает ошибка SMTPNotSupported. В противном случае Message сериализуется с клоном его policy с атрибутом utf8, установленным в значение True, и SMTPUTF8 и BODY=8BITMIME добавляются в mail_options.

Новое в версии 3.2.

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

SMTP.quit()

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

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

21.17.2. Пример SMTP

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

import smtplib

def prompt(prompt):
    return input(prompt).strip()

fromaddr = prompt("From: ")
toaddrs  = prompt("To: ").split()
print("Enter message, end with ^D (Unix) or ^Z (Windows):")

# Add the From: and To: headers at the start!
msg = ("From: %s\r\nTo: %s\r\n\r\n"
       % (fromaddr, ", ".join(toaddrs)))
while True:
    try:
        line = input()
    except EOFError:
        break
    if not line:
        break
    msg = msg + line

print("Message length is", len(msg))

server = smtplib.SMTP('localhost')
server.set_debuglevel(1)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()

Примечание

В целом, вы захотите использовать возможности пакета email для построения электронного сообщения, которое затем можно отправить с помощью send_message(); см. email: Примеры.

© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.6/library/smtplib.html

Spec-Zone.ru

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