|
@@ -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
|