# `smtplib` — SMTP protocol client

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

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

Availability: not WASI.

This module does not work or is not available on WebAssembly. 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.

  Added in version 3.5: Тепер підтримується розширення SMTPUTF8 (RFC 6531).

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

class smtplib.SMTP_SSL(host='', port=0, local_hostname=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` і дозволяє налаштовувати різні аспекти безпечного з’єднання. Будь ласка, прочитайте Міркування безпеки, щоб дізнатися про найкращі практики.

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

  Змінено в версії 3.3: The 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.9: Якщо параметр timeout дорівнює нулю, це викличе `ValueError`, щоб запобігти створенню неблокуючого сокета

  Змінено в версії 3.12: The deprecated keyfile and certfile parameters have been removed.

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

  Вибрана команда або параметр не підтримується сервером.

  Added in version 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`.

  Added in version 3.5.

SMTP.starttls(*, context=None)

  Переведіть SMTP-з’єднання в режим TLS (Transport Layer Security). Усі наступні команди SMTP будуть зашифровані. Потім вам слід знову викликати `ehlo()`.

  Якщо надано keyfile і certfile, вони використовуються для створення `ssl.SSLContext`.

  Додатковий параметр context є об’єктом `ssl.SSLContext`; Це альтернатива використанню файлу ключа та файлу сертифіката, і якщо вказано як keyfile, так і certfile, має бути `None`.

  Якщо в цьому сеансі не було попередньої команди `EHLO` або `HELO`, цей метод спочатку намагається ESMTP `EHLO`.

  Змінено в версії 3.12: The deprecated keyfile and certfile parameters have been removed.

  `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.

  Added in version 3.2.

  Added in version 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(title):
        return input(title).strip()

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

    # Add the From: and To: headers at the start!
    lines = [f"From: {from_addr}", f"To: {', '.join(to_addrs)}", ""]
    while True:
        try:
            line = input()
        except EOFError:
            break
        else:
            lines.append(line)

    msg = "\r\n".join(lines)
    print("Message length is", len(msg))

    server = smtplib.SMTP("localhost")
    server.set_debuglevel(1)
    server.sendmail(from_addr, to_addrs, msg)
    server.quit()

Примітка

Загалом, ви захочете використати функції пакета `email` для створення повідомлення електронної пошти, яке потім можна надіслати через `send_message()`; див. email: Examples.