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

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


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

Availability: это не Emscripten, это был не я.

Этот модуль не работает или недоступен на платформах WebAssembly wasm32-emscripten и wasm32-wasi. Дополнительную информацию смотрите в разделе Платформы веб-сборки.

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

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

Для нормального использования вам должны потребоваться только методы initialization/connect, sendmail() и SMTP.quit(). Ниже приведен пример.

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

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

Создает auditing event smtplib.send с аргументами self, data.

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

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

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

Изменено в версии 3.9: Если для параметра timeout задано значение, равное нулю, он выдаст значение ValueError, чтобы предотвратить создание неблокирующего сокета

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-over-SSL (465). Необязательные аргументы local_hostname, timeout и source_address имеют то же значение, что и в классе SMTP. контекст, также необязательный, может содержать SSLContext и позволяет настраивать различные аспекты защищенного соединения. Пожалуйста, ознакомьтесь с Соображения безопасности для получения рекомендаций.

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

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

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

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

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

Изменено в версии 3.9: Если для параметра timeout задано значение, равное нулю, он выдаст значение ValueError, чтобы предотвратить создание неблокирующего сокета

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

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

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

Изменено в версии 3.9: Был добавлен необязательный параметр timeout.

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

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, для параметра «отправитель» устанавливается значение строки, которую отклонил 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 новыми командами, поддерживающая динамическое обнаружение команд, предоставляемых сервером, и определяется несколько дополнительных команд.

Объекты SMTP

Экземпляр SMTP имеет следующие методы:

SMTP.set_debuglevel(level)

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

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

SMTP.docmd(cmd, args='')

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

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

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

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

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

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

Создает auditing event smtplib.connect с аргументами self, host, port.

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.

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

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

данные = объект аутентификации(вызов=Нет)

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

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

Класс SMTP предоставляет authobjects для механизмов 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 должны быть None.

Если в этом сеансе не было предыдущей команды EHLO или HELO, этот метод сначала пробует ESMTP EHLO.

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

SMTPHeloError

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

SMTPNotSupportedError

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

RuntimeError

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

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

Изменено в версии 3.4: Метод теперь поддерживает проверку имени хоста с помощью SSLContext.check_hostname и Индикатора имени сервера (см. 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. Если сервер использует протокол SMTP, ему будет передан размер сообщения и все указанные параметры (если этот параметр входит в набор функций, который рекламирует сервер). Если EHLO не удается, будет выполнена попытка HELO и параметры ESMTP будут отключены.

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

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

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

SMTPRecipientsRefused

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

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 из сообщения. Если в сообщении отображается только один набор заголовков Resent-*, обычные заголовки игнорируются и вместо них используются заголовки Resent-*. Если сообщение содержит более одного набора Resent-* заголовков, генерируется ValueError, поскольку нет способа однозначно определить самый последний набор Resent- заголовков.

send_message сериализует сообщение, используя 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 . Обычно их не требуется вызывать напрямую, поэтому здесь они не описаны. Для получения более подробной информации обратитесь к коду модуля.

Пример протокола SMTP

В этом примере пользователю предлагается указать адреса, указанные в конверте сообщения (адреса «Кому» и «От кого»), а также сообщение, которое должно быть доставлено. Обратите внимание, что заголовки, которые должны быть включены в сообщение, должны быть включены в сообщение в том виде, в каком они были введены; в этом примере не выполняется обработка заголовков RFC 822. В частности, адреса «Кому» и «От» должны быть явно включены в заголовки сообщения.

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: Примеры.

Вернуться на верх