Вопреки названию, мы используем далеко не только Python. Но большой проект на любом языке требует к себе вдумчивый подход, особенно в плане учета особенностей языка и технологий.  Пройдя все стадии от отрицания до принятия в программировании на Python, могу сказать, что он нам подошел. Но будет неправдой сказать, что нас обошли стороной трудности и проблемы, связанные с особенностями разработки.  Про жизненные неурядицы и то, как мы их решали и продолжаем решать — об этом и немного об устройстве DWH в inDrive я и расскажу. А еще на примере кейсов разберу, что в проекте может пойти не так. Наш DWH облачный и расположен в Google Cloud. Значительную часть технологий этой платформы мы используем для решения задач: BigQuery. Pub/Sub + Dataflow. Dataproc. Google Functions. Composer. Помимо этого, есть опенсорсные технологии, которые активно используем — Livy и Presto. Языки нашей разработки можно представить в виде небольшой таблицы:  Scala SQL Python General-purpose язык. Быстрый. Имеет небольшую распространенность. Поддерживается для многих систем обработки/хранения данных. Скорость зависит от системы. Очень распространен (основные конструкции). General-purpose язык. Не очень быстрый. Очень распространен. Подружить такое количество технологий с доставкой данных из API и бэкенда требует много усилий. Это выросло в целый проект, позволяющий автоматизировать выгрузки и сбор витрин данных. В качестве основного языка мы используем Python, в узких местах Scala. Проект, предоставляющий простой интерфейс для работы со сложными инструментами, мы назвали de-core. В начале проект писали два человека. Со временем команда подросла и встал вопрос, как ориентироваться в коде.  Проблемы: Непонятно, что и где лежит. common.py на 10 тысяч строк. IDE не помогает найти нужные файлы. Документации нет. Эти проблемы могут привести к тому, что в какой-то момент возникнет дублирующий функционал, а новички начнут долго разбираться в проекте. А документацию никто писать не любит, плюс понятная документация — это трудно. А если существует часть проекта и его требуется ретроспективно задокументировать? Это уже задачка со звездочкой. В нашем кейсе проблемы подсветили новые коллеги — оказалось, что порог входа в проект очень высокий. Что можно сделать: Закоммититься на определенную структуру проекта. Явно разделить функционал для общего использования и частного процесса. Описать базовые классы того, что ожидается от фичи. Начать вести документацию.  Придумать нейминг. Первым делом мы выделили «ядро» проекта. Это центральная часть, которая часто переиспользуется и должна быть написана наиболее качественно. Провели глубокий рефакторинг этой части, определили базовые структуры для того, чтобы унифицировать разрабатываемые модули. Ввели понятную структуру в проекте для поддержки ETL-процессов, завязались на нашу архитектуру DWH (raw-, ods-, dds-, cdm-слои), и поиск нужных файлов свелся к логическим единицам — источник и таблица. Больше человек в команде — больше работы с чужим кодом. Python часто используют для маленьких скриптов, где требования к коду ниже, так как сам скрипт легко влезает на экран. В большом проекте нужно писать код так, чтобы другой человек смог легко в нем разобраться. Проблемы: IDE не подсказывает методы класса. Передал аргументы не того типа. Нейминг функций/методов/переменных не всегда помогает. Типизация помогает понять, что ожидает функция или метод, IDE может подсказать атрибуты и методы. А линтеры автоматически проверят эти ожидания. Мы также определили базовые классы как стандарт написания ETL. Поддержка интерфейса классов позволяет быстрее ориентироваться в чужом коде. Что можно сделать: Прописать типы. Определить интерфейс ответа функции/метода. Подготовить базовые классы. Настроить линтеры и хуки. В большом проекте возникает соблазн притянуть импорты из другого модуля и быстро решить проблему. Но подход может привести к тому, что возникнут сложные зависимости, которые будет сложно  дебажить. Проблемы: Всегда нужно деплоить проект целиком. Трудно вынести часть проекта в отдельную библиотеку.  Пакеты зависят друг от друга циклически для разных файлов. Здесь помогает регулярный рефакторинг, когда нужно пересматривать актуальность текущего кода после изменения требований. Как вариант разрыва зависимостей — определение объектов для передачи в функцию/метод/класс. Что можно сделать: Переразбить проект на пакеты. Провести код-ревью и груминг. Заложить время на рефакторинг. Одна из частых проблем — запуск в разных средах и локальное тестирование. Существует риск, что среда будет отличаться от продакшена при тесте. А это может привести к непредсказуемым ошибкам. Проблемы: Разное поведение локально и на проде. Неправильные подсказки от IDE. Здесь спасает Docker. Все тесты и проверки работы приложения нужно тестировать в виртуальной сред, соответствующей проду. Что можно сделать: Сделать отдельное виртуальное окружение для проекта; Запускать тесты только в Docker. Изначально простой и маленький проект вырос в сложный, с которым работает много разработчиков. Стандарты работы с этой кодовой базой постоянно эволюционировали. А про те кейсы, которые задели струны в моей душе, я написал выше. Главное, что стоит держать в голове, начиная большой проект на Python: Промышленная разработка на Python — это сложно. IDE ваш друг, используйте возможности по максимуму. Есть много рекомендаций по тому, как писать код — лучше их изучить. Не поскупитесь на автоматизацию, линтеры, хуки, документацию. В итоге задача разработчика — знать о разных практиках, уметь оценить полезность для вашего конкретного проекта и иметь волю по их внедрению при необходимости. Даже если вы пишете на Python.