Eggs are being more and more used in Python land. One thing Python developers can do easily with them is plugins cooking. They are used in Paste*, TurboGears and Trac for instance, so i wanted to see how to design a simple mini plugins based system. The main requirement here is setuptools_ (i link directly to PyPI because Peak's wiki lags quite a bit currently). Setuptools supply a mechanism to plug systems together called **entry points**, so in your framework you can search plugins by entrypoint, and each egg supplying the entry point would be found. For the lazy people i made a little archive_, holding the few lines of code showed in this article. We'll use an entry point called "my.plugins". Create a new tree structure which will be our first plugin base: :: foo |-- foo_plugin | |-- __init__.py | `-- foo.py `-- setup.py In the ``setup.py``, declare the setup() and don't forget the entry points! :: from setuptools import setup, find_packages setup( name="Foo", version="0.0", description="""Foo plugin""", author="Phil", packages=['foo_plugin'], entry_points=""" [my.plugins] myFoo = foo_plugin.foo:Foo """) Basically we have one entry point labelled ``myFoo`` in the "category" called "my.plugins". The entry point points to the Foo class of the module foo_plugin.foo. That's quite simple, no ? Next step, in the ``foo_plugin/foo.py``, declare your Foo class: :: print 'Foo loading!' class Foo: def echo(self, message): """ sample method, returning its argument """ return message The next step is to package your foo plugin to a full fledged egg and to install it using easy_install: :: $ cd foo $ python setup.py bdist_egg $ sudo easy_install dist/Foo-0.0-py2.3.egg One alternate, and simpler way to go when you are developing your plugin: :: $ cd foo $ sudo python setup.py develop Thus, you don't need to re-compile the egg each time you modify your code, setuptools directly access to it via a link (as i understood it, i may be wrong here). Now the code to search and load our plugins, create a file called ``load_plugins.py`` with following code included: :: import pkg_resources for entrypoint in pkg_resources.iter_entry_points("my.plugins"): plugin_class = entrypoint.load() print entrypoint.name, plugin_class Execute it and here we go, the foo plugin magically pops up: :: $ python load_plugins.py Foo loading! foo_plugin.foo.Foo myFoo After that, the developer can instantiate the class, and play with the plugin. That's all for now, i could have used interfaces to infer the plugin API, but i'm too lazy for now ;-) The interested user should read the `Trac Egg Cooking tutorial`_ which explains how to design trac plugins using the trac components architecture based on interfaces. This document is really worth looking at, Trac is a good piece of code, really well-designed IMHO. .. _setuptools: http://cheeseshop.python.org/pypi/setuptools .. _archive: http://base-art.net/static/sample_plugin_system.tgz .. _Trac Egg Cooking tutorial: http://trac-hacks.org/wiki/EggCookingTutorial