Prefect 2.3.0 получил ряд реально крутых и очень востребованных возможностей, о которых и пойдет речь в этой статье. Полноценную информацию обо всех улучшениях ищите в примечаниях к релизу и обновленной документации.

Единовременное создание и применение деплоев

В данном релизе для команды build появился новый флаг --apply, а также соответствующий kwarg apply для Deployment.build_from_flow. Это позволяет единовременно создавать и применять деплои, еще больше оптимизируя пользовательский опыт:

prefect deployment build flow.py:flow_func -n dev --apply

При использовании этого нового флага командной строки (CLI) вам уже не нужно беспокоиться о файле YAML, генерируемом в качестве артефакта сборки, если только вы не хотите вручную скорректировать его либо использовать для устранения проблем.

Пропуск загрузки, если код не изменился

Если у вас сложный проект со множеством потоков и кастомных модулей, то повторная загрузка всех файлов из проекта в удаленное хранилище не всегда желательна. Благодаря новому флагу --skip-upload теперь можно пропускать загрузку, если файлы в удаленном хранилище находятся в актуальном виде.

prefect deployment build flow.py:flow_func -n dev --skip-upload

Кастомные (под)пути в блоках удаленного хранилища

Предположим, что у вас монорепозиторий, в котором хранится несколько проектов с потоками Prefect.

Пример структуры каталогов

В таком случае вы можете не захотеть повторно использовать один и тот же блок удаленного хранилища для нескольких проектов. До сих пор в подобных ситуациях требовалось несколько отдельных блоков. Тем не менее релиз 2.3.0 все упрощает, предоставляя возможность использовать пути и подпути.

Подпути

В PR #6518 мы добавили поддержку относительных подпутей, которые невероятно упрощают кастомизацию блоков удаленного хранилища. Чтобы продемонстрировать использование этого улучшения, мы начнем с настройки блока хранилища S3:

Пример конфигурации блока хранилища S3

После создания блока хранилища на него можно ссылаться из ваших деплоев. Вот как можно использовать относительные подпути с этим блоком:

Явные пути

В качестве альтернативы подпутям можно явно предоставлять относительный --path к bucket_path внутри удаленного объектного хранилища. В результате у вас будет полный контроль над тем, куда код загружается или откуда извлекается. Вот пример.

1) Сначала устанавливаем нужный bucket_path в блоке хранилища в формате bucket_name/path:

2) После создания блока хранилища устанавливаем path деплоя относительно этого bucket_path:

prefect deployment build flows/healthcheck.py:healthcheck \
-n s3 -q prod -sb s3/prod --path project1 --apply

На картинке показан вывод команды build и конечный результате в S3:

Пример вывода при создании деплоя из командной строки

Создание блоков через UI с помощью ссылок из CLI

Что касается создания блоков удаленного хранилища, то теперь делать это через UI еще проще. С PR #6492 были введены ссылки, позволяющие создавать блоки из CLI. Просто введите prefect block type ls в командной строке и выберите команду, соответствующую типу нужного блока. Будет сгенерирован URL, ведущий на страницу создания блока в UI, как показано ниже:

Клик по выделенной ссылке приведет к созданию нового блока хранилища S3:

Валидация блоков в деплоях

В PR #6535 мы внесли дополнительную валидацию инфраструктуры и блоков хранилища во время процесса сборки деплоя. Теперь Prefect будет выводить полезные сообщения об ошибках, если вы, к примеру, попытаетесь установить блок хранилища в качестве блока инфраструктуры. Эта валидация реализуется путем проверки возможностей предоставленного блока.

Новые опыт развертывания Docker 

После введения в общем релизе Prefect 2.0 нового способа развертывания потоков многие пользователи попросили интерфейс для деплоев Docker, который бы не требовал разделения между блоками хранилища и инфраструктуры

PR #6574 для релиза 2.3.0 предоставил возможность включать и код потока, и зависимости модуля в один образ Docker. Это стало возможным благодаря введению автоматического обнаружения блоков инфраструктуры docker и неудаленного хранилища.

Что это значит? Если в деплое определяется -ib docker-container/prod, и не указывается никакой блок удаленного хранилища, Prefect предположит, что код потока встроен в образ.

Вот полная команда build для потока, хранящегося в образе Docker с точкой входа flows/healthcheck.py:

prefect deployment build flows/healthcheck.py:healthcheck \
-n prod -ib docker-container/prod -q prod --apply

Обратите внимание, что в этой команде мы не устанавливаем для блока хранилища флаг -sb, потому что код потока вложен в образ Docker, указанный в блоке инфраструктуры docker-container/prod. Для запуска выполнения из этого деплоя используйте команду:

prefect deployment run healthcheck/prod

Когда вы запустите агента с тем же именем очереди заданий, какое указано в деплое, агент выберет этот поток и запустит его выполнение:

prefect agent start -q prod

Как указать расположение кода потока в образе Docker?

Предустановленным путем деплоя для потоков, хранящихся в образе Docker, является /opt/prefect/flows, но его можно полностью изменить с помощью флага --path, например:

prefect deployment build flow.py:flow_func --path /app/image_path

В качестве более подробного примера с Dockerfile и структурой образца проекта можете использовать этот шаблон репозитория.

Обобщение новых флагов CLI 

К этому моменту мы разобрали ряд изменений, произошедших относительно деплоев. Ниже я привожу обобщенный список введенных в этом релизе флагов командной строки для prefect deployment build.

  • --apply  —  при добавлении к prefect deployment build одновременно выполняет сборку и создает или обновляет деплой, отправляя вызов API к бэкенду Prefect.
  • --skip-upload  —  позволяет пропускать загрузку в удаленное хранилище.
  • --path  —  позволяет указать подкаталог удаленного хранилища, куда нужно произвести загрузку.

Блок удаленного хранилища GitHub только для чтения

Одним из важнейших принципов дизайна в Prefect 2.0 является поэтапное освоение: пользователи должны узнавать о Prefect ровно столько, сколько им необходимо для их частного случая. Первые шаги должны быть простыми, а более продвинутые концепции можно освоить уже тогда, когда они станут актуальны для решаемой задачи. 

Следуя этому принципу, в данный релиз мы добавили блоки GitHub только для чтения, чтобы начинающие пользователи могли задействовать имеющиеся в репозитории шаблоны в качестве отправной точки без необходимости изучать все детали функционирования блоков удаленного хранилища:

Пример блока хранилища GitHub, использующий репозиторий https://github.com/anna-geller/dataflow-ops

В PR #6598 мы добавили GitHub как один из вариантов для сохранения кода потока в деплоях. Вот как этот блок можно использовать в деплоях из Prefect CLI:

prefect deployment build -n gh -q prod -sb github/dataflowops --apply flows/healthcheck.py:healthcheck
prefect deployment build -n gh -q prod -sb github/dataflowops --apply flows/hello.py:hello

Блок KubernetesJob теперь использует args вместо commands

До сих пор блок KubernetesJob опирался на commands, а не args. В PR #6581 мы изменили это поведение, чтобы сделать его более согласованным между блоками инфраструктуры Docker и Kubernetes. Подтолкнуло нас к этому проблема, связанная с ситуацией, когда некоторые пользователи хотят использовать базовый образ Prefect и установить кастомные зависимости, такие как s3ds, в среде выполнения. Ранее это можно было сделать при использовании блока DockerContainer, но не блока KubernetesJob. Теперь же этот функционал работает одинаково для тех и других.

Вот пример блока KubrtnetesJob, который показывает, как можно установить кастомные пакеты в среде выполнения до того, как под запуска потока начнет выполнение этого потока:

Для быстрой проверки этого поведения можно использовать:

Новый контекстный менеджер для отключения логгера Prefect

Одной из общих проблем, обозначенных сообществом, было тестирование потоков и задач за пределами контекста выполнения потока. Например, выполняя модульное тестирование или задачу с помощью task_function_name.fn(), вы можете столкнуться с ошибками, так как логгер Prefect (prefect.get_run_logger) доступен для использования только в контексте выполнения потока либо задачи. По этому поводу с PR #6575 был добавлен контекстный менеджер disable_run_logger(), который можно задействовать так:

from prefect import task, flow
from prefect import get_run_logger
from prefect.logging.loggers import disable_run_logger


@task
def run_this_task(user_name: str):
logger = get_run_logger()
logger.info("Hi, %s! 👋", user_name)
logger.info("Those logs are only visible from flow and task runs")
print("This will get printed, even in unit tests! 🚀")


@flow
def marvin(user: str = "Marvin"):
run_this_task(user)


if __name__ == "__main__":
with disable_run_logger():
run_this_task.fn("World")

Дальнейшие планы

Мы только что поверхностно разобрали улучшения, введенные в данном релизе. Более подробно о произошедших изменениях читайте в примечаниях к релизу и документации.

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи Anna Geller: Prefect 2.3.0 adds support for flows defined in Docker Images and GitHub Repositories

Предыдущая статьяМодули Python для ускоренной обработки JSON
Следующая статья7 способов применения Stack Overflow, о которых вы могли не знать