Skip to content

Commit

Permalink
Tasks Userguide: Added section about decorating tasks. Closes celery#224
Browse files Browse the repository at this point in the history
  • Loading branch information
Ask Solem committed Oct 25, 2010
1 parent 3ffd0f8 commit 6b1bbb8
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 1 deletion.
8 changes: 7 additions & 1 deletion FAQ
Original file line number Diff line number Diff line change
Expand Up @@ -474,11 +474,17 @@ For more information see :ref:`task-request-info`.
Can I specify a custom task_id?
-------------------------------

**Answer**: Yes. Use the ``task_id`` argument to
**Answer**: Yes. Use the ``task_id`` argument to
:meth:`~celery.execute.apply_async`::

>>> task.apply_async(args, kwargs, task_id="...")


Can I use decorators with tasks?
--------------------------------

**Answer**: Yes. But please see note at :ref:`tasks-decorating`.

.. _faq-natural-task-ids:

Can I use natural task ids?
Expand Down
64 changes: 64 additions & 0 deletions docs/userguide/tasks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,70 @@ add the project directory to the Python path::

This makes more sense from the reusable app perspective anyway.

.. tasks-decorating:
Decorating tasks
================

Using decorators with tasks requires extra steps because of the magic keyword
arguments.

If you have the following task and decorator:

.. code-block:: python
from celery.utils.functional import wraps
def decorator(task):
@wraps(task)
def _decorated(*args, **kwargs):
print("inside decorator")
return task(*args, **kwargs)
@decorator
@task
def add(x, y):
return x + y
Then the worker will see that the task is accepting keyword arguments,
while it really doesn't, resulting in an error.

The workaround is to either have your task accept arbitrary keyword
arguments:

.. code-block:: python
@decorator
@task
def add(x, y, **kwargs):
return x + y
or patch the decorator to preserve the original signature:

.. code-block:: python
from inspect import getargspec
from celery.utils.functional import wraps
def decorator(task):
@wraps(task)
def _decorated(*args, **kwargs):
print("in decorator")
return task(*args, **kwargs)
_decorated.argspec = inspect.getargspec(task)
Also note the use of :func:`~celery.utils.functional.wraps` here,
this is necessary to keep the original function name and docstring.

.. note::

The magic keyword arguments will be deprecated in the future,
replaced by the ``task.request`` attribute in 2.2, and the
keyword arguments will be removed in 3.0.

.. _task-states:

Task States
Expand Down

0 comments on commit 6b1bbb8

Please sign in to comment.