Запустите скрипт Python в виртуальной среде из планировщика задач Windows.

Я пытаюсь настроить повторяющуюся задачу Python через планировщик задач Windows.

У меня был успех, когда я ввел путь к 'python.exe' и указал путь к скрипту в качестве параметра для планировщика задач Windows (см. Скриншот ниже)

планировщик задач Windows

Тем не менее, я хочу иметь возможность выбрать конкретную виртуальную среду для запуска сценария. У меня нет особых знаний о venv, и я обычно использую его, открыв cmd и запустив Scripts\activ.bat в нужном каталоге виртуальной среды.

Как выполнить "запуск задачи x в venvxxx каждые 24 часа" с помощью планировщика задач Windows?

9 ответов

Решение

Создайте командный файл с этими командами:

c:\__full_path_to_virtualenv__\Scripts\activate.bat && python __full_path_to_python_script__.py

&& означает запуск команды2, если команда1 выполнена успешно.

Затем установите этот пакетный файл как скрипт для запуска. Вам не нужно устанавливать никаких дополнительных аргументов в планировщике задач (или вы можете установить их в пакетном файле в любом случае) и можете установить Start in, если скрипт должен читать / писать из определенного каталога и использует относительные пути.

Это более многословно, но очень легко понять, и - я нашел самое важное - гораздо проще, чем использовать настройки планировщика заданий Windows, когда у вас много сценариев. Чтобы создать другой, просто скопируйте файл.bat и измените одну строку.

Сохраните это как файл.bat и укажите на него в Actions > Start a Program > Program/Script:, без аргументов или "Начало в" необходимо.

set original_dir=%CD%
set venv_root_dir="C:\Python-Venvs\env-name"
cd %venv_root_dir%
call %venv_root_dir%\Scripts\activate.bat

python your_script.py <arg1> <arg2>

call %venv_root_dir%\Scripts\deactivate.bat
cd %original_dir%
exit /B 1

Для установленной программы командной строки вы можете заменить python your_script.py <arg1> <arg2> ... с <program name> <arg1> <arg2> ...,

Кроме того, просто добавить еще один скрипт в следующую строку, вместо того, чтобы пытаться анализировать последовательные скрипты в одну строку для планировщика задач.

Хотя ответ mx0 выше, похоже, работает, я настроил Task Scheduler для запуска веб-приложения на флеш-накопителе при загрузке. В этом случае ручной запуск работает нормально, а ручной - нет. Завершение задачи убивает задачу cmd.exe, которая устанавливает виртуальную среду, но python.exe продолжает работать.

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

path\to\venv\Scripts\python.exe path\to\script.py

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

Я пробовал с ответом mx0, и он отлично работает, если ваш сценарий не займет слишком много времени.

Я использую другой подход в планировщике задач вместо командных файлов:

В текстовом поле "Программа / сценарий" вы устанавливаете путь к исполняемому файлу Python (в моем случае находится внутри папки virtualenv).

"Добавить аргументы" => Просто имя вашего скрипта Python (name.ppy).

"Начать в" => Полный путь к вашему скрипту Python (без name.py).

Таким образом скрипт запускается и дожидается конца.

Мое решение почти идентично mx0, но я добавил дополнительный шаг, чтобы каждый раз проверять параметры среды. Отредактируйтеpath/to/app для app_path переменная.

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

Просто запланируйте execute_app.batфайл или запустите в командной строке. Команда деактивировать не требуется, если она не запускается из командной строки Anaconda. Если вы используете полный путь дляpath/to/appэтот файл можно запустить из любого каталога. У меня также есть решение для Linux, использующееexecute_app.sh файл ниже из терминала.

Этот ответ был отредактирован для упрощения и использования переменных, чтобы упростить адаптацию к новым проектам.

Структура приложения:
app/bin/app.py
app/bin/execute_app.bat
app/env/requirements.txt

# execute_app.bat file
# windows solution

SETLOCAL
set app_path=path/to/app
set env_path=%app_path%/env
set activ=%env_path%/Scripts/activate.bat
set req=%env_path%/requirements.txt
set app=%app_path%/bin/app.py

py -m venv %env_path% && %activ% && python -m pip install --upgrade pip && pip install -r %req% && python %app%
ENDLOCAL
#!/bin/bash

# execute_app.sh file
# Linux solution

app_path='path/to/app'
env_path=$app_path'/env'
activ=$env_path'/bin/activate'
req=$env_path'/requirements.txt'
app=$app_path'/bin/app.py'

python3 -m venv $env_path &&
. $activ &&
python3 -m pip install --upgrade pip &&
pip install -r $req &&
python $app &&
deactivate

Выбранный ответ на этот вопрос неверен. Если вы просмотрите комментарии, вы увидите проблему.

Мой ответ основан на ответе @Nick P (в настоящее время ответ №2). Его пакетный файл будет работать, но вам нужно изменить код выхода с 1 на 0, если вы хотите, чтобы планировщик заданий Windows сообщал об успешном завершении задачи. Кроме того, простой вызов файла .bat в строке «Программа/скрипт» не сработает. Вместо этого вам нужно указать имя вашей оболочки в качестве «Программы/скрипта» для запуска (например, cmd), а затем указать «/c name-of-batch-file.bat» в «Добавить аргументы (необязательно ):" поле. И, наконец, укажите путь к пакетному файлу (минус имя файла) в поле «Начать в (необязательно):».

Это должно выглядеть примерно так:

Создание bat-файла для запуска скрипта Python работает при запуске процесса, но не при его остановке. Когда taskengine.exe решит остановить задание, процесс bat будет уничтожен, а Python.exe останется соломинкой.

Имхо, лучший способ - создать служебный модуль, например patch_conda_pathисправить PATH в os.environ на основе sys.base_exec_prefix.
например

      import is, sys
conda_base = sys.base_exec_prefix
subps = [";", "library\\mingw-w64\\bin;", "library\\usr\\bin;", "library\\bin;", "scripts;", "bin;", "condabin;"]
conda_paths = ""
for p in subps :
    _p = os.path.join(conda_base, p)
    if _p in os.environ["PATH"]:
        continue
    else:
        conda_paths += _p
os.environ["PATH'"] = conda_paths + os.environ["PATH"]

Импортируйте этот модуль в самое начало основного скрипта. Установлен programв task schedulerк ... conda path...\python.exe, argumentsк вашему имени файла сценария py и start inв папку вашего py-скрипта.

Это также работает для сценария фляги, запускаемого официанткой в ​​​​conda3.

С помощью ChatGPT мне удалось создать небольшой скрипт «.bat», который может активировать виртуальную среду, а затем запустить скрипт Python. Самое приятное то, что каждый элемент находится в корневой папке проекта, поэтому вам не нужно слишком много думать о путях к файлам.

Вот сначала моя структура папок:

      Project
 - venv
 - update_data.bat
 - extraction.py

и это код файлаupdate_data.bat:

      @echo off

rem Get the directory path of the script
for %%I in (%0) do set SCRIPT_DIR=%%~dpI

rem Specify the name of the virtual environment folder
set VENV_FOLDER=venv

rem Set the virtual environment path by combining the script directory and the virtual environment folder
set VENV_PATH=%SCRIPT_DIR%%VENV_FOLDER%

rem Activate the virtual environment
call %VENV_PATH%\Scripts\activate.bat

rem Move to script location
call cd %SCRIPT_DIR%

rem Run your Python script
python extraction.py

rem Deactivate the virtual environment
call %VENV_PATH%\Scripts\deactivate.bat

Затем вы можете вызвать командный файл с помощью планировщика задач.

      REM Windows batch script to run 1+ Python program/scripts, sequentially, within
REM their virtual environment. This can be called from Windows Task Scheduler.
        
set original_dir=%CD%

set venv_root_dir="C:\Users\myUsername\myProjects\nameOfProject"
        
cd %venv_root_dir%
        
call %venv_root_dir%\Scripts\activate.bat
        
python nameOfPythonProgram.py
        
call %venv_root_dir%\Scripts\deactivate.bat
        
cd %original_dir%
    
exit /B 1

Скопировал это с nmpowell на github, и он отлично работает. Запуск из планировщика задач

Другие вопросы по тегам