smtplib — SMTP protocol client

Вихідний код: Lib/smtplib.py


Модуль smtplib визначає об’єкт сеансу клієнта SMTP, який можна використовувати для надсилання пошти на будь-яку машину в Інтернеті з демоном прослуховування SMTP або ESMTP. Щоб дізнатися більше про роботу SMTP і ESMTP, зверніться до RFC 821 (простий протокол передачі пошти) і RFC 1869 (розширення служби SMTP).

Availability: not Emscripten, not WASI.

This module does not work or is not available on WebAssembly platforms wasm32-emscripten and wasm32-wasi. See WebAssembly platforms for more information.

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

An SMTP instance encapsulates an SMTP connection. It has methods that support a full repertoire of SMTP and ESMTP operations. If the optional host and port parameters are given, the SMTP connect() method is called with those parameters during initialization. If specified, local_hostname is used as the FQDN of the local host in the HELO/EHLO command. Otherwise, the local hostname is found using socket.getfqdn(). If the connect() call returns anything other than a success code, an SMTPConnectError is raised. The optional timeout parameter specifies a timeout in seconds for blocking operations like the connection attempt (if not specified, the global default timeout setting will be used). If the timeout expires, TimeoutError is raised. The optional source_address parameter allows binding to some specific source address in a machine with multiple network interfaces, and/or to some specific source TCP port. It takes a 2-tuple (host, port), for the socket to bind to as its source address before connecting. If omitted (or if host or port are '' and/or 0 respectively) the OS default behavior will be used.

Для звичайного використання вам знадобляться лише методи ініціалізації/підключення, 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 argument was added.

Нове в версії 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 через SSL (465). Необов’язкові аргументи local_hostname, timeout і source_address мають те саме значення, що й у класі SMTP. context, також необов’язковий, може містити SSLContext і дозволяє налаштовувати різні аспекти безпечного з’єднання. Будь ласка, прочитайте Міркування безпеки, щоб дізнатися про найкращі практики.

keyfile and certfile are a legacy alternative to context, and can point to a PEM formatted private key and certificate chain file for the SSL connection.

Змінено в версії 3.3: додано контекст.

Змінено в версії 3.3: source_address argument was added.

Змінено в версії 3.4: The class now supports hostname check with ssl.SSLContext.check_hostname and Server Name Indication (see ssl.HAS_SNI).

Застаріло починаючи з версії 3.6: keyfile and certfile are deprecated in favor of context. Please use ssl.SSLContext.load_cert_chain() instead, or let ssl.create_default_context() select the system’s trusted CA certificates for you.

Змінено в версії 3.9: Якщо параметр timeout дорівнює нулю, це викличе ValueError, щоб запобігти створенню неблокуючого сокета

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

The LMTP protocol, which is very similar to ESMTP, is heavily based on the standard SMTP client. It’s common to use Unix sockets for LMTP, so our connect() method must support that as well as a regular host:port server. The optional arguments local_hostname and source_address have the same meaning as they do in the SMTP class. To specify a Unix socket, you must use an absolute path for host, starting with a „/“.

Підтримується автентифікація за допомогою звичайного механізму 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 для рівня призводить до повідомлень про налагодження для з’єднання та для всіх повідомлень, надісланих і отриманих із сервера. Значення 2 для рівня призводить до того, що ці повідомлення мають мітку часу.

Змінено в версії 3.5: Додано рівень налагодження 2.

SMTP.docmd(cmd, args='')

Надішліть на сервер команду cmd. Необов’язковий аргумент args просто об’єднується з командою, розділяючись пробілом.

Це повертає 2-кортеж, що складається з числового коду відповіді та фактичного рядка відповіді (багаторядкові відповіді об’єднуються в один довгий рядок).

У нормальній роботі не потрібно явно викликати цей метод. Він використовується для реалізації інших методів і може бути корисним для тестування приватних розширень.

Якщо з’єднання із сервером втрачено під час очікування відповіді, буде виведено SMTPServerDisconnected.

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

Підключіться до хосту на заданому порту. За замовчуванням підключення до локального хосту здійснюється через стандартний порт SMTP (25). Якщо ім’я хоста закінчується двокрапкою (':''), після якої йде число, цей суфікс буде видалено, а число інтерпретується як номер порту для використання. Цей метод автоматично викликається конструктором, якщо під час створення екземпляра вказано хост. Повертає 2-кортеж коду відповіді та повідомлення, надіслане сервером у відповіді на підключення.

Викликає подію аудиту smtplib.connect з аргументами self, host, port.

SMTP.helo(name='')

Ідентифікуйте себе на сервері SMTP за допомогою HELO. Аргумент імені хоста за замовчуванням відповідає повному доменному імені локального хосту. Повідомлення, яке повертає сервер, зберігається як атрибут helo_resp об’єкта.

У нормальній роботі не потрібно явно викликати цей метод. За потреби його неявно викликає sendmail().

SMTP.ehlo(name='')

Ідентифікуйте себе на сервері ESMTP за допомогою EHLO. Аргумент імені хоста за замовчуванням відповідає повному доменному імені локального хосту. Перевірте відповідь для опції 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 must be a callable object taking an optional single argument:

data = authobject(challenge=None)

Якщо необов’язковий аргумент ключового слова 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, який він передає, буде байтом. Він має повернути ASCII str data, які будуть закодовані base64 і надіслані на сервер.

Клас SMTP надає authobjects для механізмів CRAM-MD5, PLAIN і LOGIN; вони називаються SMTP.auth_cram_md5, SMTP.auth_plain і SMTP.auth_login відповідно. Усі вони вимагають, щоб властивості користувач і пароль примірника 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 and certfile are deprecated in favor of context. Please use ssl.SSLContext.load_cert_chain() instead, or let ssl.create_default_context() select the system’s trusted CA certificates for you.

SMTPHeloError

Сервер не відповів належним чином на привітання HELO.

SMTPNotSupportedError

Сервер не підтримує розширення STARTTLS.

RuntimeError

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

Змінено в версії 3.3: додано контекст.

Змінено в версії 3.4: The method now supports hostname check with SSLContext.check_hostname and Server Name Indicator (see 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 з повідомлення. Якщо в повідомленні з’являється рівно один набір заголовків 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

This example prompts the user for addresses needed in the message envelope („To“ and „From“ addresses), and the message to be delivered. Note that the headers to be included with the message must be included in the message as entered; this example doesn’t do any processing of the RFC 822 headers. In particular, the „To“ and „From“ addresses must be included in the message headers explicitly.

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: Examples.