2

Based on get id for current task.

I call chain like:

chain = (nice_task.s(a=1) |
         task2.s(a=2)).apply_async()

Task defined as:

@celery.task(bind=True)
def nice_task(self, a):
    print a
    print self.request.id  # None
    return a

How to get id of task inside chain?

I tried to turn on / off CELERY_ALWAYS_EAGER - with no effect.

UPD Also self.request has empty context.

Community
  • 1
  • 1
Nikolay Fominyh
  • 8,946
  • 8
  • 66
  • 102

1 Answers1

6

Calling the chain will call the tasks inside it and return the result of the last task in the chain.

When you are calling chain like this

chain = (nice_task.s(a=1) | task2.s(a=2)).apply_async()

it is returning result of task2. You can verify this by checking chain.info

In [25]: chain.info
Out[25]: 'task2'

In [26]: chain.id
Out[26]: 'bec26eff-2dfe-4203-aed2-a122d908c905'

To access previous task, you need to use .parent attribute. chain.parent gives you previous task and you can get id from .id.

In [27]: chain.parent
Out[27]: <AsyncResult: 242d338b-35fe-4f16-be07-36d0d8f2bb53>

In [28]: chain.parent.info
Out[28]: 'task1'

In [29]: chain.parent.id
Out[29]: '242d338b-35fe-4f16-be07-36d0d8f2bb53'
Chillar Anand
  • 27,936
  • 9
  • 119
  • 136
  • 1
    I don't know if it is related, but in my case, it does not matter if I run the chain with `apply_async` or `delay`, the `chain.parent` is always *None*. I have been looking for possible solution all over the Internet, but can't find any clues. :( – Wiktor Stribiżew Jun 02 '23 at 14:00
  • 1
    @WiktorStribiżew in my case worked getting the parent id from the `GroupResult`, since chain, chord and group return a `GroupResult`: `AsyncResult(GroupResult.restore(task_id, app=celery_app).parent.id, app=celery_app)` – Y4RD13 Aug 07 '23 at 15:53