Reference resources:
- https://zhuanlan.zhihu.com/p/95563033
- https://www.cnblogs.com/qq834761298/p/12164717.html
- https://www.cnblogs.com/KdeS/p/13158152.html#autoid-0-6-0
1 Basic concepts
1.1 Basic Components
1.1.1 Trigger triggers
Conditions used to set trigger tasks
Trigger binds to Job, calculates the trigger time of Job based on the trigger's rules when scheduler schedules to filter Job, and then compares with the current time to determine if this Job will be executed, that is, calculates the next execution time based on the trigger's rules.
There are a variety of Triggers, DateTrigger at a specified time, IntervalTrigger at a specified interval, CronTrigger like crontab on Linux.
When dispatching a job, you need to select a triggers for the job to describe when the job is triggered. APScheduler has three built-in trigger types:
- "Date": specify the date at one time;
- How often does "interval" execute at intervals within a time range?
- The "cron" and "Linux crontab" formats are compatible and most powerful.
1.1.2 Job Storage job stores:
Used to store tasks in memory or in a database
If your application recreates jobs every time it starts, you can use the default job storage (MemoryJobStore), but if you need to keep jobs even when the scheduler restarts or the application runs, you should choose specific job storage based on your application environment.
For example, use Mongo or SQLAlchemy JobStore (to support most RDBMS)
1.1.3 Executor executors
For task execution, you can set the execution mode to single-threaded or thread pool
The choice of an executor depends on which framework you use above, and in most cases, using the default ThreadPoolExecutor already works. If your application involves CPU intensive operations, you might consider using ProcessPoolExecutor to use more CPU cores. You can also use both, using ProcessPoolExecutor as the second executor.
1.1.4 Scheduler schedulers:
Run by creating a dispatcher instance with the above three components as parameters
- BlockingScheduler: Blocking Scheduler: A program for a run-only scheduler
- BackgroundScheduler: Background Scheduler: For non-blocking scenarios, the scheduler runs independently in the background
- AsyncIOScheduler: When your program uses asyncio (an asynchronous framework).
- GeventScheduler: When your program uses gevent, a high-performance Python concurrency framework.
- Tornado Scheduler: When your program is based on Tornado, a web framework.
- TwistedScheduler: When your program uses Twisted (an asynchronous framework)
- QtScheduler: If your application is a Qt application, you can use it.
The choice of task store depends on whether the task needs to be persisted.
If you are running a task that is stateless, you can handle it by choosing the default task store, MemoryJobStore.
However, if you need to save the state of a task when the program is shut down or restarted, you need to choose a persistent task store.
Author recommendation Use SQLAlchemyJobStore with PostgreSQL as the background database.
This scheme can provide powerful data integration and protection.
2 Simple examples
2.1 Loop Execution Example
2.1.1 Executes every 5s
#!/usr/bin/python # -*- coding: UTF-8 -*- """ Explain: - Every 5 s Execute once """ import datetime from apscheduler.schedulers.blocking import BlockingScheduler def job1(): print("Doing Job", datetime.datetime.now()) scheduler = BlockingScheduler() scheduler.add_job(job1, "interval", seconds=5, id="job1") # scheduler.add_job(job1, 'cron', minute="/2", id='job1') # Execute every minute # scheduler.add_job(job1, 'interval', hours=1, id='job1') # Execute every hour scheduler.start() >>> Doing Job 2021-07-20 14:40:19.232279 Doing Job 2021-07-20 14:40:24.239411 Doing Job 2021-07-20 14:40:29.237285 Doing Job 2021-07-20 14:40:34.244373 Doing Job 2021-07-20 14:40:39.237203 Doing Job 2021-07-20 14:40:44.245174 Doing Job 2021-07-20 14:40:49.242486
2.1.2 Execute once per minute for a specified period of time
#!/usr/bin/python # -*- coding: UTF-8 -*- """ Explain: - 50 per hour-55,Run every minute """ import datetime from apscheduler.schedulers.blocking import BlockingScheduler scheduler = BlockingScheduler() @scheduler.scheduled_job("cron", minute="50-55") def request_update_status(): print("Doing Job", datetime.datetime.now()) scheduler.start()
2.1.3 Daily scheduled execution
#!/usr/bin/python # -*- coding: UTF-8 -*- """ Explain: - Run once a day at 1:30 a.m. for 50 seconds """ import datetime from apscheduler.schedulers.blocking import BlockingScheduler scheduler = BlockingScheduler() f = open('./task_of_scheduler.txt', 'w', encoding='utf8') @scheduler.scheduled_job("cron", day_of_week="*", hour="1", minute="30", second="30") def check_db(): print("Doing Job, and time:", datetime.datetime.now()) if __name__ == '__main__': try: scheduler.start() f.write("Timed Task Executed Successfully") except Exception as e: scheduler.shutdown() f.write("Timed task execution failed") finally: f.close()
2.1.4 runs every 2 hours, but only on Saturdays and Sundays
#!/usr/bin/python # -*- coding: UTF-8 -*- """ Explain: - Run every 2 hours, but only on Saturdays and Sundays """ from apscheduler.triggers.combining import AndTrigger from apscheduler.triggers.interval import IntervalTrigger from apscheduler.triggers.cron import CronTrigger trigger = AndTrigger([IntervalTrigger(hours=2), CronTrigger(day_of_week='sat,sun')]) scheduler.add_job(job_function, trigger)
3 Example Details
3.1 triggers Use Details
3.1.1 date triggers a task at a specified point in time
#!/usr/bin/python # -*- coding: UTF-8 -*- """ Explain: - # Enforced on July 21, 2021 """ from datetime import date from apscheduler.schedulers.blocking import BlockingScheduler scheduler= BlockingScheduler() def my_job(text): print(text) # Enforced on July 21, 2021 scheduler.add_job(my_job, 'date', run_date=date(2021, 7, 21), args=['text']) scheduler.start()
3.1.2 datetime type (for exact time)
#!/usr/bin/python # -*- coding: UTF-8 -*- """ Explain: - # Enforced on July 21, 2021 """ from datetime import date, datetime from apscheduler.schedulers.blocking import BlockingScheduler scheduler= BlockingScheduler() def my_job(text): print(text, datetime.now()) scheduler.add_job(my_job, 'date', run_date=datetime(2021, 7, 20, 14, 56, 00), args=['Doing Job']) # scheduler.add_job(my_job, 'date', run_date="2021-07-20 14:56:00", args=['Doing Job']) scheduler.start() >>> Doing Job 2021-07-20 14:56:00.013597
3.2 interval cycle trigger task
3.2.1 Triggered every two hours
#!/usr/bin/python # -*- coding: UTF-8 -*- """ Explain: - Trigger every two hours """ from datetime import date, datetime from apscheduler.schedulers.blocking import BlockingScheduler def job_function(): print("Hello World", datetime.now()) schedeler = BlockingScheduler() # Trigger every 2 hours schedeler.add_job(job_function, 'interval', hours=2) schedeler.start()
3.2.2 via scheduled_job() decorator implementation
#!/usr/bin/python # -*- coding: UTF-8 -*- """ Explain: - adopt scheduled_job()Decorator implementation """ import time from apscheduler.schedulers.blocking import BlockingScheduler scheduler = BlockingScheduler() @scheduler.scheduled_job('interval', id='my_job_id', minutes=0.5) def job_function(): print("Hello World", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) scheduler.start() >>> Hello World 2021-07-20 15:06:29 Hello World 2021-07-20 15:06:59
3.3.3 Use start_date and end_date limits the period of time planned to run
#!/usr/bin/python # -*- coding: UTF-8 -*- """ Explain: - Use start_date and end_date Limit the period of time planned to run """ import time from apscheduler.schedulers.blocking import BlockingScheduler scheduler = BlockingScheduler() def job_function(): print("Hello World: ", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) scheduler.add_job(job_function, "interval", minutes=0.5, start_date="2021-07-20 15:10:00", end_date="2021-07-20 15:15:00") scheduler.start() >>> Hello World: 2021-07-20 15:10:00 Hello World: 2021-07-20 15:10:30 Hello World: 2021-07-20 15:11:00 Hello World: 2021-07-20 15:11:30 Hello World: 2021-07-20 15:12:00 Hello World: 2021-07-20 15:12:30 Hello World: 2021-07-20 15:13:00 Hello World: 2021-07-20 15:13:30 Hello World: 2021-07-20 15:14:00 Hello World: 2021-07-20 15:14:30 Hello World: 2021-07-20 15:15:00
3.3 cron class crontab expression
""" When the time parameter is omitted, the parameter is set to before explicitly specifying the parameter*, The parameters are then set to the minimum value. week and day_of_week The minimum value is*. For example: Set up day=1, minute=20 Equivalent to Settings year='*', month='*', day=1, week='*', day_of_week='*', hour='*', minute=20, second=0, It is the first day of each month and triggers when the minute reaches 20. """ # Note the order of parameters class apscheduler.triggers.cron.CronTrigger( year=None, month=None, day=None, week=None, day_of_week=None, hour=None, minute=None, second=None, start_date=None, end_date=None, timezone=None, jitter=None) # Vibration parameters