Автоматизация отчётов на Python — гайд для аналитика
Зачем автоматизировать
Каждый понедельник вы открываете базу, пишете SQL, копируете результат в Excel, форматируете, отправляете в Slack. Тратите 40 минут. Через месяц — 160 минут. Через год — 32 часа. На одном отчёте.
Скрипт на Python делает то же самое за 30 секунд без вашего участия. Один раз написать — дальше работает само.
Что стоит автоматизировать:
- Еженедельные/ежемесячные отчёты с фиксированной структурой
- Мониторинг метрик с алертами (DAU упал > 20% — сообщение в Slack)
- Выгрузки для других команд (маркетинг просит свежий отчёт по когортам)
- Обновление дашбордов, которые не в BI-инструменте
Что НЕ стоит:
- Одноразовый ad-hoc анализ
- Отчёты, которые каждый раз разные по структуре
- Задачи, где 80% времени — интерпретация, а не подготовка данных
Чтение данных
Первый шаг — получить данные. Три основных источника:
Из CSV/Excel
Самый простой вариант. Если данные выгружаются в файл:
import pandas as pd
df = pd.read_csv("data/sales_2026.csv")
# или
df = pd.read_excel("data/report_template.xlsx", sheet_name="Raw")Подробнее о read_csv — в отдельном гайде.
Из SQL-базы
Напрямую из PostgreSQL, MySQL, ClickHouse:
import pandas as pd
from sqlalchemy import create_engine
engine = create_engine("postgresql://user:pass@host:5432/db")
query = """
SELECT
DATE_TRUNC('week', created_at) AS week,
COUNT(DISTINCT user_id) AS active_users,
SUM(revenue) AS total_revenue
FROM events
WHERE created_at >= CURRENT_DATE - INTERVAL '90 days'
GROUP BY 1
ORDER BY 1
"""
df = pd.read_sql(query, engine)Из API
Google Analytics, Яндекс.Метрика, внутренние сервисы:
import requests
import pandas as pd
response = requests.get(
"https://api.example.com/metrics",
headers={"Authorization": "Bearer TOKEN"},
params={"date_from": "2026-01-01", "date_to": "2026-03-31"}
)
data = response.json()
df = pd.DataFrame(data["results"])Трансформация с pandas
После загрузки данных — подготовка: фильтрация, агрегация, расчёт метрик.
# Добавляем расчётные поля
df["arpu"] = df["total_revenue"] / df["active_users"]
df["wow_change"] = df["active_users"].pct_change() * 100
# Фильтруем последние 12 недель
df_recent = df.tail(12)
# Форматируем для отчёта
df_recent["week"] = df_recent["week"].dt.strftime("%d.%m.%Y")
df_recent["total_revenue"] = df_recent["total_revenue"].round(0).astype(int)
df_recent["arpu"] = df_recent["arpu"].round(2)
df_recent["wow_change"] = df_recent["wow_change"].round(1)Генерация Excel-отчётов
Pandas + openpyxl позволяют создавать отформатированные Excel-файлы:
from openpyxl.styles import Font, PatternFill, Alignment
output_path = "reports/weekly_report.xlsx"
with pd.ExcelWriter(output_path, engine="openpyxl") as writer:
df_recent.to_excel(writer, sheet_name="Метрики", index=False)
# Форматирование
ws = writer.sheets["Метрики"]
header_fill = PatternFill(start_color="4472C4", fill_color="4472C4",
fill_type="solid")
header_font = Font(color="FFFFFF", bold=True)
for cell in ws[1]:
cell.fill = header_fill
cell.font = header_font
cell.alignment = Alignment(horizontal="center")
# Автоширина колонок
for col in ws.columns:
max_len = max(len(str(cell.value or "")) for cell in col)
ws.column_dimensions[col[0].column_letter].width = max_len + 4Для PDF-отчётов можно использовать Jupyter Notebook + nbconvert или библиотеки вроде WeasyPrint и FPDF.
Отправка в Slack
import requests
def send_slack_report(webhook_url, file_path, message):
# Текстовое сообщение
requests.post(webhook_url, json={"text": message})
# Файл — через Slack API (не webhook)
requests.post(
"https://slack.com/api/files.upload",
headers={"Authorization": "Bearer xoxb-YOUR-TOKEN"},
data={"channels": "C0123ANALYTICS", "title": "Weekly Report"},
files={"file": open(file_path, "rb")}
)
send_slack_report(
webhook_url="https://hooks.slack.com/services/XXX/YYY/ZZZ",
file_path="reports/weekly_report.xlsx",
message="Еженедельный отчёт готов. Основные метрики за неделю 31.03–06.04."
)По email — через smtplib + email.mime:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
msg = MIMEMultipart()
msg["From"] = "analytics@company.com"
msg["To"] = "team@company.com"
msg["Subject"] = "Еженедельный отчёт"
with open("reports/weekly_report.xlsx", "rb") as f:
part = MIMEBase("application", "octet-stream")
part.set_payload(f.read())
encoders.encode_base64(part)
part.add_header("Content-Disposition", "attachment; filename=weekly_report.xlsx")
msg.attach(part)
with smtplib.SMTP("smtp.company.com", 587) as server:
server.starttls()
server.login("analytics@company.com", "password")
server.send_message(msg)Расписание: cron и Airflow
cron (простые задачи)
Для одного скрипта — cron на Linux/Mac:
# Каждый понедельник в 9:00
0 9 * * 1 /usr/bin/python3 /home/analyst/scripts/weekly_report.py >> /var/log/report.log 2>&1Airflow (сложные пайплайны)
Когда скриптов много и между ними есть зависимости — Airflow:
from airflow import DAG
from airflow.operators.python import PythonOperator
from datetime import datetime
dag = DAG("weekly_report", schedule_interval="0 9 * * 1",
start_date=datetime(2026, 1, 1))
extract = PythonOperator(task_id="extract", python_callable=load_data, dag=dag)
transform = PythonOperator(task_id="transform", python_callable=transform_data, dag=dag)
send = PythonOperator(task_id="send", python_callable=send_report, dag=dag)
extract >> transform >> sendПолный пример: скрипт от данных до Slack
"""weekly_report.py — еженедельный отчёт по метрикам."""
import pandas as pd
import requests
from sqlalchemy import create_engine
from datetime import datetime
import os
# 1. Загрузка данных
engine = create_engine(os.environ["DATABASE_URL"])
df = pd.read_sql("""
SELECT DATE_TRUNC('week', created_at)::date AS week,
COUNT(DISTINCT user_id) AS wau,
SUM(revenue) AS revenue
FROM events
WHERE created_at >= CURRENT_DATE - INTERVAL '12 weeks'
GROUP BY 1 ORDER BY 1
""", engine)
# 2. Расчёт метрик
df["arpu"] = (df["revenue"] / df["wau"]).round(2)
df["wau_change"] = df["wau"].pct_change().mul(100).round(1)
# 3. Сохранение в Excel
output = f"reports/weekly_{datetime.now():%Y%m%d}.xlsx"
df.to_excel(output, index=False, sheet_name="Metrics")
# 4. Формирование сообщения
last = df.iloc[-1]
msg = (f"Отчёт за неделю {last['week']}\n"
f"WAU: {last['wau']:,} ({last['wau_change']:+.1f}%)\n"
f"Revenue: {last['revenue']:,.0f}\n"
f"ARPU: {last['arpu']}")
# 5. Отправка в Slack
requests.post(os.environ["SLACK_WEBHOOK"], json={"text": msg})
print(f"Отчёт отправлен: {output}")Советы для production-ready скриптов
- Логирование:
loggingвместоprint. Когда скрипт упадёт в 3 часа ночи — логи спасут. - Обработка ошибок:
try/exceptс алертом. Если скрипт сломался — отправьте сообщение об ошибке, а не молчите. - Конфигурация: креды и параметры — в переменных окружения, не в коде.
- Идемпотентность: скрипт можно запустить дважды без побочных эффектов.
- Версионирование: храните скрипты в Git. Отчёт изменился — вы видите, когда и почему.
Подробнее о сохранении результатов — в гайде по to_csv и matplotlib для визуализации.
Вопросы с собеседований
— Как бы вы автоматизировали еженедельный отчёт? — Скрипт на Python: pandas для подготовки данных, openpyxl для Excel, отправка в Slack через webhook. Запуск по cron или Airflow. Логирование и алерты при ошибках.
— Какие библиотеки Python используете для работы с отчётами? — pandas — обработка данных, openpyxl — Excel, matplotlib/plotly — графики, sqlalchemy — подключение к БД, requests — API и Slack, smtplib — email. Для сложных пайплайнов — Airflow.
— Как обеспечить надёжность автоматического скрипта?
— Логирование через logging, обработка ошибок с алертами (Slack/email при падении), идемпотентность (повторный запуск не ломает данные), мониторинг (проверять, что скрипт отработал), тесты на тестовых данных.
— Когда не стоит автоматизировать отчёт? — Когда отчёт разовый, когда структура каждый раз разная, когда 90% времени — интерпретация, а не подготовка, или когда задачу проще решить через BI-инструмент с автообновлением.
FAQ
С чего начать автоматизацию отчётов?
С самого простого: возьмите отчёт, который вы делаете вручную каждую неделю. Разбейте на шаги: загрузка данных, трансформация, выгрузка, отправка. Напишите скрипт для каждого шага. Запустите вручную несколько раз, убедитесь, что работает. Потом добавьте cron.
Что лучше — cron или Airflow?
Для одного-двух скриптов — cron. Простой, есть на любом сервере, не требует настройки. Для пяти и более скриптов с зависимостями — Airflow. Он даёт UI для мониторинга, retry при ошибках, управление зависимостями между задачами и логирование из коробки.
Можно ли автоматизировать отчёты без Python?
Да. Google Sheets + Apps Script, SQL-шедулеры в BI-инструментах (Looker, Metabase), no-code платформы (Zapier, Make). Но Python даёт максимальную гибкость: любой источник данных, любой формат вывода, любая логика. Для аналитика это самый универсальный инструмент.
Потренируйте вопросы по Python и аналитике — откройте тренажёр. 1500+ вопросов для собеседования аналитика. Бесплатно.