Найти тему
Computer Pro

Celery, Redis, Flower выполнение периодических задач

Оглавление

Тот учебный материал, что был предоставлен образовательной платформой (очень известной чтобы её называть) для изучения материала по "сельдерею с редиской" мне (моё оценочное суждение), оказался непонятным. Я попытался по пунктам разложить, как всё делал.

Итак, скачаем контейнер redis:

-2

Затем его нужно запустить:

так как я его уже запускал с этими параметрами, то у меня произошел конфликт имен, и запуск не получился, тут нужна уже другая команда, см. ниже:
так как я его уже запускал с этими параметрами, то у меня произошел конфликт имен, и запуск не получился, тут нужна уже другая команда, см. ниже:

Можно запустить контейнер в интерактивном режиме, будут отображаться все сообщения:

-4

Можно в фоновом:

-5

Завершить работу контейнера можно командой

-6

Проверить работу контейнера можно командой, она покажет только запущенные контейнеры:

-7

Вывести все контейнеры можно той же командой что и выше, с ключом -а:

-8

Итак, redis у нас запущен, теперь дело за celery, его так же нужно запустить как типа сервер-задач, иначе программа не будет отрабатывать:

-9

Запускал я его из той директории где находится файл tasks.py. Затем мне пришла в голову идея - а может запуск celery не нужен, я просто выполню в консоли файл tasks.py ???

-10

И... я попробовал его запустить, только вот незадача, без запущенного celery задачи не выполняются, пришлось скрипт завершать сочетанием клавиш Ctrl+C:

сработало исключение после нажатия Ctrl+C, иначе бы result.get() мог бы ждать пока электричество не кончится...
сработало исключение после нажатия Ctrl+C, иначе бы result.get() мог бы ждать пока электричество не кончится...

Понятно, без celery -A tasks worker скрипт не может завершить работу... Запустил celery и повторил те же самые команды, теперь получил ответ:

-12

Практическая работа:

Представьте, что пользователь загружает на сервис некоторое количество изображений, указывая свою почту. Ко всем изображениям применяется эффект размытия. Изображения отправляются ему на почту в виде архива или списка изображений по мере готовности.
Реализуйте следующие endpoints:
POST /blur
Ставит в очередь обработку переданных изображений. Возвращает ID группы задач по обработке изображений.
GET /status/<id>
Возвращает информацию о задаче: прогресс (количество обработанных задач) и статус (в процессе обработки, обработано).
POST /subscribe
Пользователь указывает почту и подписывается на рассылку. Каждую неделю ему будет приходить письмо о сервисе на почту.
POST /unsubscribe
Пользователь указывает почту и отписывается от рассылки.
Функции для обработки изображения и отправки письма уже реализованы, поэтому можете сконцентрироваться на внедрении очереди задач.

Начнем с того что нужно запустить все необходимые сервисы для работы нашего приложения (при условии, что ранее все зависимости были установлены, см. выше):

-13
-14
-15
пока ни одной задачи не выполняется и не выполнялось
пока ни одной задачи не выполняется и не выполнялось

Итак, создадим эндпойнт, который будет загружать картинки на сервер, все эндпойнты будут прописаны в файле app.py

-17
шаблон главной страницы
шаблон главной страницы
Как это всё будет выглядеть в браузере
Как это всё будет выглядеть в браузере

Пройдем по ссылке "Загрузить изображения". Открывается форма выбора файлов для загрузки. Можно выбрать сразу несколько файлов.

-20
-21

Выбрали несколько изображений, нажали, кнопочку "Отправить", изображения попали на сервер, колёсики завертелись, что-то стало там происходить и мы получаем ответ в виде id группы задач.

-22

А в директории проекта появилась папка куда будут загружаться изображения до и после обработки (после обработки имена файлов будут отличаться словом "blur_":

в правом верхнем углу можно наблюдать размер исходного файла
в правом верхнем углу можно наблюдать размер исходного файла
в правом верхнем углу можно наблюдать размер обработанного фала, разница с оригиналом почти в 10 раз меньше
в правом верхнем углу можно наблюдать размер обработанного фала, разница с оригиналом почти в 10 раз меньше

Ну теперь посмотрим из чего состоит эндпойнт /blur, так сказать - что же происходило под капотом нашего сервера обработки изображений.

собственно про импорты: не то что бы именно в этом месте кода надо импортировать, имеется в виду что непосредственно перед использованием! Кому как нравится, можно собственно сделать импорт в начале функции blur(), главное чтоб не в начале файла app.py
собственно про импорты: не то что бы именно в этом месте кода надо импортировать, имеется в виду что непосредственно перед использованием! Кому как нравится, можно собственно сделать импорт в начале функции blur(), главное чтоб не в начале файла app.py

Итак, это у нас эндпойнт, посмотрим как происходит постановка задач, изначально файл был назван celery.py, мне пришлось его переименовать чтобы не было конфликтов при использовании имени celery. Теперь он у меня celery_tasks.py:

-26

В консоли, где запущен сервер celery, происходит следующее:

-27

Изначальный файл image.py, я тоже немного доработал, возможно не в самую лучшую сторону, но это работает. Потому что в начальной версии был просто приём файлов, без указания директорий для загружаемых файлов а это мне не очень нравилось. И была аннотация типов, которая почему то "ругалась" на то что мол у меня "не строка", а как не строка если путь к файлу и есть строка!? Поэтому не стал заморачиваться и чуть подправил данный файл. Возможно куратору это не понравится...

-28

Следующий пункт, теперь отблюренные файлы нужно заархивировать и отправить в качестве рассылки на все зарегистрированные email'ы.

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

-29
-30

Так же можно вбить group_id в поле ввода и так же получить на почту архив с отблюренными снимками.

-31

Работает это так:

-32

Примерно так же работает с шаблоном, в котором есть поле для ввода group_id.

Теперь осталось написать обработку периодических задач. А так же подписку и отписку от рассылки писем один раз в неделю от нашего блюр-сервиса.

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

Итак, подписка, вводим email:

-33
-34

Создаем базу данных emails, с одной таблицей и вставляем в таблицу адрес электронной почты полученный из формы для ввода.

-35

Отписка еще проще:

-36

Теперь про запуск периодических задач. Чтобы периодические задачи выполнялись worker тоже должен быть запущен:

-37

У меня он запущен в отдельном окне терминала. Как я его запускал, по порядку с докером и редис:

-38

А затем уже из терминала в Pycharm запустил планировщик периодических задач.

-39

Долго не мог понять почему не запускаются задачи по времени, а тут непонятная мне фишка с UTC, у меня мозг отказывается понимать как правильно записывать время. Вот фактически у меня сейчас 8 часов вечера а в скрипте приходится указывать на 3 часа меньше.

-40

Я тут немного испытывал свой код в разных режимах и рассылка шла на 2 действительных электронных адреса, которые задача считывала из базы данных.

-41

Давайте посмотрим, сколько писем я написал сам себе пока испытывал программу:

-42
-43

Я попытался снять видео с тем как я запускал всё это добро, вдруг кому-то пригодится, видео без обрезки, плюс там выскакивает ошибка, от кучи задач которые сохранились со вчерашнего вечера (это я сегодня пришел с работы и включил домашний комп, чтоб снять видео) хотя всё равно всё работает, так что не обессудьте:

Ну вот, собственно и всё. Я таки немного понял азы Celery, Redis, Flower, дай то бог и вам моя писанина на что-то сгодится. Возможно тут найдется куча ошибок, но это не руководство по эксплуатации готового программного продукта а лишь мой конспект.