Search code examples
pythoncronscheduled-tasks

Schedule the execution of a Python function


I'm building a web app where I have a calendar where users can choose a day and an hour in the future and schedule tasks. The scheduled task is a simple function in python to be called on the exact date and time the user has chosen to.

I came across the schedule package but I rapidly understood that it wasn't suitable for my goal as they explicitly stated that it shouldn't be used if you need job persistence and localization, which I definitely need.

Because of my need, I think I'll need to use some sort of OS cron such as the crontab on Linux. The issue is that I do not need to have my function execute every given time interval but only at a given time chosen by the user.

Is there any other solution than crontab? I've seen the python-crontab package but it seems able to execute commands and not really function directly on a Python file.

Any thoughts?

PS I'm using Django and I've already seen the django-crontab package but it seems too static to me as I need to have dynamic cron jobs to add/remove


Solution

  • So, in the end, my solution was to use python-crontab as below:

    python_exec_command = 'python ' + __file__ + ' ' + playlist_id + ' ' + username
        python_folder = str(Path(__file__).resolve().parent.parent) + '/venv/bin/'
        command = 'source ' + python_folder + 'activate && ' + python_exec_command + ' && deactivate'
        cron = CronTab(user='nicola')
        job = cron.new(command=command, comment=playlist_id)
        job.minute.on(minute)
        job.hour.on(hour)
        job.month.on(month)
        job.day.on(day)
        cron.write()
    

    which will launch the following script

    def main(playlist_id, username):
        # run the actual update
        cron = CronTab(user='nicola')
        cron.remove_all(command=playlist_id)
        cron.write()
        pass
    
    
    if __name__ == "__main__":
        playlist_id = sys.argv[1]
        username = sys.argv[2]
        main(playlist_id, username)
    

    so in this way I'm able to use parameters and delete the cron once executed checking for the unique id as a comment