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. Если заданы дополнительные параметры хоста и порта, метод SMTP connect() вызывается вместе с этими параметрами во время инициализации. Если указано, local_hostname используемый в качестве полного доменного имени хоста локальная в команде HELO/EHLO. В противном случае имя хоста локальная будет найдено с помощью socket.getfqdn(). Если вызов connect() возвращает что-либо, кроме успешного код, возникает SMTPConnectError. Дополнительный параметр timeout определяет перерыв в секундах для блокирования операций как попытка связи (если не определенный, глобальная настройка перерыва по умолчанию будет используемый). Если время ожидания истекает, socket.timeout увеличивается. Необязательный параметр source_address позволяет биндинг к определенному адресу источника в машине с несколькими сетевыми интерфейсами и/или к определенному порту TCP источника. Перед подключением требуется 2-кортеж (хост, порт) для привязки сокет в качестве адреса источника. Если опущено (или если хост или порт '' и/или 0 соответственно), поведение оС по умолчанию будет используемый.

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

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

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

Все команды вызывают событие аудита smtplib.SMTP.send с аргументами self и data, где data - это байты, отправляемые удаленному узлу.

Изменено в версии 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, [тайм-аут, ]контекст = None, source_address=None)

SMTP_SSL сущность ведет себя точно так же, как и сущности SMTP. SMTP_SSL следует используемый для ситуаций, когда SSL требуется с начала соединения и использование starttls() не подходит. Если host не указан, локальная узел будет используемый. Если port равно нулю, используемый стандартный порт SMTP-over-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() выбрать доверенные сертификаты цС системы.

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

Протокол LMTP, который очень похож на ESMTP, в значительной степени основан на стандартном SMTP-клиенте. Обычно для LMTP используется Unix сокеты, поэтому наш метод connect() должен поддерживать как обычный сервер host: port. Необязательные аргументы 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 новыми командами, поддержка динамического обнаружения команд, предоставляемых сервером, и определяются несколько дополнительных команд.

Объекты SMTP

В SMTP сущность используются следующие методы:

SMTP.set_debuglevel(level)

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

Изменено в версии 3.5: Added debuglevel 2.

SMTP.docmd(cmd, args='')

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

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

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

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

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

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

Raises an auditing event smtplib.connect with arguments 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. Сначала выполняется попытка EHLO ESMTP.

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, этот метод сначала пытается выполнить EHLO ESMTP. Этот метод обычно возвращает, если аутентификация прошла успешно, или может вызвать следующие исключения:

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 для указанного mechanism аутентификации и обработать ответ на запрос с помощью команды authobject.

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

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

data = authobject(challenge=None)

Если параметр ключевой argument 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 data, который будет 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 (безопасность транспортного уровня). Все следующие команды SMTP будут зашифрованы. Тогда позвони ehlo() еще раз.

При наличии keyfile и certfile создается используемый ssl.SSLContext.

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

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

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

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 from-address строка, список RFC 822 to-address строки (голый строка будет рассматриваться как список с 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, этот метод сначала пытается выполнить EHLO ESMTP. Если сервер выполняет 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. Как правило, их не требуется вызывать напрямую, поэтому они не документируются здесь. Для получения более подробной информации см. код модуля.

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