0

I am building an APIs with Flask and I need to check for skipped and send them mail for skipping automatically, but with my approach Server won't start, I need to check for skipped with APIs running, without while I can access all the routes but with while the server is not even starting. is there any way to do that? thanks in advance

def check_skipped():
    users = User.query.all()
    for user in users:
        if user.skipped == 3:
            msg = Message("Skipped 3 times", sender="admin@Kill3r.tech", recipients=user.email)
            msg.body = 'Open app and verify now'
            mail.send(msg)

schedule.every(10).seconds.do(check_skipped)

while 1:
    schedule.run_pending()
    time.sleep(1)

@app.route('/user', methods=['GET'])
@token_required
def get_all_users(current_user):
Ankur
  • 23
  • 7
  • 1
    Use [threading.Timer](https://docs.python.org/3/library/threading.html). – Jared Smith May 24 '20 at 12:31
  • @JaredSmith I need to check for expiration date for users and send them email accordingly, I am not sure Threading is a good choice for this, any else choices I have? Thanks for response – Ankur May 25 '20 at 09:43
  • What I don't understand is why this has to be part of your flask server *at all*. This seems like the kind of job you'd have running separately from your webserver (and ideally not even on the same box). Put a python script that does it in cron/systemd timer file and monitor it with your monitoring software of choice. – Jared Smith May 25 '20 at 12:20

2 Answers2

1

Firstly I am assuming you actually start the server somewhere, but your issue is the while loop, the while loop is always running when you start it, to the moment the program stops, this means. If you go through the program how a computer does (in order from top to bottom) you will see your routes get created after the while loops end, but in your case as soon as the while loop ends so does the program meaning you can't access these routes. You should look at the threading standard library so you can use multiple threads at the same time, one for emails, and one for the website.

Or you could put them into separate files. But I think you need to step back a bit and look a bit more into python to learn a bit about while loops.

So in short

Your while loop starts, runs until the program is killed, then thats it. Your routes never get created.

To stop this either use multiple threads, or put them into separate files. But never have a while loop before you necessary code for your website.

tygzy
  • 698
  • 1
  • 6
  • 23
0

You can't place the while loop between your routes like that, it freezes the program because it has no condition to stop. Maybe take a look at this answer

Using that answer, I think you could replace your while loop with this.

from apscheduler.schedulers.background import BackgroundScheduler

scheduler = BackgroundScheduler()
scheduler.add_job(func=check_skipped, trigger="interval", seconds=10)
scheduler.start()

I don't think it'll freeze the program, but I'm not sure. Also, I don't know many flask conventions yet so I wouldn't know where would be the best place to put this, I think it would be fine to place it somewhere after declaring your routes.

edit: I realise I'm not sure what your schedule instance is. If it is some custom class you can use
scheduler.add_job(func=schedule.run_pending, trigger="interval", seconds=10)

Queuebee
  • 651
  • 1
  • 6
  • 24