route flask from scheduled function

Question:

I have a Flask app, which is running a web-app to control an alarm. I use apscheduler to trigger a function triggerAlarm() and within that I want to have the logic to actually trigger it, but also I want to have the web-page to display another alarm.html, no matter which site the user is currently on.

The idea is to show the user, that the alarm went off by opening another html page (possibly the main page, which has context dependent text and layout)! Also the page content is outdated after an alarm. The client must reload the page, if the after-alarm info should be displayed/updated.

This is the key problem: in my head it is necessary to redirect every client to the alarm page at this event. Maybe there is a better solution all along. (I don’t want to use JavaScript, since I use 4 languages already besides the 3 I use regularly.)

The problem is, that the function itself has no "route" and is not part of the app (this is what I think happens). Also I cannot easily make it a route, since it is activated not by a html request, but by the scheduler.
How can I trigger a function and redirect to a specified page?

*I tried redirect() and RequestRedirect() w/ and w/o url_for() and return render_template('index.html', **templateData) … but I cannot load the desired page.

The code looks something like this:

from apscheduler.schedulers.background import BackgroundScheduler
# Web Server Gateway WSGI
from flask import Flask, render_template, request, url_for

scheduler = BackgroundScheduler()
scheduler.start()
scheduler.add_job(triggerAlarm,'date',run_date=somedate)

@app.route("/")
def index():
    # prepare templateData
    return render_template('index.html', **templateData)

def triggerAlarm():
    # this doesn't work, since it is called by the scheduler and has no route!
    return redirect(url_for("/")) 
Asked By: mike

||

Answers:

If you have defined a method, “triggerAlarm()”, and want to make it available to a route, then create your route like:

@app.route("/alarm-url")
def web_alarm():
    triggerAlarm()
    return redirect(url_for("/")) 

This will cause the same thing that happens when the scheduler runs triggerAlarm() to happen when a user hits the route /alarm-url, and then return them home.

The takeaway is that you can define methods outside of flask route, in other modules, etc, and then call those methods in a flask route.

Update

If you have to keep triggerAlarm() separate from any routes you could do something like:

class StatusDenied(Exception):
  pass

@app.errorhandler(StatusDenied)
def web_alarm(error):
  return redirect(url_for("/")) 

def triggerAlarm():
  ...
  raise StatusDenied
Answered By: Logan Bertram
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.