7

I'd like to update the state of my Celery task from another function. Here's what I have now:

The Route

@app.route('/my-long-function', methods=['POST'])
def my_long_function():

    param1 = request.form['param1']
    param2 = request.form['param2']

    task = outside_function.delay(param1, param2)

    return task.id

Celery Task - starts some_python_script.handle in the background

@celery.task(name='outside_function')
def outside_function(param1, param2):
    with app.app_context():
        some_python_script.handle(param1, param2)

some_python_script.handle:

def handle(param1, param2):
    param1 + param2
    # many, many different things

Ideally, I'd like to be able to self.update_state the celery task so that I can easily request its status from my app, like so:

some_python_script.handle (ideally):

def handle(param1, param2):
    param1 + param2
    # many, many different things
    self.outside_function.update_state('PROGRESS', meta = {'status':'progressing'})

check progress (ideally):

@app.route('/status/<task_id>')
def taskstatus(task_id):
    task = outside_function.AsyncResult(task_id)
    response = {
    'state': task.state,
    'id': task.id,
    'status' : task.status,
    }

    return jsonify(response)

Or something similar. Would appreciate any help, I'm very new to Celery!

vandernath
  • 3,665
  • 3
  • 15
  • 24

3 Answers3

0

You should declare the task id for calling. You can check update_state.

The below code should work.

# capture id of celery task
ID = self.request.id

def handle(param1, param2):
    param1 + param2
    # many, many different things
    # update the state of celery task with direct reference to it
    self.update_state(task_id=ID, state='PROGRESS', meta = {'status':'progressing'})
amin
  • 1,413
  • 14
  • 24
0

If you add bind=True to the main celery task, you get access to the celery task object with the self keyword. Pass the task object to the next function using self.

@celery.task(name='outside_function', bind=True)
def outside_function(self, param1, param2):
    with app.app_context():
        some_python_script.handle(self,param1, param2)

The other function can accept this task object and update it:

def handle(celery_task, param1, param2):
    param1 + param2
    # many, many different things
    celery_task.update_state('PROGRESS', meta = {'status':'progressing'})
Mitalee Rao
  • 191
  • 6
0

use celery_app.backend.store_result(task_id, state, result) can fix this store_result use by update_state