Combien de fois tu relances le même script à la main ? Le récap du matin, la sauvegarde du dimanche, la vérification de l'API toutes les quinze minutes. À force, tu finis par oublier, ou par te lever exprès pour appuyer sur Entrée. APScheduler met fin à ce cirque : c'est une bibliothèque Python qui planifie des fonctions comme le ferait cron, mais directement dans ton code, sans toucher au crontab du système.
Le principe est simple. Tu écris une fonction Python normale, tu la confies à un planificateur avec un déclencheur, et il se charge de l'appeler au bon moment : toutes les cinq secondes, chaque lundi à 8 h 30, le premier du mois, ou n'importe quelle combinaison. Dans ce tutoriel, on monte un planificateur de zéro, avec des exemples qui tournent vraiment.
Installe APScheduler
Comme toujours, on travaille dans un environnement virtuel pour ne pas polluer ton système.
python -m venv .venv
source .venv/bin/activate
pip install apschedulerLa bibliothèque s'appelle apscheduler sur PyPI. Aucune dépendance exotique : elle tourne partout où Python 3 tourne.
Ta première tâche, toutes les cinq secondes
Le planificateur le plus simple s'appelle BlockingScheduler. Il prend la main sur le programme et boucle jusqu'à ce que tu l'arrêtes. Ici, on lance une fonction toutes les cinq secondes :
from apscheduler.schedulers.blocking import BlockingScheduler
from datetime import datetime
def bonjour():
print(f"[{datetime.now():%H:%M:%S}] Tâche exécutée")
scheduler = BlockingScheduler()
scheduler.add_job(bonjour, "interval", seconds=5)
scheduler.start()add_job prend trois arguments : la fonction, le type de déclencheur ("interval"), puis ses paramètres. Ici, seconds=5. La boucle bloque le script : pour l'arrêter, un Ctrl+C suffit.
Planifie comme un cron, à l'heure près
Pour du vrai ordonnancement calendaire, on passe à CronTrigger. Même logique qu'un crontab, mais avec des mots clés lisibles : hour, minute, day_of_week, day, month. Exemple : générer un récap chaque jour ouvré à 8 h 30.
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.cron import CronTrigger
def recap_du_matin():
print("Génération du récap du matin")
scheduler = BlockingScheduler()
scheduler.add_job(
recap_du_matin,
CronTrigger(hour=8, minute=30, day_of_week="mon-fri"),
)
scheduler.start()day_of_week="mon-fri" couvre du lundi au vendredi. Tu peux écrire minute="*/10" pour toutes les dix minutes, hour="0,12" pour minuit et midi, ou day="1" pour le premier du mois. Les plages, les listes et les pas se combinent librement.
Un cas réel : surveiller une API en arrière-plan
BlockingScheduler bloque tout, ce qui ne colle pas si ton programme a autre chose à faire. BackgroundScheduler exécute les tâches dans des threads séparés et te rend la main. Cas classique : vérifier qu'une API répond, et alerter dès que ça casse.
import time
import requests
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.interval import IntervalTrigger
def verifier_api():
reponse = requests.get("https://api.exemple.com/status", timeout=10)
if reponse.status_code != 200:
print(f"Alerte : l'API répond {reponse.status_code}")
scheduler = BackgroundScheduler()
scheduler.add_job(verifier_api, IntervalTrigger(minutes=15))
scheduler.start()
# Ton programme continue de tourner ici
try:
while True:
time.sleep(1)
except (KeyboardInterrupt, SystemExit):
scheduler.shutdown()Ici, verifier_api est appelée toutes les quinze minutes pendant que ton script continue de vivre dans sa boucle. Remplace l'URL par la tienne : un endpoint de santé, une file de messages à vider, un dossier à scanner. L'alerte peut être un email, un message Slack ou un simple log.
Survivre au redémarrage avec SQLite
Par défaut, les jobs sont stockés en mémoire : si ton script plante, tout est perdu. Pour que le planning survive à un redémarrage, on branche un job store SQLAlchemy sur un fichier SQLite.
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from apscheduler.executors.pool import ThreadPoolExecutor
from apscheduler.triggers.cron import CronTrigger
def sauvegarde_quotidienne():
print("Sauvegarde lancée")
jobstores = {"default": SQLAlchemyJobStore(url="sqlite:///jobs.sqlite")}
scheduler = BackgroundScheduler(
jobstores=jobstores,
executors={"default": ThreadPoolExecutor(4)},
)
scheduler.add_job(
sauvegarde_quotidienne,
CronTrigger(hour=2, minute=0),
id="sauvegarde",
replace_existing=True,
)
scheduler.start()Une subtilité importante : avec la persistance, il faut une fonction nommée, pas un lambda. APScheduler doit pouvoir retrouver la référence de ta fonction pour la sérialiser, sinon il lève une erreur. L'id et replace_existing=True évitent de dupliquer le job si tu relances le script.
Conclusion
APScheduler, c'est le chaînon qui transforme un script jetable en petit service autonome. Pas de démon à configurer, pas de crontab à maintenir sur chaque machine : la planification vit dans ton code, versionnée avec le reste du projet. Commence par un interval de cinq secondes pour comprendre le mécanisme, puis branche un CronTrigger sur tes vraies tâches. Tu ne lanceras plus jamais rien à la main.
Auteur
Krugz
Développeur fullstack
Développeur fullstack qui tente, tant bien que mal, de suivre l'actualité de l'IA au milieu d'une marée d'informations imbuvables et des milliers d'outils et de modèles qui sortent chaque jour.






