我正在根据API调用在运行时使用APScheduler添加后台任务。换句话说,启动应用程序时没有后台任务。当用户调用API时,任务会在运行时添加。但我收到一条错误消息:
AssertionError:弹出错误的应用上下文
如果我注释掉安排后台任务的行,则该应用程序将正常运行。 我的应用程序结构如下:
/project
manage.py
requirements.txt
/app
/models
/routes
/utils
/api
config.py
__init__.py
我的manage.py
文件如下:
app = create_app('dev')
app.app_context().push()
manager = Manager(app)
migrate = Migrate(app, db, render_as_batch=True)
manager.add_command('db', MigrateCommand)
with app.app_context():
scheduler = BackgroundScheduler()
scheduler.start()
@manager.command
def run():
app.run()
atexit.register(lambda: scheduler.shutdown())
if __name__ == '__main__':
manager.run()
应用程序文件夹中的init .py是:
from flask import Flask
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy
from email_scheduler.routes.routes import set_routes
from .config import config_by_name
# from app.models.task import TaskModel
db = SQLAlchemy()
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config_by_name[config_name])
api = Api(app)
set_routes(api)
from email_scheduler.models.api_models import TaskModel, User
db.init_app(app)
with app.app_context():
db.create_all()
return app
我的api.py文件是:
class SignUp(Resource):
def clean_scheduling_time(self, schedule_time):
day = schedule_time.split(' ')[0].lower()[:3]
hour, mins = schedule_time.split(' ')[1].split(':')
return day, hour, mins
def post(self):
args = user_parser.parse_args()
username, password = args.get('username'), args.get('password')
schedule_time, email_to = args.get('schedule_time'), args.get('email_to')
if username is None or password is None:
abort(400) # missing arguments
from email_scheduler.models.api_models import User
if User.query.filter_by(username=username).first() is not None:
abort(400) # existing user
user = User(username=username, schedule_time=schedule_time.split(' ')[1], email_to=email_to)
user.hash_password(password)
user.save_to_db()
from manage import scheduler
from email_scheduler.utils.utils import send_email
day, hour, mins = self.clean_scheduling_time(args.get('schedule_time'))
trigger = CronTrigger(day_of_week=day, hour=int(hour), minute=int(mins))
scheduler.add_job(send_email, trigger=trigger)
print(scheduler.get_jobs())
return make_response(jsonify({'username': username}), 200)
奇怪的是,即使我在终端上遇到此错误,该任务仍会按计划进行并运行。而且,如果我从用于计划任务的api中取出代码,则该API可以正常运行。我在做什么错了?
答案 0 :(得分:0)
问题出在您的manage.py
文件中。
您正在全局运行以下行:
app.app_context().push()
您正确需要工作人员访问应用上下文。将其移到工作人员调用的函数中。
不是这个吗?
app = create_app()
app.app_context().push()
def your_async_fn():
# your code for the worker...
但这是
def your_async_fn():
app = create_app()
app.app_context().push()
# your code for the worker...