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 AsynchResult
.
To obtain the value of task_id
you first have to create an instance of that class, afterwards accessing asynch_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.