Зачем капстон
Финальный модуль курса — это end-to-end mini-pipeline, который ты построишь руками. Он закрывает всё, что ты прошёл: extraction из источника, хранилище, dimensional modeling в dbt, тесты, простой dashboard, оркестрация. По размеру — это pet-project на джуна: что-то, чем можно гордиться, что положить в GitHub, на чём отрабатывать собеседование.
Цель капстона — не построить production-systems-grade продукт за один заход. Цель — пройти полный цикл DE-работы: от выбора источника до доставки данных в дашборд. Тогда ты увидишь, как всё, что выучил по модулям, соединяется в живую систему.
Размер скоупа специально подобран так, чтобы junior-developer смог сделать его за 1-2 дня full-time или 1-2 недели по вечерам. Если получаешь больше — урезай объём (одна дата вместо месяца, одна таблица вместо пяти). Если меньше — добавляй (orchestration, более глубокая модель, дашборд).
Задача
Сценарий. Воображаемая аналитическая компания хочет каждый день видеть метрики по поездкам такси в NYC (или другие данные на выбор). Они хотят:
- Свежие данные за вчерашний день к 9 утра.
- Дашборд с метриками: total trips, total revenue, top zones, avg fare.
- Возможность смотреть исторические данные (последние 3 года).
- Простой алерт, если данные за день не пришли вовремя.
Твоя задача: построить pipeline, который это закрывает. End-to-end.
Архитектура
Public API -> ingester -> object store / DWH -> dbt -> dashboard
Стек:
- Python 3.12 — ingestion и orchestration glue.
- DuckDB или Postgres — DWH (DuckDB проще для local-dev).
- dbt 1.7+ — трансформации.
- Airflow 2.8+ — оркестрация (обязательно; cron годится только как разминка для понимания идеи планировщика).
- Streamlit — dashboard.
- Docker Compose — packaging всего стека.
- MinIO — object-store для raw данных (обязателен: на него ждёт sensor в capstone-DAG).
Выбор источника
Рекомендую NYC TLC Trip Data:
- Большой volume (~ 1-3 GB на месяц по Yellow Taxi).
- Parquet формат, готовый к загрузке.
- Знакомая всем структура: пикап / дроп-офф, fare, distance.
- Несколько лет истории, partition by month.
- Хорошо моделируется как fact (trips) + dimensions (date / zone / vendor).
URL: https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_YYYY-MM.parquet.
Альтернативы (если NYC Taxi надоел):
- GitHub Events Archive — https://www.gharchive.org. Hourly JSON gzip.
- OpenWeather API — текущая и историческая погода, free-tier.
- CoinGecko / Binance — crypto prices, free, rate-limited.
- Spotify Top Charts — top-200 daily by country (требует API key).
Для оставшейся части модуля примеры буду показывать на NYC Taxi.
Скоуп для джуна
Чтобы не зашиться в сложности, ограничь себя:
| Параметр | Скоуп для джуна | Расширения дальше |
|---|---|---|
| Объём данных | 3-6 месяцев | 3 года |
| Таблицы | 1 fact + 2 dim | 2 fact + 5 dim |
| dbt models | 5-10 моделей | 20-30 моделей |
| Tests | 5-10 тестов | 30+ тестов |
| Dashboard | 1 страница | Multi-page |
| Orchestration | Daily Airflow DAG (обязательно) | Hourly + monitoring |
| Tests in CI | optional | GitHub Actions |
Делать сложно сразу — антипаттерн. Сначала сделай весь pipeline на минимуме (1 модель, 1 тест, 1 chart). Потом расширяй. Это и есть iterative delivery — production-mindset.
Самая частая ошибка в pet-projects — overscope. Кандидат хочет сделать “идеальный pipeline” со streaming, lakehouse, и Kafka — и не доходит до конца. Лучше doable MVP с README и demo, чем недоделанный monster.
Технический план
День 1 (или неделя 1):
- Скачать 1 месяц данных вручную, открыть в pandas, посмотреть структуру.
- Написать Python-ingester, который скачивает один месяц.
- Загрузить в DuckDB как одну сырую таблицу.
- Написать пару SQL-запросов в DuckDB для проверки.
День 2 (или неделя 2):
- dbt init проект, настроить profiles.yml на DuckDB.
- Написать staging-модель (raw -> typed).
- Написать intermediate (clean: убрать negative fare, future dates).
- Написать 2-3 mart-модели (daily_metrics, zone_metrics).
- Добавить tests (unique, not_null, accepted_values).
- Написать Streamlit-дашборд на 3-4 chart-а.
День 3 (обязательно — оркестрация):
- Написать Airflow DAG с daily schedule, настроенными ретраями и multi-task dependency graph.
- Добавить sensor, который ждёт появления объекта в object store (MinIO), прежде чем загружать.
- Прогнать backfill за несколько дат и показать восстановление после умышленного падения задачи.
- Завернуть в Docker Compose.
- Дописать README.
- Сделать GIF / screen-cast демо.
Оркестрация — обязательная часть капстона, а не “если останется время”. Capstone-DAG ДОЛЖЕН продемонстрировать пять вещей: multi-task dependency graph (а не один скрипт), настроенные ретраи на задачах, sensor, который ждёт появления данных в object store (MinIO), хотя бы один backfill-прогон за диапазон дат, и умышленное падение задачи с последующим восстановлением (retry + recovery). LAB-03 (nyc_taxi_pipeline) — это пошаговая сборка ровно этого DAG: extract -> land_to_minio -> wait_for_raw (S3KeySensor) -> flaky_quality_gate -> load_to_duckdb с веером на build_daily_metrics и assert_quality. Лаба содержит готовый poison-date сценарий и backfill-команду, так что сдать оркестрацию можно прямо по её шагам.
Ожидаемый результат
После капстона у тебя:
- GitHub-репозиторий с README, архитектурой, кодом, Docker Compose.
- Понимание полного DE-цикла на практике, а не только в теории.
- Темa для собеседования — 5-минутный рассказ о том, что построил и какие были challenges.
- Доказательство навыков — можно прислать ссылку на резюме / в LinkedIn.
Что НЕ должно быть в капстоне (для junior-уровня)
- Spark / Flink / Kafka — это middle+. Запутаешься и не доделаешь.
- Real-time streaming — над junior. Batch достаточно.
- Сложные ML-фичи (feature store, model serving) — это MLE, не DE-обзор.
- Multi-region replication, disaster recovery — это middle+ infra.
- Custom orchestrator — используй готовый Airflow / Dagster.
Если хочется этих штук — добавь во второй pet-project, не в капстон.
Возможные альтернативные сценарии
Если NYC Taxi скучен, можно адаптировать pattern под другие домены, сохраняя архитектуру:
Сценарий А: GitHub Events
- Source: gharchive.org (hourly JSON gzip).
- Ingester: каждый час скачивает один файл.
- Transforms: aggregations по языкам, top repos.
- Dashboard: тренды по неделям.
- Challenge: nested JSON, schema evolution.
Сценарий B: Crypto Price Tracker
- Source: Binance / CoinGecko API, 5-минутный интервал.
- Ingester: каждые 5 мин тащит топ-10 coins.
- Transforms: minute / hour / day aggregations.
- Dashboard: candlesticks, volatility.
- Challenge: frequent updates, idempotent merge.
Сценарий C: Weather Analysis
- Source: OpenWeather API + историческая выгрузка.
- Ingester: daily for N cities.
- Transforms: deviations from norms, anomalies.
- Dashboard: maps, anomaly alerts.
- Challenge: geospatial joins, time-series.
Все три — реальные сценарии Junior DE pet-project, доступные за 1-2 недели.
Не пытайся выбрать “максимально модный стек”. Junior pet-project не должен быть демонстрацией всех технологий. Он должен показать, что ты умеешь думать end-to-end и доводить до конца. Простой стек, доведённый до качественного состояния, сильнее любого buzzword-проекта.
Попробуй сам
- Открой URL NYC Taxi (https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2024-01.parquet). Скачай файл руками, открой в Python через pandas. Что внутри? Какие колонки? Какие проблемы данных (NULL, ranges)?
- Открой следующий урок (02-design). Перед чтением — попробуй сам распланировать архитектуру pipeline на бумаге. Какие компоненты? Какие данные между ними? Где должны быть тесты?
- Поставь в календаре 1-2 часа в день на 2 недели для работы над капстоном. Это даст 14-28 часов — достаточно для MVP.