| 
					
				 | 
			
			
				@@ -0,0 +1,109 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.. _guide-extending: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+========================== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ Extensions and Bootsteps 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+========================== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.. contents:: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    :local: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    :depth: 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.. _extending-bootsteps: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Bootsteps 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+========= 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.. _extending-programs: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Command-line programs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+===================== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.. _extending-commandoptions: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Adding new command-line options 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+You can add additional command-line options to the ``worker``, ``beat`` and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+``events`` commands by modifying the :attr:`~@Celery.user_options` attribute of the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+application instance. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Celery commands uses the :mod:`optparse` module to parse command-line 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+arguments, and so you have to use optparse specific option instances created 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+using :func:`optparse.make_option`.  Please see the :mod:`optparse` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+documentation to read about the fields supported. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Example adding a custom option to the :program:`celery worker` command: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.. code-block:: python 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    from celery import Celery 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    from optparse import make_option as Option 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    celery = Celery(broker='amqp://') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    celery.user_options['worker'].add( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Option('--enable-my-option', action='store_true', default=False, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               help='Enable custom option.'), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.. _extending-subcommands: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Adding new :program:`celery` sub-commands 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+----------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+New commands can be added to the :program:`celery` umbrella command by using 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+`setuptools entry-points`_. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.. _`setuptools entry-points`: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    http://reinout.vanrees.org/weblog/2010/01/06/zest-releaser-entry-points.html 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Entry-points is special metadata that can be added to your packages ``setup.py`` program, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+and then after installation, read from the system using the :mod:`pkg_resources` module. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Celery recognizes ``celery.commands`` entry-points to install additional 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+subcommands, where the value of the entry-point must point to a valid subclass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+of :class:`celery.bin.base.Command`.  Sadly there is limited documentation, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+but you can find inspiration from the various commands in the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+:mod:`celery.bin` package. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+This is how the `Flower`_ extension adds the :program:`celery flower` command, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+by adding an entry-point in :file:`setup.py`: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.. code-block:: python 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setup( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        name='flower', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        entry_points={ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            'celery.commands': [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               'flower = flower.command.FlowerCommand', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+The command definition is in two parts separated by the equal sign, where the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+first part is the name of the subcommand (flower), then the fully qualified 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+module path to the class that implements the command 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(``flower.command.FlowerCommand``). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+In the module :file:`flower/command.py`, the command class is defined 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+something like this: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    from celery.bin.base import Command, Option 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    class FlowerCommand(Command): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        def get_options(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Option('--port', default=8888, type='int', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    help='Webserver port', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Option('--debug', action='store_true'), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        def run(self, port=None, debug=False, **kwargs): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            print('Running our command') 
			 |