Smtplib.SMTP.sendmail: примеры (PYTHON)

Использование функции sendmail для отправки почты через Python
Раздел: Email, Отправка почты
smtplib.SMTP.sendmail(from_addr, to_addrs, msg, mail_options, rcpt_options): dict

Основные сведения о функции smtplib.SMTP.sendmail

Метод sendmail() принадлежит объекту класса SMTP в модуле smtplib. Он используется для отправки электронной почты через SMTP-сервер. Эта функция применяется в сценариях автоматической отправки уведомлений, рассылок и других задачах, связанных с почтовой коммуникацией.

Сигнатура метода: sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[]).

Аргументы:

  • from_addr (строка): Адрес отправителя. Это может быть просто адрес (например, 'user@example.com') или строка с именем и адресом ('Имя <user@example.com>').
  • to_addrs (строка или список строк): Адрес или список адресов получателей.
  • msg (строка или байты): Содержимое письма, включая заголовки и тело. Заголовки должны быть отделены от тела пустой строкой. Строка может быть в байтовом виде или unicode (для unicode будет применено кодирование в ascii).
  • mail_options (список, необязательный): Список параметров для команды MAIL (например, ['BODY=8BITMIME', 'SMTPUTF8']).
  • rcpt_options (список, необязательный): Список параметров для команды RCPT.

Возвращаемое значение: Функция возвращает словарь, где ключами являются адреса получателей, которые не смогли получить письмо, а значениями - кортежи с кодом ошибки и сообщением. Пустой словарь означает успешную отправку всем получателям.

Простые примеры использования sendmail

Пример с одним получателем и простым текстом:

import smtplib
from email.mime.text import MIMEText

msg = MIMEText('Текст письма.')
msg['Subject'] = 'Тема письма'
msg['From'] = 'отправитель@example.com'
msg['To'] = 'получатель@example.com'

with smtplib.SMTP('smtp.example.com', 587) as server:
    server.starttls()
    server.login('логин', 'пароль')
    result = server.sendmail('отправитель@example.com', 'получатель@example.com', msg.as_string())
    print('Результат:', result)
Результат: {}

Пример с несколькими получателями и обработкой ошибок:

import smtplib

from_addr = 'отправитель@example.com'
to_addrs = ['получатель1@example.com', 'получатель2@example.com', 'несуществующий@example.com']
msg = """From: отправитель@example.com
To: получатель1@example.com, получатель2@example.com
Subject: Тест

Тело письма."""

with smtplib.SMTP('smtp.example.com', 25) as server:
    try:
        failed = server.sendmail(from_addr, to_addrs, msg)
        if failed:
            print('Не доставлено:', failed)
        else:
            print('Все письма отправлены.')
    except smtplib.SMTPException as e:
        print('Ошибка SMTP:', e)
Не доставлено: {'несуществующий@example.com': (550, b'User unknown')}

Альтернативные подходы в Python

Для отправки почты в Python также можно использовать:

  • smtplib.SMTP.send_message(): Более современный метод, принимающий объект email.message.EmailMessage. Он автоматически обрабатывает адреса отправителя и получателей из заголовков письма.
  • smtplib.SMTPSSL: Класс для безопасного соединения с SMTP-сервером через SSL/TLS с самого начала (вместо использования starttls()).
  • Внешние библиотеки: Например, yagmail для Gmail или flask-mail для интеграции с Flask. Они предоставляют более высокоуровневый API.

Метод send_message часто предпочтительнее, так как он интегрирован с современным email-модулем и менее подвержен ошибкам в формировании письма.

Отправка почты в других языках программирования

PHP: Используется функция mail() или библиотека PHPMailer.

// Простой пример с mail()
mail('recipient@example.com', 'Subject', 'Message', 'From: sender@example.com');

JavaScript (Node.js): Популярен модуль nodemailer.

const nodemailer = require('nodemailer');
let transporter = nodemailer.createTransport({
    host: 'smtp.example.com',
    port: 587,
    auth: { user: 'user', pass: 'pass' }
});
transporter.sendMail({
    from: 'sender@example.com',
    to: 'recipient@example.com',
    subject: 'Subject',
    text: 'Message'
});

Java: Используется JavaMail API (javax.mail).

Properties props = new Properties();
props.put("mail.smtp.host", "smtp.example.com");
Session session = Session.getInstance(props);
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("sender@example.com"));
msg.addRecipient(Message.RecipientType.TO, new InternetAddress("recipient@example.com"));
msg.setSubject("Subject");
msg.setText("Message");
Transport.send(msg);

Основное отличие Python - в использовании контекстного менеджера (with) для автоматического управления соединением, в то время как в других языках часто требуется явное закрытие ресурсов.

Распространенные ошибки

Неправильное формирование сообщения: Отсутствие заголовков или неправильный формат может привести к отклонению письма.

msg = 'Просто текст без заголовков.'
server.sendmail('from@example.com', 'to@example.com', msg)
Письмо может быть отправлено, но часто попадает в спам или отвергается сервером.

Некорректное кодирование: Использование не-ASCII символов без указания кодировки.

msg = "Subject: Тест\n\nТекст с кириллицей."
# Если строка является unicode и содержит не-ASCII, может возникнуть ошибка кодирования.

Ошибки аутентификации: Попытка отправки без предварительного вызова login() или с неверными данными.

server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
# Пропущен server.login()
server.sendmail(...)  # Вызовет smtplib.SMTPException

Игнорирование возвращаемого словаря: Необработанные отклоненные адреса.

failed = server.sendmail(...)
# Если failed не пустой, но программа не реагирует на это, отправитель может не узнать о проблемах с доставкой.

Изменения в последних версиях Python

В Python 3.5 был добавлен аргумент mail_options с поддержкой расширения SMTPUTF8 для интернационализированных адресов email.

В Python 3.7 добавлена поддержка тайм-аутов на уровне сокета через аргументы timeout в конструкторе SMTP.

Начиная с Python 3.9, улучшена обработка SSL-контекстов в SMTP_SSL и starttls().

Функция sendmail сама по себе остается стабильной, изменения в основном касаются всего модуля smtplib.

Расширенные примеры

Пример с использованием 8BITMIME и SMTPUTF8 для отправки письма с кириллицей в теме и теле:

Пример python
import smtplib
from email.mime.text import MIMEText
from email.header import Header

msg = MIMEText('Текст письма на русском.', 'plain', 'utf-8')
msg['Subject'] = Header('Тема на русском', 'utf-8')
msg['From'] = 'отправитель@example.com'
msg['To'] = 'получатель@example.com'

with smtplib.SMTP('smtp.example.com', 587) as server:
    server.starttls()
    server.login('логин', 'пароль')
    # Использование опций для поддержки UTF-8
    server.sendmail(msg['From'], msg['To'], msg.as_string(),
                    mail_options=['BODY=8BITMIME', 'SMTPUTF8'])
Успешная отправка письма с кириллическими символами.

Пример отправки письма с вложением (используя sendmail в связке с email-модулем):

Пример python
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication

msg = MIMEMultipart()
msg['Subject'] = 'Документ'
msg['From'] = 'sender@example.com'
msg['To'] = 'recipient@example.com'

msg.attach(MIMEText('См. вложение.'))
with open('document.pdf', 'rb') as f:
    part = MIMEApplication(f.read(), Name='document.pdf')
part['Content-Disposition'] = 'attachment; filename="document.pdf"'
msg.attach(part)

with smtplib.SMTP('localhost', 25) as server:
    server.send_message(msg)  # Альтернатива sendmail

Пример с кастомизацией параметров RCPT:

Пример python
import smtplib

from_addr = 'sender@example.com'
to_addrs = ['recipient@example.com']
msg = """From: sender@example.com
To: recipient@example.com
Subject: Test

Test message."""

with smtplib.SMTP('smtp.example.com', 25) as server:
    # Некоторые серверы поддерживают параметры для RCPT TO, например, для проверки аккаунта
    failed = server.sendmail(from_addr, to_addrs, msg,
                             rcpt_options=['NOTIFY=SUCCESS,DELAY'])
    print(failed)

питон smtplib.SMTP.sendmail function comments

En
Smtplib.SMTP.sendmail Send email via SMTP