简体   繁体   中英

Getting task_id inside a Celery task

This is probably a stupid question but its got me stumped coming from a Ruby background.

I have an object that looks like this when I try to print it.

print celery.AsyncResult.task_id
>>><property object at 0x10c383838>

I was expecting the actual value of the task_id property to be printed here. How do I get to the actual value?

UPDATE 1

@celery.task
def scan(host):
    print celery.AsyncResult.task_id
    cmd = 'ps -ef'
    cm = shlex.split(cmd)
    scan = subprocess.check_output(cm)
    return scan

Best Regards.

Short story, within function scan , use scan.request.id .

See http://docs.celeryproject.org/en/latest/userguide/tasks.html?highlight=request#task-request-info

You are accessing the property from the class, while task_id is a property of instances of AsyncResult .

To obtain the value of task_id you first have to create an instance of that class, afterwards accessing async_result_instance.task_id will return you the real id.

In your updated code:

@celery.task
def scan(host):
    print celery.AsyncResult.task_id
    # ...

Here you are accessing the class as I've already explained. What you want is an instance of the currently executing task. You might use celery.current_task to get the currently executing task-object:

@celery.task
def scan(host):
    print celery.current_task.task_id

Or, if you are interested in the unique id use the request attribute of the decorated function:

@celery.task
def scan(host):
    print scan.request.id
    cmd = 'ps -ef'
    cm = shlex.split(cmd)
    # IMPORTANT: Do *not* use "scan = ..."!
    result = subprocess.check_output(cm)
    return result

In this second case do not use any local variable called scan otherwise you'll an UnboundLocalError .

(Code not tested since I don't have celery installed.)


The property s are descriptors used to provide attribute-like access to getter/setter methods, so that you can access data like:

instance.attribute
instance.attribute = value

But when the code is executed the setter or getter can control what's going on.

You can verify this with a dummy class:

>>> class Dummy(object):
...     @property
...     def a(self):
...             print("called the getter!")
...             return 1
... 
>>> Dummy.a
<property object at 0x7fdae86978e8>
>>> Dummy().a
called the getter!
1

In order to make your tasks more "OO-like", you could use the bind argument to get a reference to self :

@celery.task(bind=True)
def scan(self, host):
  print self.request.id

Please note that self.request.id is actually an instance of AsyncTask . In order to have the task id as a string , you should do self.request.id.__str__() .

From Celery's documentation (after the example):

The bind argument means that the function will be a “bound method” so that you can access attributes and methods on the task type instance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM