Avant de demander, Mes tâches et planificateur de tâches seront mes dernières options, ce script sera utilisé sous Windows et Linux et je préférerais avoir une méthode codée de le faire plutôt que de la laisser à la utilisateur final à compléter.
Existe-t-il une bibliothèque pour Python que je peux utiliser pour planifier des tâches? Je devrai exécuter une fonction toutes les heures. Toutefois, si je lance un script toutes les heures et utilise .sleep , "une fois par heure" sera exécuté à une heure différente de la veille en raison du retard inhérent à l’exécution/à l’exécution du script et/ou de la fonction.
Quel est le meilleur moyen de planifier l'exécution d'une fonction à une heure spécifique de la journée (plusieurs fois) sans à l'aide d'un Cron Job ou planification avec Task Scheduler?
Ou si cela n’est pas possible, je voudrais également connaître votre opinion.
import datetime
import time
from apscheduler.scheduler import Scheduler
# Start the scheduler
sched = Scheduler()
sched.daemonic = False
sched.start()
def job_function():
print("Hello World")
print(datetime.datetime.now())
time.sleep(20)
# Schedules job_function to be run once each minute
sched.add_cron_job(job_function, minute='0-59')
en dehors:
>Hello World
>2014-03-28 09:44:00.016.492
>Hello World
>2014-03-28 09:45:00.0.14110
(De la réponse d'Animesh Pandey ci-dessous)
from apscheduler.schedulers.blocking import BlockingScheduler
sched = BlockingScheduler()
@sched.scheduled_job('interval', seconds=10)
def timed_job():
print('This job is run every 10 seconds.')
@sched.scheduled_job('cron', day_of_week='mon-fri', hour=10)
def scheduled_job():
print('This job is run every weekday at 10am.')
sched.configure(options_from_ini_file)
sched.start()
Peut-être que ceci peut aider: Advanced Python Scheduler
Voici un petit morceau de code de leur documentation:
from apscheduler.schedulers.blocking import BlockingScheduler
def some_job():
print "Decorated job"
scheduler = BlockingScheduler()
scheduler.add_job(some_job, 'interval', hours=1)
scheduler.start()
Pour exécuter quelque chose toutes les 10 minutes après l'heure.
from datetime import datetime, timedelta
while 1:
print 'Run something..'
dt = datetime.now() + timedelta(hours=1)
dt = dt.replace(minute=10)
while datetime.now() < dt:
time.sleep(1)
Pour apscheduler
<3.0, voir réponse de l'inconn .
Pour apscheduler
> 3.0
from apscheduler.schedulers.blocking import BlockingScheduler
sched = BlockingScheduler()
@sched.scheduled_job('interval', seconds=10)
def timed_job():
print('This job is run every 10 seconds.')
@sched.scheduled_job('cron', day_of_week='mon-fri', hour=10)
def scheduled_job():
print('This job is run every weekday at 10am.')
sched.configure(options_from_ini_file)
sched.start()
apscheduler
documentation .
Ceci pour apscheduler-3.3.1
sur Python 3.6.2
.
"""
Following configurations are set for the scheduler:
- a MongoDBJobStore named “mongo”
- an SQLAlchemyJobStore named “default” (using SQLite)
- a ThreadPoolExecutor named “default”, with a worker count of 20
- a ProcessPoolExecutor named “processpool”, with a worker count of 5
- UTC as the scheduler’s timezone
- coalescing turned off for new jobs by default
- a default maximum instance limit of 3 for new jobs
"""
from pytz import utc
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from apscheduler.executors.pool import ProcessPoolExecutor
"""
Method 1:
"""
jobstores = {
'mongo': {'type': 'mongodb'},
'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite')
}
executors = {
'default': {'type': 'threadpool', 'max_workers': 20},
'processpool': ProcessPoolExecutor(max_workers=5)
}
job_defaults = {
'coalesce': False,
'max_instances': 3
}
"""
Method 2 (ini format):
"""
gconfig = {
'apscheduler.jobstores.mongo': {
'type': 'mongodb'
},
'apscheduler.jobstores.default': {
'type': 'sqlalchemy',
'url': 'sqlite:///jobs.sqlite'
},
'apscheduler.executors.default': {
'class': 'apscheduler.executors.pool:ThreadPoolExecutor',
'max_workers': '20'
},
'apscheduler.executors.processpool': {
'type': 'processpool',
'max_workers': '5'
},
'apscheduler.job_defaults.coalesce': 'false',
'apscheduler.job_defaults.max_instances': '3',
'apscheduler.timezone': 'UTC',
}
sched_method1 = BlockingScheduler() # uses overrides from Method1
sched_method2 = BlockingScheduler() # uses same overrides from Method2 but in an ini format
@sched_method1.scheduled_job('interval', seconds=10)
def timed_job():
print('This job is run every 10 seconds.')
@sched_method2.scheduled_job('cron', day_of_week='mon-fri', hour=10)
def scheduled_job():
print('This job is run every weekday at 10am.')
sched_method1.configure(jobstores=jobstores, executors=executors, job_defaults=job_defaults, timezone=utc)
sched_method1.start()
sched_method2.configure(gconfig=gconfig)
sched_method2.start()
Sur la version publiée par sunshinekitty appelée "Version <3.0", vous devrez peut-être spécifier apscheduler 2.1.2. J'avais accidentellement eu la version 3 sur mon installation 2.7, alors je suis allé:
pip uninstall apscheduler
pip install apscheduler==2.1.2
Cela a fonctionné correctement après cela. J'espère que ça t'as aidé.
Une option consiste à écrire un wrapper C/C++ qui exécute régulièrement le script python. Votre utilisateur final lancera l’exécutable C/C++, qui restera exécuté en arrière-plan, et exécutez périodiquement le script python. Ce n'est peut-être pas la meilleure solution et peut ne pas fonctionner si vous ne connaissez pas C/C++ ou si vous ne souhaitez pas conserver ce code 100% python. L'approche la plus conviviale, car les utilisateurs sont habitués à cliquer sur les exécutables. Tout cela suppose que python est installé sur l'ordinateur de l'utilisateur final.
Une autre option consiste à utiliser le planificateur de tâches/tâches cron, mais à le placer dans l'installateur en tant que script afin que l'utilisateur final ne l'ait pas obligé.
#For scheduling task execution
import schedule
import time
def job():
print("I'm working...")
schedule.every(1).minutes.do(job)
#schedule.every().hour.do(job)
#schedule.every().day.at("10:30").do(job)
#schedule.every(5).to(10).minutes.do(job)
#schedule.every().monday.do(job)
#schedule.every().wednesday.at("13:15").do(job)
#schedule.every().minute.at(":17").do(job)
while True:
schedule.run_pending()
time.sleep(1)