falsk use celery background tasks

# Falsk use celery background tasks

1. Basic environment to build

doc:https://flask.palletsprojects.com/en/1.0.x/patterns/celery/

mkdir celery_tasks

the init .py # instantiated celery

from celery import Celery

# celery
my_celery = Celery('my_celery')

task_1.py # celery task

from celery_tasks import my_celery

@my_celery.task
def add_together(a, b):
    #print('add_together执行中。。。')
    return a + b

app .__ init__ # celery instance configuration

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)

Configuration located app.app.py

def _handle_celery_task(app, my_celery):
    # celery
    my_celery.conf['broker_url'] = 'redis://:[email protected]:6379/0'
    my_celery.conf['result_backend'] = 'redis://:[email protected]: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. With a background task status updates

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

Code segment is too long, is not the focus of this article, link address:
https://github.com/miguelgrinberg/flask-celery-example
is simply non-stop access / status via ajax / Updating pages based on the returned data.

3. Run

(Venv)> celery -A -l App worker info -P eventlet
--logfile = c.log
Note that the command must be a module pointed configuration example where the Celery, otherwise it will give a null register task celery .

可以看到tasks列表
[tasks]
. app.app.ContextTask
. celery_tasks.tasks_1.add_togethe
. celery_tasks.tasks_1.long_task

Then run flask, access to the appropriate address can verify the effect.

Guess you like

Origin www.cnblogs.com/wodeboke-y/p/11600946.html