Отправка email из Python через smtplib
Финальный шаг многих пайплайнов — разослать результат по почте. Встроенные модули smtplib и email отправляют письма программно, а пароль при этом берётся из переменной окружения.
Суть:email.messageсобирает письмо (от, кому, тема, тело),smtplibподключается к SMTP-серверу и отправляет. Пароль — только из окружения, никогда в коде.
Отчёт посчитан, документ собран — теперь его надо доставить. Python шлёт почту встроенными средствами: модуль email конструирует само письмо, а smtplib отправляет его через SMTP — протокол отправки почты. Установка SMTP-сервера, порт, шифрование TLS — всё это пара строк настройки.
Сборку самого письма (заголовки, тело) можно полностью отработать в браузере: модуль email.message входит в stdlib и доступен в Pyodide. Соберём письмо и посмотрим на его «сырой» вид.
Попробуй сам ▶
from email.message import EmailMessage
msg = EmailMessage()
msg['From'] = '[email protected]'
msg['To'] = '[email protected]'
msg['Subject'] = 'Отчёт о продажах за 22.06.2026'
msg.set_content('''Здравствуйте!
Во вложении дневной отчёт.
Итоговая выручка: 184 200 руб.
-- Автоматическая рассылка''')
# Так письмо выглядит на проводе (заголовки + тело)
print(msg.as_string()[:300])
print('...')
print('Тема:', msg['Subject'])Объект EmailMessage сам формирует корректные заголовки и кодировку — вам не нужно вручную собирать MIME. Метод set_content задаёт текстовое тело. Отправка через SMTP трогает сеть и пароль, поэтому показана как нерабочая в браузере врезка.
import os, smtplib
from email.message import EmailMessage
msg = EmailMessage()
msg['From'] = '[email protected]'
msg['To'] = '[email protected]'
msg['Subject'] = 'Отчёт о продажах'
msg.set_content('Во вложении дневной отчёт.')
# Пароль — из переменной окружения, НЕ в коде!
password = os.environ['EMAIL_PASSWORD']
with smtplib.SMTP_SSL('smtp.company.ru', 465) as server:
server.login('[email protected]', password)
server.send_message(msg)
print('Письмо отправлено')ПУТЬ ПИСЬМА
данные отчёта
| EmailMessage (From/To/Subject/тело)
v
готовое письмо
| smtplib + login (пароль из окружения)
v
SMTP-сервер --TLS--> почта получателя
os.environ['EMAIL_PASSWORD'] <- секрет вне кодаВажная практическая деталь — почтовые провайдеры обычно не дают слать письма под вашим обычным паролем. Вместо него заводят пароль приложения (app password) — отдельный ключ, выданный специально для скриптов, который можно в любой момент отозвать, не меняя основной пароль аккаунта. Это и безопаснее, и обязательно при включённой двухфакторной аутентификации. Получают такой пароль в настройках безопасности почты и кладут — как и любой секрет — в переменную окружения. Если письма «не уходят» с ошибкой авторизации, причина почти всегда в этом: сервис ждёт пароль приложения, а не обычный.
Как работает под капотом
SMTP — это текстовый протокол: ваш скрипт ведёт со сервером диалог из команд (HELO, AUTH, MAIL FROM, DATA). smtplib прячет эти детали за методами. Обёртка SMTP_SSL сразу устанавливает шифрованное соединение, поэтому логин и письмо не идут по сети открытым текстом.
Чтение пароля через os.environ['EMAIL_PASSWORD'] — не стилистическая прихоть, а требование безопасности. Пароль в коде попадёт в git и станет виден всем. Переменная окружения задаётся вне кода (в настройках сервера или файле .env), поэтому секрет не утекает в репозиторий. Это та же логика, что и в уроке про SECRET_KEY.
Частые ошибки
- Хардкодить пароль в скрипте. Он утечёт в git. Только переменные окружения или секрет-хранилище.
- Путать порты и режимы. 465 — SSL сразу, 587 — STARTTLS после подключения. Несовпадение — и соединение висит.
- Слать без обработки ошибок. Сеть ненадёжна; оборачивайте отправку в try и логируйте сбои.
Best practices
- Секреты — всегда из окружения, никогда в исходниках.
- Используйте шифрованное соединение (SSL/TLS) для логина.
- Для массовой рассылки делайте паузы и обрабатывайте отказы, чтобы не попасть в спам-лимиты.
Итоги. smtplib и email отправляют почту из Python: соберите письмо, подключитесь по SSL, возьмите пароль из окружения. Безопасность секрета — главное правило. Дальше прикрепим к письму файлы-вложения.