{"id":49360450,"url":"https://github.com/cornish/python-task-scheduler","last_synced_at":"2026-04-27T16:02:20.257Z","repository":{"id":327311510,"uuid":"1104187522","full_name":"cornish/python-task-scheduler","owner":"cornish","description":"A lightweight, production-ready pure-Python job scheduler featuring YAML-based configuration, flexible scheduling (seconds to monthly), an optional Tkinter GUI for management and monitoring, automatic log rotation, a service control command line tool, and Windows service integration with watchdog auto-recovery.","archived":false,"fork":false,"pushed_at":"2026-03-13T21:09:01.000Z","size":84,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-14T09:33:46.406Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cornish.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-25T21:57:12.000Z","updated_at":"2026-03-13T21:09:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cornish/python-task-scheduler","commit_stats":null,"previous_names":["cornish/python-task-scheduler"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cornish/python-task-scheduler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cornish%2Fpython-task-scheduler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cornish%2Fpython-task-scheduler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cornish%2Fpython-task-scheduler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cornish%2Fpython-task-scheduler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cornish","download_url":"https://codeload.github.com/cornish/python-task-scheduler/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cornish%2Fpython-task-scheduler/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32343571,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T23:26:28.701Z","status":"online","status_checked_at":"2026-04-27T02:00:06.769Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-27T16:02:19.240Z","updated_at":"2026-04-27T16:02:20.245Z","avatar_url":"https://github.com/cornish.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# Job Scheduler\n\nA production-ready Python job scheduler with configuration validation, logging, and process management. Fully supports UNC network paths and cross-platform operation.\n\n## Quick Start\n\n### Windows (PowerShell - Recommended)\n\n```powershell\n# Create virtual environment\npython -m venv venv\n\n# Activate virtual environment\n.\\activate_venv.ps1\n\n# Install dependencies from requirements.txt\npip install -r requirements.txt\n\n# Start scheduler\n.\\scheduler_ctl.ps1 start       # Background mode (daemon)\n# or\n.\\start_scheduler.ps1           # Foreground mode (see logs)\n.\\start_scheduler.ps1 -bg       # Background mode\n```\n\n### Command Line (Python)\n\n```bash\n# Install dependencies\npip install -r requirements.txt\n\n# Start scheduler\npython scheduler_ctl.py start\n```\n\n### GUI (Optional)\n\n```powershell\n# Install dependencies\npip install -r requirements.txt\n\n# Launch GUI\npython gui.py\n```\n\nThe GUI provides:\n- Visual job management (add, edit, delete, enable/disable)\n- Live log viewer with filtering and color coding\n- One-click scheduler control (start/stop/restart)\n- Real-time status monitoring\n- Job validation with visual indicators\n- Manual job execution (\"Run Now\")\n\n## Files\n\n| File | Purpose |\n| --- | --- |\n| **Python Scripts** | |\n| scheduler.py | Main scheduler daemon |\n| scheduler_core.py | Shared core functionality (job execution, process control) |\n| scheduler_ctl.py | Command-line control script (start/stop/restart/status) |\n| gui.py | Optional Tkinter GUI for management and monitoring |\n| watchdog.py | Auto-restart monitor with thrashing detection |\n| validate_jobs.py | YAML configuration validator |\n| jobs.yaml | Job definitions |\n| **PowerShell Scripts** | |\n| scheduler_ctl.ps1 | PowerShell control script (wraps Python version) |\n| start_scheduler.ps1 | Start scheduler with foreground/background modes |\n| run_watchdog.ps1 | Run watchdog monitor |\n| activate_venv.ps1 | Activate virtual environment |\n| **Batch Files** | |\n| start_scheduler.bat | Windows startup batch file (background mode) |\n\n## Control Scripts\n\n### PowerShell (Recommended for Windows)\n\n```powershell\n.\\scheduler_ctl.ps1 status   # Show running status, PID, memory, CPU\n.\\scheduler_ctl.ps1 start    # Start scheduler in background\n.\\scheduler_ctl.ps1 stop     # Stop scheduler gracefully\n.\\scheduler_ctl.ps1 restart  # Restart scheduler\n```\n\n### Python (Cross-Platform)\n\n```powershell\npython scheduler_ctl.py status   # Show running status, PID, memory, CPU\npython scheduler_ctl.py start    # Start scheduler in background\npython scheduler_ctl.py stop     # Stop scheduler gracefully\npython scheduler_ctl.py restart  # Restart scheduler\n```\n\n## Starting the Scheduler\n\n### PowerShell Scripts\n\n#### Foreground Mode (Interactive)\n```powershell\n.\\start_scheduler.ps1\n```\n- Shows live logs and output\n- Useful for debugging\n- Press Ctrl+C to stop\n\n#### Background Mode (Daemon)\n```powershell\n.\\start_scheduler.ps1 background\n.\\start_scheduler.ps1 bg\n```\n- Runs hidden in background\n- No console window\n- Verifies PID file creation\n- Returns immediately\n\n### Using Control Script\n```powershell\n.\\scheduler_ctl.ps1 start    # Always background mode\n```\n\n## GUI Features\n\nLaunch with `python gui.py` for a graphical interface with:\n\n### Job Management\n- **Create/Edit/Delete Jobs**: Full CRUD operations with validation\n- **Enable/Disable Jobs**: Toggle jobs without deleting\n- **Run Now**: Execute any job immediately for testing\n- **Invalid Job Detection**: Visual indicators for jobs with configuration errors\n\n### Monitoring\n- **Live Log Viewer**: Auto-refreshing log display (updates every 2 seconds)\n- **Log Filtering**: Filter by log level (ERROR, WARNING, INFO, DEBUG)\n- **Color Coding**: Different colors for each log level\n- **Status Display**: Shows scheduler state, PID, and last job execution\n\n### Scheduler Control\n- **Start/Stop/Restart**: One-click scheduler management\n- **Status Monitoring**: Real-time scheduler status updates\n- **Validation Blocking**: Prevents starting with invalid enabled jobs\n\n### Dialog Features\n- **Dynamic Validation**: Real-time field validation with visual warnings\n- **Smart Hints**: Context-sensitive hints based on schedule type\n- **Command Tooltips**: Hover over long commands to see full text\n- **Required Field Indicators**: Red exclamation marks for missing required fields\n\n## Job Configuration\n\nJobs are defined in `jobs.yaml`:\n\n```yaml\njobs:\n  - name: \"daily_backup\"\n    command: \"python scripts/backup.py\"\n    schedule:\n      every: 1\n      unit: \"days\"\n      at: \"02:00\"\n\n  - name: \"hourly_check\"\n    command: \"python scripts/check_disk.py\"\n    schedule:\n      every: 1\n      unit: \"hours\"\n      at: \":15\"\n\n  - name: \"weekly_report\"\n    command: \"python scripts/report.py\"\n    schedule:\n      every: 1\n      unit: \"weeks\"\n      day: \"monday\"\n      at: \"09:00\"\n\n  - name: \"monthly_invoice\"\n    command: \"python scripts/report.py\"\n    schedule:\n      unit: \"months\"\n      day_of_month: 1\n      at: \"09:00\"\n\n  - name: \"quarterly_maintenance\"\n    command: \"python scripts/maintenance.py\"\n    schedule:\n      unit: \"months\"\n      day_of_month: 1\n      at: \"03:00\"\n      months: [1, 4, 7, 10]\n\n  - name: \"init_check\"\n    command: \"python scripts/heartbeat.py\"\n    schedule:\n      unit: \"startup\"\n    enabled: true  # Optional: defaults to true if omitted\n```\n\n### Required Fields\n\n- `name`: Unique job identifier\n- `command`: Shell command to execute (can include arguments)\n- `schedule`: Schedule configuration (see below)\n\n### Optional Fields\n\n- `enabled`: Set to `false` to disable a job without deleting it (defaults to `true`)\n\n### Schedule Types\n\n| Unit | every | at | day | day_of_month | months |\n| --- | --- | --- | --- | --- | --- |\n| seconds | required | - | - | - | - |\n| minutes | required | :SS offset | - | - | - |\n| hours | required | :MM offset | - | - | - |\n| days | required | HH:MM | - | - | - |\n| weeks | required | HH:MM | day name | - | - |\n| months | - | HH:MM | - | 1-31 | list of 1-12 |\n| startup | - | - | - | - | - |\n\n### Time Offsets\n\nUse offsets to stagger jobs and avoid thundering herd:\n\n- Hours: `:15` runs at 15 minutes past each hour\n- Minutes: `:30` runs at 30 seconds past each interval\n\n### Startup Jobs\n\nJobs with `unit: \"startup\"` run once immediately when the scheduler starts. Useful for initialization tasks, health checks, or cache warming.\n\n### Monthly Jobs\n\nJobs with `unit: \"months\"` run on a specific day of the month. The scheduler checks daily and only executes if today matches `day_of_month`.\n\nOptionally, use `months` to restrict a monthly job to specific months (e.g., quarterly):\n\n```yaml\n  - name: \"quarterly_report\"\n    command: \"python scripts/report.py\"\n    schedule:\n      unit: \"months\"\n      day_of_month: 1\n      at: \"03:00\"\n      months: [1, 4, 7, 10]  # Jan, Apr, Jul, Oct\n```\n\nWhen `months` is omitted, the job runs every month.\n\n## Path Handling\n\nThe scheduler fully supports both relative and absolute paths, including UNC network paths:\n\n### Relative Paths\nRelative paths in job commands are resolved from the scheduler directory:\n```yaml\ncommand: \"python scripts/backup.py\"\n```\n\n### Absolute Paths\nFull paths work on both local and network drives:\n```yaml\ncommand: \"python C:\\\\tools\\\\backup.py\"\ncommand: \"python \\\\\\\\server\\\\share\\\\scripts\\\\backup.py\"\n```\n\n### UNC Path Support\nWhen the scheduler runs from a UNC path (e.g., `\\\\server\\share\\scheduler`), the system automatically handles CMD.EXE limitations using `pushd`/`popd` to temporarily map network paths to drive letters.\n\n## Environment Variables\n\n| Variable | Default | Description |\n| --- | --- | --- |\n| SCHEDULER_CONFIG | jobs.yaml | Config file path |\n| SCHEDULER_LOG_LEVEL | INFO | Log level |\n| SCHEDULER_TIMEOUT | 300 | Default timeout (seconds) |\n| SCHEDULER_LOG_SIZE | 10 | Log max size (MB) |\n| SCHEDULER_LOG_COUNT | 5 | Log backup count |\n\n## Watchdog\n\nThe watchdog is a monitoring script that checks if the scheduler is running and restarts it if needed. It's designed to be run periodically by an external scheduler (like Windows Task Scheduler or cron).\n\n### Manual Execution\n\n#### PowerShell\n```powershell\n.\\run_watchdog.ps1\n```\n\n#### Python\n```powershell\npython watchdog.py\n```\n\n### Automated Monitoring Setup\n\nThe watchdog is a one-shot script - it checks once and exits. For continuous monitoring, schedule it to run periodically using **Windows Task Scheduler or cron** (external to the scheduler process):\n\n#### Windows Task Scheduler (Recommended)\n1. Open Task Scheduler\n2. Create a new task to run the watchdog every 5-10 minutes\n3. Set trigger: \"Repeat task every 5 minutes\"\n4. Action - Choose one:\n   - **PowerShell**: \n     - Program: `powershell.exe`\n     - Arguments: `-ExecutionPolicy Bypass -File \"\\\\mcwcorp\\Departments\\Pathology\\Users\\tcornish\\automation\\scheduler\\run_watchdog.ps1\"`\n   - **Python directly**:\n     - Program: `pythonw.exe` (from your venv or system Python)\n     - Arguments: `\"\\\\mcwcorp\\Departments\\Pathology\\Users\\tcornish\\automation\\scheduler\\watchdog.py\"`\n\n#### Linux/Mac (cron)\n```bash\n*/5 * * * * /path/to/venv/bin/python /path/to/watchdog.py\n```\n\n**Important**: The watchdog must be scheduled **externally** (not by the scheduler itself) so it can restart the scheduler if it crashes.\n\n### Features\n\n- Checks if scheduler is running (single check per execution)\n- Auto-restarts if process has died\n- Thrashing detection: 5 restarts in 15 min triggers 30 min backoff\n- Logs to `logs/watchdog.log`\n- Designed for external scheduling (not a continuous service)\n\n**Note**: The watchdog performs a single check each time it runs. Schedule it externally for continuous monitoring.\n\n## Windows Startup\n\n### Option 1: PowerShell Script (Recommended)\n1. Press Win+R, type `shell:startup`\n2. Create a shortcut to `start_scheduler.ps1 -bg`\n3. Right-click shortcut → Properties → Target:\n   ```\n   powershell.exe -WindowStyle Hidden -ExecutionPolicy Bypass -File \"\\\\mcwcorp\\Departments\\Pathology\\Users\\tcornish\\automation\\scheduler\\start_scheduler.ps1\" -bg\n   ```\n\n### Option 2: Batch File\n1. Press Win+R, type `shell:startup`\n2. Copy `start_scheduler.bat` to the startup folder\n3. Edit batch file to set your Python path\n\n### Option 3: Task Scheduler\nCreate a scheduled task to run `.\\scheduler_ctl.ps1 start` at system startup.\n\n## Log Rotation\n\nAutomatic rotation via RotatingFileHandler:\n\n- Scheduler: 10MB max, 5 backups\n- Watchdog: 5MB max, 3 backups\n- Location: `logs/` directory\n\n## Validation\n\n```powershell\npython validate_jobs.py\n```\n\nAlso runs automatically on scheduler startup.\n\n## Troubleshooting\n\n**Scheduler won't start**: Check `.\\scheduler_ctl.ps1 status` or `python scheduler_ctl.py status`. Delete stale `scheduler.pid` if needed.\n\n**Jobs not running**: Check `logs/scheduler.log`. Validate config with `python validate_jobs.py`.\n\n**Watchdog keeps restarting**: Check both log files for root cause of crashes.\n\n**UNC path errors**: The scheduler now handles UNC paths automatically. If you see \"UNC paths are not supported\" errors, ensure you're using the latest version of `scheduler_core.py`.\n\n**Virtual environment issues**: Use `.\\activate_venv.ps1` to properly activate the venv, or ensure PowerShell execution policy is set with `Set-ExecutionPolicy RemoteSigned -Scope CurrentUser`.\n\n## Platform Support\n\n- **Windows**: Full support with PowerShell and batch scripts\n- **Linux/Mac**: Python scripts work natively (PowerShell scripts are Windows-only)\n- **UNC Paths**: Fully supported on Windows with automatic `pushd`/`popd` handling\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcornish%2Fpython-task-scheduler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcornish%2Fpython-task-scheduler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcornish%2Fpython-task-scheduler/lists"}