How can I get a python cron like scheduler in Python?
I’m looking for a library in Python that provides functionality similar to cron and at. I’d prefer a pure Python solution instead of relying on tools installed on the system, as I want it to work on machines that don’t have cron installed.
For those who aren’t familiar with cron, it allows you to schedule tasks based on a time expression like:
0 2 * * 7 /usr/bin/run-backup # run backups at 2:00 AM every Sunday
0 9-17/2 * * 1-5 /usr/bin/purge-temps # run the purge temps command every 2 hours between 9 AM and 5 PM, Monday to Friday.
The exact cron time expression syntax isn’t as important to me, but I would like something with that kind of flexibility.
If there’s no direct solution available, I’d appreciate any suggestions on the building blocks I could use to create something like this.
Additionally, I’m not looking to launch processes; I just need to schedule Python jobs (functions). While this would likely require a different thread, it doesn’t need to be a separate process.
I’m seeking a Python solution that offers the expressiveness of cron time expressions while being as portable as possible.
Hey @Punamhans
Using the schedule Library
The schedule
library provides a simple and flexible way to schedule Python functions without relying on external tools. While it doesn’t directly support cron-like syntax, you can schedule tasks with intervals, specific times, or at regular intervals.
import schedule
import time
def job():
print("Running scheduled job")
# Schedule job every Sunday at 2:00 AM
schedule.every().sunday.at("02:00").do(job)
# Schedule job every 2 hours between 9 AM and 5 PM from Monday to Friday
for hour in range(9, 18, 2):
schedule.every().monday.at(f"{hour}:00").do(job)
schedule.every().tuesday.at(f"{hour}:00").do(job)
schedule.every().wednesday.at(f"{hour}:00").do(job)
schedule.every().thursday.at(f"{hour}:00").do(job)
schedule.every().friday.at(f"{hour}:00").do(job)
while True:
schedule.run_pending()
time.sleep(1)
It’s lightweight and straightforward, but keep in mind it doesn’t directly support cron-like syntax."
That’s a great introduction, @charity-majors! If you want to take it a step further, APScheduler offers more flexibility and directly supports cron-like syntax, which can simplify complex schedules. Here’s an example:
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
def job():
print("Running scheduled job")
# Create scheduler
scheduler = BackgroundScheduler()
# Schedule job with cron-like expression
scheduler.add_job(job, CronTrigger(hour=2, day_of_week='sun')) # Every Sunday at 2:00 AM
scheduler.add_job(job, CronTrigger(hour='9-17/2', day_of_week='mon-fri')) # Every 2 hours from 9 AM to 5 PM on weekdays
# Start the scheduler
scheduler.start()
# Keep the script running
while True:
pass
With APScheduler, you get support for cron expressions, background task execution, and a range of other scheduling options. It’s a bit heavier than schedule
but offers much more power for complex scheduling needs.
Both approaches are excellent! However, if you’re working on a system where cron is already in place and you need to manage jobs directly from Python, python-crontab is another fantastic option. It allows you to programmatically interact with your system’s crontab file:
from crontab import CronTab
def add_job():
cron = CronTab(user=True)
# Create a cron job for running a Python function
job = cron.new(command='python3 /path/to/your/script.py')
# Schedule job every Sunday at 2:00 AM
job.setall('0 2 * * 7')
# Schedule job every 2 hours between 9 AM and 5 PM, Monday to Friday
for hour in range(9, 18, 2):
job = cron.new(command='python3 /path/to/your/script.py')
job.setall(f'0 {hour} * * 1-5')
cron.write()
add_job()
This approach directly writes cron jobs to the system, which ensures they’ll run independently of the Python process. Just make sure cron
is installed and properly configured on your system!