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