'APScheduler RuntimeError: No application found

I have a problem. I have IP addresses and with APScheduler I try to ping them every 10 seconds and update my database. For APScheduler I understand that I need to use with app.app_context() but the problem is that I don't know where to place it and wherever I have tried to place it, it raise: RuntimeError: No application found and fails to update the database

init.py:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from os import path

db = SQLAlchemy()
DB_NAME = "database.db"

def create_app():
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'hjshjhdjah kjshkjdhjs'
    app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'

    db.init_app(app)
    
    from .views import views
    from .auth import auth

    app.register_blueprint(views, url_prefix='/')
    app.register_blueprint(auth, url_prefix='/')

    from .models import Servers

    create_database(app)

    return app

def create_database(app):
    if not path.exists('websiteflaskupdatedd/' + DB_NAME):
        db.create_all(app=app)
        print('Created Database!')

auth.py:

from flask import Blueprint, render_template, request, flash, redirect, url_for, escape, session
from .models import Servers, ping
from . import db, create_app
from apscheduler.schedulers.background import BackgroundScheduler

@auth.route('/servers', methods = ['POST', 'GET'])
def servers():
    if request.method == 'POST':
        server_ip = request.form.get("server_ip")

        new_server = Servers(server_ip = server_ip)

        try:
            db.session.add(new_server)
            db.session.commit()
            return redirect("/servers")

        except:
            return "There was an error adding your server"

    else:
        if not Servers.query.get(1) == None:
            servers = Servers.query.order_by(Servers.date_created)
            return render_template('servers.html', servers=servers)


def update_up_status():
    with create_app().app_context():
        server_status_column = Servers.query.filter(Servers.server_status.in_(["0","1"]))
        for server in server_status_column:
            server.server_status = ping(server.server_ip)
        
    db.session.commit()
    
scheduler = BackgroundScheduler()

if not scheduler.running:
    scheduler.add_job(func=update_up_status, trigger="interval", seconds=10)
    scheduler.start()

models.py:

from . import db
from datetime import datetime
import platform    
import subprocess

def ping(host):

    cmd = ['ping', '-w', "1", "-n", '1', host]
    
    return subprocess.call(cmd) == 0

class Servers(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    server_ip = db.Column(db.String(12), nullable=False, unique=True)
    server_status = db.Column(db.String(12), nullable=False)
    date_created = db.Column(db.DateTime, default= datetime.now)


Solution 1:[1]

Looks like you don't have your application running.

I use this setup regularly (flask + apscheduler) and have a main.py file with the following (including the necessary module imports from your other files):

if __name__ == "__main__":

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

    scheduler.start()

    app.run(host="0.0.0.0", debug=True)

The background scheduler works within the background of another application and will not be blocked by the main thread which in this case is the flask application. As opposed to the blocking scheduler which will block the main thread and cannot be run inside of a another application.

Solution 2:[2]

Just like this.

def insertArticles(articles):
    from app import db
    from app.models.articles import Article
    from app import scheduler
    # ?? flask apscheduler RuntimeError: No application found
    with scheduler.app.app_context():
        for article in articles:
            # ?? ?????????
            new_article = Article(**article)
            db.session.add(new_article)
            db.session.flush()
            db.session.commit()

with scheduler.app.app_context() is the important line.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2