J'ai un hébergement Web Flask sans accès à la cron
commande.
Comment puis-je exécuter une fonction Python toutes les heures?
Vous pouvez utiliser à BackgroundScheduler()
partir du package APScheduler (v3.5.3):
import time
import atexit
from apscheduler.schedulers.background import BackgroundScheduler
def print_date_time():
print(time.strftime("%A, %d. %B %Y %I:%M:%S %p"))
scheduler = BackgroundScheduler()
scheduler.add_job(func=print_date_time, trigger="interval", seconds=3)
scheduler.start()
# Shut down the scheduler when exiting the app
atexit.register(lambda: scheduler.shutdown())
Notez que deux de ces planificateurs seront lancés lorsque Flask est en mode débogage. Pour plus d'informations, consultez cette question.
flask
aviez unApp.runonce
ouApp.runForNseconds
vous pouviez basculer entreschedule
et le coureur de flacon, mais ce n'est pas le cas, donc le seul moyen pour le moment est de l'utiliserVous pouvez utiliser
APScheduler
dans votre application Flask et exécuter vos tâches via son interface:la source
lambda
intérieuratexit.register
?atexit.register
besoin d'une fonction à appeler. Si nous venons de passer,cron.shutdown(wait=False)
nous passerons le résultat de l'appelcron.shutdown
(ce qui est probablementNone
). Donc, au lieu de cela, nous passons une fonction à zéro argument, et au lieu de lui donner un nom et d'utiliser une instructiondef shutdown(): cron.shutdown(wait=False)
,atexit.register(shutdown)
nous l'enregistrons à la place en ligne aveclambda:
(qui est une expression de fonction à zéro argument .)Je suis un peu nouveau avec le concept des planificateurs d'applications, mais ce que j'ai trouvé ici pour APScheduler v3.3.1 , c'est quelque chose d'un peu différent. Je crois que pour les dernières versions, la structure du package, les noms de classe, etc., ont changé, donc je mets ici une nouvelle solution que j'ai faite récemment, intégrée à une application Flask de base:
Je laisse également ce Gist ici , si quelqu'un est intéressé par les mises à jour de cet exemple.
Voici quelques références, pour de futures lectures:
la source
apscheduler.schedulers.background
, car il est possible que vous puissiez rencontrer d'autres scénarios utiles pour votre application. Cordialement.Vous pouvez essayer d'utiliser BackgroundScheduler d'APScheduler pour intégrer le travail d'intervalle dans votre application Flask. Voici l'exemple qui utilise le plan directeur et la fabrique d'applications ( init .py):
J'espère que ça aide :)
Réf:
la source
Pour une solution simple, vous pouvez ajouter un itinéraire tel que
Ensuite, ajoutez une tâche cron unix qui POST périodiquement sur ce point de terminaison. Par exemple pour l'exécuter une fois par minute, en type de terminal
crontab -e
et ajoutez cette ligne:(Notez que le chemin d'accès à curl doit être complet, car lorsque le travail s'exécute, il n'aura pas votre PATH. Vous pouvez trouver le chemin complet de curl sur votre système en
which curl
)J'aime cela dans la mesure où il est facile de tester le travail manuellement, il n'a pas de dépendances supplémentaires et comme il n'y a rien de spécial, il est facile à comprendre.
Sécurité
Si vous souhaitez protéger par mot de passe votre tâche cron, vous pouvez
pip install Flask-BasicAuth
, puis ajouter les informations d'identification à la configuration de votre application:Pour protéger par mot de passe le point de terminaison du travail:
Ensuite, pour l'appeler depuis votre tâche cron:
la source
Une autre alternative pourrait être d'utiliser Flask-APScheduler qui joue bien avec Flask, par exemple:
Plus d'informations ici:
https://pypi.python.org/pypi/Flask-APScheduler
la source
Un exemple complet utilisant la planification et le multitraitement, avec un contrôle marche / arrêt et un paramètre à run_job (), les codes de retour sont simplifiés et l'intervalle est défini sur 10 s, changez
every(2).hour.do()
pour 2 heures. Le calendrier est assez impressionnant, il ne dérive pas et je ne l'ai jamais vu à plus de 100 ms de décalage lors de la planification. Utilisation du multitraitement au lieu du threading car il a une méthode de terminaison.Vous testez cela en émettant simplement:
Toutes les 10 secondes, le minuteur est activé, il émettra un message de minuterie à la console:
la source
Vous voudrez peut-être utiliser un mécanisme de file d'attente avec un planificateur comme le planificateur RQ ou quelque chose de plus lourd comme Celery (très probablement un surpuissance).
la source