---
# System prepended metadata

title: python Apscheduler
tags: [python]

---

# 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'])
    ```