falsk 使用celery后台执行任务
Posted wodeboke-y
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了falsk 使用celery后台执行任务相关的知识,希望对你有一定的参考价值。
# falsk 使用celery后台执行任务
1.基础环境搭建
doc:https://flask.palletsprojects.com/en/1.0.x/patterns/celery/
mkdir celery_tasks
init.py # 实例化celery
from celery import Celery # celery my_celery = Celery(‘my_celery‘)
task_1.py # celery任务
from celery_tasks import my_celery @my_celery.task def add_together(a, b): #print(‘add_together执行中。。。‘) return a + b
app.__init__ # celery实例配置
from .app import create_app, db
from .app import create_app, db
flask_app = create_app()
from celery_tasks import my_celery
from .app import _handle_celery_task
_handle_celery_task(flask_app, my_celery)
配置方法位于app.app.py
def _handle_celery_task(app, my_celery): # celery my_celery.conf[‘broker_url‘] = ‘redis://:123@192.168.199.113:6379/0‘ my_celery.conf[‘result_backend‘] = ‘redis://:123@192.168.199.113:6379/0‘ my_celery.conf[‘imports‘] = [‘celery_tasks.tasks_1‘] from celery.task import Task class ContextTask(Task): def on_success(self, retval, task_id, args, kwargs): print(‘task done: {0}‘.format(retval)) return super(ContextTask, self).on_success(retval, task_id, args, kwargs) def on_failure(self, exc, task_id, args, kwargs, einfo): print(‘task fail, reason: {0}‘.format(exc)) return super(ContextTask, self).on_failure(exc, task_id, args, kwargs, einfo) def __call__(self, *args, **kwargs): print(‘应用名:‘, app.name) with app.app_context(): print(app.route) return self.run(*args, **kwargs) my_celery.Task = ContextTask
2.带状态更新的后台任务
task
@celery.task(bind=True) def long_task(self): """Background task that runs a long function with progress reports.""" verb = [‘Starting up‘, ‘Booting‘, ‘Repairing‘, ‘Loading‘, ‘Checking‘] adjective = [‘master‘, ‘radiant‘, ‘silent‘, ‘harmonic‘, ‘fast‘] noun = [‘solar array‘, ‘particle reshaper‘, ‘cosmic ray‘, ‘orbiter‘, ‘bit‘] message = ‘‘ total = random.randint(10, 50) for i in range(total): if not message or random.random() < 0.25: message = ‘{0} {1} {2}...‘.format(random.choice(verb), random.choice(adjective), random.choice(noun)) self.update_state(state=‘PROGRESS‘, meta={‘current‘: i, ‘total‘: total, ‘status‘: message}) time.sleep(1) return {‘current‘: 100, ‘total‘: 100, ‘status‘: ‘Task completed!‘, ‘result‘: 42}
route
@app.route(‘/celery_1‘, methods=[‘GET‘, ‘POST‘]) def celery_1(): if request.method == ‘GET‘: return render_template(‘celery_t.html‘) @app.route(‘/longtask‘, methods=[‘POST‘]) def longtask(): task = long_task.apply_async() return jsonify({}), 202, {‘Location‘: url_for(‘taskstatus‘, task_id=task.id)} @app.route(‘/status/‘) def taskstatus(task_id): task = long_task.AsyncResult(task_id) if task.state == ‘PENDING‘: # job did not start yet response = { ‘state‘: task.state, ‘current‘: 0, ‘total‘: 1, ‘status‘: ‘Pending...‘ } elif task.state != ‘FAILURE‘: response = { ‘state‘: task.state, ‘current‘: task.info.get(‘current‘, 0), ‘total‘: task.info.get(‘total‘, 1), ‘status‘: task.info.get(‘status‘, ‘‘) } if ‘result‘ in task.info: response[‘result‘] = task.info[‘result‘] else: # something went wrong in the background job response = { ‘state‘: task.state, ‘current‘: 1, ‘total‘: 1, ‘status‘: str(task.info), # this is the exception raised } return jsonify(response)
celery_1.html
代码段太长,也不是本文重点,链接地址:
https://github.com/miguelgrinberg/flask-celery-example
简单来说就是通过ajax不停访问/status/
3.运行
(venv) >celery -A app worker -l info -P eventlet
--logfile=c.log
需要注意的是命令中所指向的模块一定要是配置后的Celery实例所在,否则会得到一个空注册任务的celery。
可以看到tasks列表
[tasks]
. app.app.ContextTask
. celery_tasks.tasks_1.add_togethe
. celery_tasks.tasks_1.long_task
然后运行flask,访问相应地址就可以验证效果了。
>以上是关于falsk 使用celery后台执行任务的主要内容,如果未能解决你的问题,请参考以下文章