Task Scheduler for Python Scripts and Batch Files is a utility that allows you to schedule Python scripts and batch files to run at specified intervals. It handles virtual environments for Python scripts automatically and persists tasks between restarts.
- Schedule Python scripts and batch files to run at specified intervals
- Give descriptive names to scheduled tasks
- Edit existing tasks with updated parameters
- Automatic virtual environment activation for Python scripts (venv and uv projects)
- Batch files run directly from their own directory
- Persistent storage of tasks in SQLite database
- Configurable logging system with detailed debugging options
- Graceful shutdown handling
- Status page generation (HTML or PHP with authentication)
- FTP upload with configurable sync interval
- Configurable output path for status page
- Python 3.10 or higher
- Windows operating system
- uv package manager
- Each Python script must have one of:
- A
venvsubfolder (traditional virtual environment), OR - A
pyproject.toml+uv.lock(uv-managed project, requiresuvinstalled)
- A
- Batch files (.bat) can be scheduled without any additional requirements
- Clone this repository
- Install uv if not already installed
- Run the installation script:
Or manually:
install.batuv sync
There are two ways to add a new task:
Use the --add flag to enter interactive mode, which will guide you through the process:
python main.py --addThis will prompt you for:
- Script path (with validation)
- Task name
- Interval in minutes
- Arguments (optional, press Enter twice to finish)
Use the --script flag along with other parameters to add a task directly:
python main.py --script "path/to/script.py" --name "task description" --interval minutes -- script_arguments--script: Path to the Python script or batch file to schedule (absolute path or relative to current directory)--name: Descriptive name for the task (e.g., "convert audio notes to text")--interval: Interval in minutes between script executions--: Separator after which all arguments are passed to the script- Arguments after
--are passed directly to the script
# Simple Python task without arguments
python main.py --script "local_script.py" --name "local task" --interval 1
# Batch file task
python main.py --script "backup.bat" --name "daily backup" --interval 60
# Complex Python task with quoted arguments and paths
python main.py --script "D:\GIT\BenjaminKobjolke\ai-file-renamer\main.py" --name "convert XIDA invoices" --interval 5 -- --source "Z:\Resilio Sync\XIDA_Invoices" --examples "E:\Owncloud\xida\company\GmbH\[--Dokumente--]\[--Rechnungen--]\[--In--]"
# Batch file with arguments
python main.py --script "cleanup.bat" --name "cleanup temp files" --interval 30 -- --force --verboseNote: When using arguments with spaces or special characters, make sure to:
- Use
--to separate scheduler arguments from script arguments - Quote values that contain spaces or special characters
To view all configured tasks without starting the scheduler:
python main.py --listThis will display each task's:
- ID (for use with --delete or --edit)
- Name
- Script path
- Interval
- Arguments
- Next scheduled run time
To view recent task executions:
# Show last 10 executions (default)
python main.py --history
# Show last N executions
python main.py --history 20This will display:
- Execution timestamp (local time)
- Task name
- Success/failure status
To edit an existing task:
python main.py --edit IDThis will:
- Show the task's current details
- Enter interactive mode with current values pre-filled
- Press Enter to keep existing values or enter new ones
- Update the task with any changes
For example:
python main.py --edit 1To delete a task by its ID:
python main.py --delete IDThis will:
- Show the task's details
- Ask for confirmation
- Delete the task if confirmed
To start the scheduler and run all configured tasks:
python main.pyThis will:
- Load all tasks from the database
- Display the list of configured tasks
- Start executing them at their specified intervals
-
Python scripts: Each Python script must have either:
- A
venvsubfolder (usesvenv/Scripts/python.exedirectly), OR - A
pyproject.toml+uv.lockfile (usesuv run python script.py)
The scheduler auto-detects the environment type and activates it appropriately.
- A
-
Batch files: Batch files (.bat) are executed directly from their own directory. No virtual environment is required.
-
Tasks persist between scheduler restarts
-
The scheduler executes scripts in their respective directories
Logging can be configured through both the config.ini file and command-line arguments.
[Logging]
# Logging level: DEBUG, INFO, WARNING, ERROR
level = INFO
# Enable/disable detailed argument logging
detailed_args_logging = falseOverride logging settings temporarily:
# Set logging level
python main.py --log-level DEBUG
# Enable detailed argument logging
python main.py --detailed-logs true
# Combine both
python main.py --log-level DEBUG --detailed-logs true- DEBUG: Show all log messages including detailed debugging information
- INFO: Show general operational messages (default)
- WARNING: Show only warning and error messages
- ERROR: Show only error messages
When enabled (detailed_args_logging = true), shows:
- Original arguments as entered
- JSON format stored in database
- Parsed arguments during task execution
This is particularly useful when debugging issues with argument handling.
Logs are stored in the logs directory with the following format:
- File name:
scheduler_YYYYMMDD.log - Contains execution details, script output, and any errors
- Log level and detail settings affect what information is included
The scheduler generates a status page showing recent executions and upcoming tasks.
[StatusPage]
# Output type: html or php (php adds password authentication)
output_type = html
# Output path (relative to project root or absolute path)
output_path = web
# Password for PHP login (only used when output_type = php)
php_password = changeme
# Path to php-simple-login library (only used when output_type = php)
php_login_library_path = D:\GIT\BenjaminKobjolke\php-simple-login- html: Simple HTML page (default)
- php: HTML wrapped with PHP authentication using php-simple-login
Automatically upload the status page to an FTP server.
[FTP]
# Enable automatic FTP sync after status page updates
enabled = false
# FTP server settings
host = ftp.example.com
port = 21
username = your_username
password = your_password
remote_path = /public_html/status
# Connection settings
passive_mode = true
timeout = 30
# Minimum minutes between FTP syncs (0 = sync every time)
sync_interval = 5Trigger FTP sync manually:
python main.py --ftp-syncTo stop the scheduler:
- Press Ctrl+C in the terminal
- The scheduler will gracefully shutdown, completing any running scripts
- If a Python script has neither a
venvfolder nor uv project files (pyproject.toml+uv.lock), an error will be logged - If
uvis not installed but an uv project is detected, the execution will fail with an error - If a script or batch file fails to execute, it will be logged and the scheduler will continue with the next task
- All errors are logged with full stack traces for debugging
task-scheduler/
├── .venv/ # Project's virtual environment (uv managed)
├── src/
│ ├── __init__.py
│ ├── scheduler.py # Core scheduling logic
│ ├── script_runner.py # Script/batch file execution handling
│ ├── database.py # Task persistence
│ ├── config.py # Configuration handling
│ ├── constants.py # Application constants
│ ├── logger.py # Logging functionality
│ ├── status_page.py # Status page generation (HTML/PHP)
│ ├── php_login.py # PHP authentication handling
│ └── ftp_syncer.py # FTP upload functionality
├── sources/web/templates/ # Status page templates
├── data/ # Database directory
│ └── tasks.sqlite # SQLite database for tasks
├── logs/ # Log files directory
├── web/ # Generated status page output
├── main.py # Entry point
├── config.ini # Configuration file
├── config.ini.example # Example configuration
├── pyproject.toml # Project dependencies (uv)
├── install.bat # Installation script
└── README.md # This file