Forums

Using Flask APScheduler with PythonAnywhere

Hi! I've been building 2 web apps and I suddenly require scheduling tasks from a SQLDatabase. Adding, editing and deleting has been no issue, but now after installing Advanced Python Scheduler and it's Flask extension, I'm at odds in how to make it run.

1) Installed using pip install --user Flask-APScheduler

2) Created a jobs file using the examples as basis:

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

    SCHEDULER_API_ENABLED = True


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


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

    scheduler = APScheduler()
    # it is also possible to enable the API directly
    # scheduler.api_enabled = True
    scheduler.init_app(app)
    scheduler.start()

    app.run()

But I'm stuck in how to implement the last part of scheduler.init_app(app) and app.run() given that PythonAnywhere's configuration of Flask Server is different.

I tried adding this code into WSGI file and got the The scheduler seems to be running under uWSGI, but threads have been disabled. You must run uWSGI with the --enable-threads option for the scheduler to work..

From what I read in other threads, PythonAnywhere doesn't allow threading or Celery. So I wanted to ask if there's any way I can get this running. Given that my applications forcibly need to allow scheduling and triggering alerts when a given date/time occurs, this is a dealbreaker for me.

Also read that I can make use of the Task tab in the Dashboard to schedule them. But does it allow to programatically schedule the events? I can't manually do it because the point of the apps are to check periodically for the scheduled date and times close to be due and then perform actions (sending emails., triggering alerts on the frontend, etc.).

Or is there an easier way to check events scheduled in SQLAlchemy and trigger actions when the date of the events occur?

Thanks in advance for the help!

APScheduler definitely sounds like it won't work from our flask webapp.

On the PythonAnywhere task page, you can certainly have a task that is running in a loop, and constantly checking if there are any MySQL events that are ready to be triggered. That would probably be the best way.

If you want, we can add you to our new beta feature to have "always on tasks"- that may potentially solve your issue.

Thanks a lot for the answer conrad! Will check if it's doable to do it from the Tasks page. Since I don't need them to be always on or to trigger every minute, it may be useful. Just didn't know it gave access to the other functions.

Also it's great news that there's that feature in progress. It will be very useful in future projects.

Thanks once again! Will update once I get it working.

any updates on how to get ap scheduler working?

With a paid account you could run it as an always-on task; from a free account I don't think it would work.

I have a paid account, and try to use apschedule in always-on-tasks:

my coding as follows: scheduler = BackgroundScheduler() # Create Scheduler scheduler.configure(timezone=pytz.timezone('America/New_York')) scheduler.add_job(get_stock_data, "cron", hour="9-5", minute = "*") scheduler.start() # Start Scheduler

But it seems cannot start the scheduler. Any suggestion or material I can walk through to use any kind of scheduler in pythonanywhere. Thx.

"josonhui" is not a paid account. Do you use other account? What error do you get?

Hi, I use josonlchui paid account to ask this question again.

I did not receive any error msg. but it seems cannot run the scheduler.add_job. I try to test with the following print program, nothing printout. Any suggestion?

def testing():
    print("this is a testing")


# add scheduer start

scheduler = BackgroundScheduler() # Create Scheduler
scheduler.configure(timezone=pytz.timezone('America/New_York'))

scheduler.add_job(testing, "interval", minutes=1) # Add job to scheduler
# scheduler.add_job(testing, "cron", hour="0-23", minute = "*")

scheduler.start() # Start Scheduler
print("US Eastern timezone DateTime 2:", dt_us_eastern.strftime("%Y:%m:%d %H:%M:%S %Z %z"))

# end scheduer start

Try adding flush=True to the print call, otherwise the messages will be buffered and thus shown with significant delay.

Thanks. I rewrite the code and it works. Just for sharing to someone like me doesnt know how to use apsheduler in pythonanywhere☺️

from apscheduler.schedulers.blocking import BlockingScheduler

sched = BlockingScheduler()
@sched.scheduled_job("cron", hour="0-23", minute = "*")
def timed_job():
    print('This is a testing')
sched.start()

And now the print is working?