Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using flask_apscheduler with gunicorn

I am trying to schedule tasks within my flask app to fire now and then... this works great with flask development server, but once I fire the same app with gunicorn it is not working as intended, no errors, but no tasks are being fired..

from flask import Flask
from flask_apscheduler import APScheduler


class Config(object):
    JOBS = [
        {
            'id': 'job1',
            'func': 'myapp:job1',
            'args': (1, 2),
            'trigger': 'interval',
            'seconds': 5
            }
    ]

    SCHEDULER_API_ENABLED = True


def job1(a, b):
    print(str(a) + ' ' + str(b))

app = Flask(__name__)

if __name__ == '__main__':
    app.config.from_object(Config())

    scheduler = APScheduler()
    scheduler.init_app(app)
    scheduler.start()

    app.run()

For the purpose I include this sample, python myapp.py works fine and prints 1 2 every fifth second, however, running gunicorn -w 1 -b 0.0.0.0:5000 myapp:app it is not printing 1 2 every fifth second, why?

like image 228
Draco Malfago Avatar asked Mar 09 '23 20:03

Draco Malfago


1 Answers

so, 2 things

1) use logging, you get a LOT more info:

2) you need to declare outside your if __name__=='__main__': block:

  1 from flask import Flask
  2 from flask_apscheduler import APScheduler
  3 import logging
  4
  5 logging.basicConfig(level=logging.DEBUG,
  6                     format='%(asctime)s %(levelname)s %(message)s')
  7
  8 logger = logging.getLogger(__name__)
  9
 10 class Config(object):
 11     JOBS = [
 12         {
 13             'id': 'job1',
 14             'func': 'scratch:job1',
 15             'args': (1, 2),
 16             'trigger': 'interval',
 17             'seconds': 5
 18             }
 19     ]
 20
 21     SCHEDULER_API_ENABLED = True
 22
 23
 24 def job1(a, b):
 25     logger.info(str(a) + ' ' + str(b))
 26
 27 app = Flask(__name__)
 28 app.config.from_object(Config())
 29
 30 scheduler = APScheduler()
 31 scheduler.init_app(app)
 32 scheduler.start()
 33
 34
 35 if __name__ == '__main__':
 36         app.run()
~
~

output:

[2017-02-15 14:29:39 +0000] [25122] [INFO] Booting worker with pid: 25122
2017-02-15 14:29:39,817 INFO Adding job tentatively -- it will be properly scheduled when the scheduler starts
2017-02-15 14:29:39,819 INFO Added job "job1" to job store "default"
2017-02-15 14:29:39,819 INFO Scheduler started
2017-02-15 14:29:39,820 DEBUG Looking for jobs to run
2017-02-15 14:29:39,820 DEBUG Next wakeup is due at 2017-02-15 14:29:44.816072-05:00 (in 4.995362 seconds)
2017-02-15 14:29:44,816 DEBUG Looking for jobs to run
2017-02-15 14:29:44,817 INFO Running job "job1 (trigger: interval[0:00:05], next run at: 2017-02-15 14:29:44 EST)" (scheduled at 2017-02-15 14:29:44.816072-05:00)
2017-02-15 14:29:44,817 INFO 1 2

The issue:

The job didn't fire originally. The issue was that your scheduler definition (was inside of your block if __name__ == '__main__' This code only gets hit when you call that python file directly (python myapp.py)

When you launched it with Gunicorn, the __name__ was no longer main, it was "myapp.py" so it never got to the part of the code that created and added the scheduler :)

like image 84
Kelvin Avatar answered Mar 12 '23 10:03

Kelvin