# python APScheduler --排程、定時任務
Advanced Python Scheduler (APScheduler)可排程 Python程式碼稍後執行,可以只執行一次或定期執行。
## 安裝
```
pip install apscheduler
```
## 範例
### 基本
```
from apscheduler.schedulers.blocking import BlockingScheduler
from datetime import datetime
def job1():
print('job1:{}'.format(datetime.now()))
def job2():
print('job2:{}'.format(datetime.now()))
scheduler = BlockingScheduler()
# 每分執行job1
scheduler.add_job(job1, 'interval', minutes=1)
# 每3秒執行job2
scheduler.add_job(job2, 'interval', seconds=3)
scheduler.start()
```
### 傳遞參數
傳送參數給job可以使用args或是kwargs
- args: 列表(List)
- kwargs: 字典(Dictionary)
```
from apscheduler.schedulers.blocking import BlockingScheduler
from datetime import datetime
def job(s):
print('job{}:{}'.format(s,datetime.now()))
scheduler = BlockingScheduler()
# 每分執行job1
scheduler.add_job(job, 'interval', minutes=1, args=['1'])
# 每3秒執行job2
scheduler.add_job(job, 'interval', seconds=3, kwargs={'s': '2'})
scheduler.start()
```
## 說明
### 阻塞式/非阻塞式
- 阻塞式 BlockingScheduler
最基本的調度器,start後就會阻塞,後面程式不會執行
- 非阻塞式 BackgroundScheduler
啟動後程式會繼續執行,所以要確保讓程式持續執行,不然排程就會結束
```
from apscheduler.schedulers.background import BackgroundScheduler
from datetime import datetime
import time
def job(s):
print('job{}:{}'.format(s,datetime.now()))
scheduler = BackgroundScheduler()
# 每分執行job1
scheduler.add_job(job, 'interval', minutes=1, args=['1'])
# 每3秒執行job2
scheduler.add_job(job, 'interval', seconds=3, kwargs={'s': '2'})
scheduler.start()
while True:
time.sleep(60)
```
### Interval/Cron/Date
用於`add_job`中,可分為兩種模式,第一種interval,多久執行一次;另一種crontab,甚麼時間執行。
- interval([參考連結](https://apscheduler.readthedocs.io/en/3.x/modules/triggers/interval.html))
此方法排程作業會依照選定的時間間隔定期執行
| 參數 | 說明 |
| -------- | -------- |
| weeks | 每隔幾週 |
| days | 每隔幾天 |
| hours | 每隔幾小時 |
| minutes | 每隔幾分鐘 |
| seconds | 每隔幾秒 |
| start_date | 間隔計算的起點 |
| end_date | 最晚可能觸發的日期/時間 |
| timezone | 用於日期/時間計算的時區 |
| jitter | 最多延遲作業執行幾秒 |
- cron([參考連結](https://apscheduler.readthedocs.io/en/3.x/modules/triggers/cron.html))
當前時間與指定的時間限制符合時觸發
| 參數 | 說明 |
| -------- | -------- |
| year | 4 位數年份 |
| month | 月 (1-12) |
| day | 一個月中的某一天 (1-31) |
| week | ISO 週 (1-53) |
| day_of_week | 工作日的數字或名稱(0-6 或mon,tue,wed,thu,fri,sat,sun) |
| hour | 小時 (0-23) |
| minute | 分鐘 (0-59) |
| second | 秒鐘 (0-59) |
| start_date | 最早可能觸發的日期/時間(包含 ) |
| end_date | 最晚可能觸發的日期/時間(包含 ) |
| timezone | 用於日期/時間計算的時區(預設為調度程序時區)|
| jitter | 最多延遲作業執行幾秒 |
```
# job_function會於6,7,8,11,12月的第3個星期五的00:00, 01:00, 02:00, 03:00執行
scheduler.add_job(job_function, 'cron', month='6-8,11-12', day='3rd fri', hour='0-3'))
# job_function每日1點1分執行
scheduler.add_job(job_function, 'cron', day_of_week='0-6', hour=1, minute=1)
```
- date([參考連結](https://apscheduler.readthedocs.io/en/3.x/modules/triggers/date.html))
設定的時間觸發一次
| 參數 | 說明 |
| -------- | -------- |
| run_date | 執行作業的日期/時間 |
| timezone | 時區 |
```
# 任務於2024-2-23執行
scheduler.add_job(job, 'date', run_date=date(2024, 2, 23), args=['text'])
```