Запускаем Python-скрипт с помощью Cron на Linux

Запускаем Python-скрипт с помощью Cron на Linux

Я, как настоящий старовер, решил построить «data-pipeline» без коннекторов и DAG-менеджеров. Положив два перста на мышку, началась упорная работа. Разобрался с API рекламных систем, установил драйвер bigquery, залил первую таблицу в датасет. Победа была близка, осталось всё автоматизировать. Я начал разворачивать Airflow, а потом проснулся и вспомнил про cron.

Вспомнив про ранее купленный на лучшемгосподихостинге бегете VPS, куда я деплоил свой tf-idf кластеризатор. Было решено залить скрипт на сервер и настроить его запуск на 6 утра ежедневно.

Cron — это демон, а демон — это программа работающая в фоновом режиме. Ну а если вы программировали на Python — вам должны быть знакомы процессы-демоны. Запуск Cron-задания — это легко, но только в случаях когда мы говорим об выполнении php и bash скриптов. С Python всё иначе.


Устанавливаем Python на сервер

Выполняем, указные команды на примере Ubuntu.

sudo apt update
sudo apt install python3.8
sudo apt install -y python3-pip

Проверяем успешность установки командой python3.

Создаем виртуальное окружение virtalenv

Следующий шаг — изолировать наш проект в отдельное виртуальное окружение, куда мы будем устанавливать нужные нам библиотеки.

pip3 install virtualenv # устанавливаем библиотеку
cd /home/iakulshin # идем в папку вашего пользователя, тут на ваше усмотрение
mkdir pipeline # создаем папку проекта
cd /pipeline # переходим в папку
virtualenv -p python3 venv # создаем виртуальное окружение, важно что мы устаналиваем с параметром -p, а то получим python 2.7
source venv/bin/activate # активируем

Теперь мы видим рядом в консоли перед строкой приписку (venv) — это значит, что мы в виртуальном окружении.

создание venv python linux


Запуск Python-скрипта с помощью Сron

Давай потестируем то, что у нас получилось на маленьком скрипте, который будет писать в файл дату и время его активации. Таким образом мы проверим как работает cron. Тестовый скрипт, который мы положим в корень папки проекта, у меня это /home/iakulshin/pipeline, заливаем через файловый менеджер filezilla и прочие, если вы хардкорный девопс-дата-инженер удачи вам с nano. Заливаем скрипт указанный ниже в нашу папку.

 

from datetime import datetime

with open('test.txt', 'a+', encoding='utf-8') as file:
    file.write(datetime.today().strftime('%Y-%m-%d-%H-%M-%S') + '\n')

Давайте попробуем создать cron задание для тестового запуска. В целом нам будут нужны 2 команды:

crontab -l # выводит список текущих заданий
crontab -e # открывает файл заданий
crontab -r # удаляет файл задания
Пишем в консоль crontab -e

Появлеятся файлик с крон задачами в редакторе nano. Наша задача установить задание, которое будет запускать наш скрипт каждую минуту.

* * * * * cd /home/iakulshin/pipeline && /home/iakulshin/pipeline/venv/bin/python3 test.py
[минута] [час] [день] [месяц] [день недели] [Переходим в папку] [&& - означает "и"] [с помощью интерпретатора python3 запускаем файл test.py]

Делюсь лайфхаком — конструктор для составления расписаний cron

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


Как понять что Cron срабатывает?

Чтобы удостовериться, что cron-таск отрабатывает, нам необходимо добавить задачу и обратиться к логам сервера, для этого идем в консоль и пишем следующую команду:

tail /var/log/syslog # получаем "хвост", последние 10 строк лог-файла

В нем вы увидите следующие записи:
как понять что cron сработала

Это означает, что cron срабатывает и воспроизводит команду, которую вы указали после звездочек. Но что делать, если python-скрипт всё еще не работает?


Cron срабатывает но Python-скрипт не выполняется

Самая типичная проблема, которая связана с «холостым» крон-таском — это недоступность библиотек, неверный выбор virtual env и версии python. Способ выбранный выше — это способ к которому я пришел спустя десяток часов поисков и изучения stackoverflow. Что нужно проверить для успешного запуска скрипта:

Возьмите команду, которую собирались добавь в крон и запустите её, это поможет словить ошибки связанные с недоступностью библиотек. В моем случае Скрипт не видел импортируемый файл, это я вылечил добавлением папки в системный путь. Добавляем в скрипты следующий код:

#!/home/iakulshin/bq_uploader/venv/bin/python
import sys 
sys.path.insert(1, '/home/iakulshin/bq_uploader/') # Путь до вашей папки со скриптом

Если скрипт запускается по прямой команде из консоли, но cron всё еще не выполняется, то ошибка 100% в том, что ваш скрипт запускается не из под virtualenv или вы запускаете скрипт из под python не подходящей версии, поэтому проверяем следующее:

  1. Мы перешли в папку со скриптом командой cd
  2. Мы обратились к интерпретатору python3 находящемуся в папке с виртуальным окружением нашего проекта.

В целом данный гайд должен помочь вам разобраться с запуском Python скриптов с помощью Cron. Однако, я оставлю ссылки на полезные треды в stackoverflow, где представлены дополнительные способы решения этой проблемы.

 


Запуск Python-скрипта с Cron через Bash-скрипт: https://stackoverflow.com/questions/12534135/crontab-not-executing-a-python-script