I once tried to do something like this and failed and I had an impression that setuptools are not really intended for such things, but mainly for packaging plain Python modules.
Is this a right impression? If yes, what is a good way to package the whole Python based web application?
Take a look at https://github.com/getsentry/sentry for a good example. After doing 'pip install sentry', you can run the included gunicorn-based HTTP server via bin/sentry ('sentry init && sentry start'). A uWSGI-based server would have worked, too.
I like to create a virtualenv under /opt, install the package and its dependencies with pip, and then run fpm to create an RPM or DEB. Then I use Chef or Puppet to install the package, deploy config files, deploy a service script (for upstart or daemontools), and enable the service.
See also http://www.12factor.net/ for some principles on how to structure your app. These can be applied whether or not you use setuptools. For example, Heroku's Python buildpack will deploy your 12-factor app in-place using requirements.txt and Procfile in your app root, ignoring setup.py. I find 12-factor apps are easier to deploy whatever method you choose, since configs/services/logs are cleanly separated from your app itself.
You just need a quickly whipped up Fabric script, and then you deploy remotely from the command line.
A good rule of thumb is that if you have defined access points for others to consume your code with (command line tools, Python modules, or Setuptools entry points), it's a good idea to make a Python package like this. Otherwise, skip it.
from setuptools import setup
kw = {
'name' : 'funniest',
'version' : '0.1',
'description' : 'The funniest joke in the world',
'url' : 'http://github.com/storborg/funniest',
'author' : 'Flying Circus',
'author_email' : 'flyingcircus@example.com',
'license' : 'MIT',
'packages' : ['funniest'],
'zip_safe' : False,
}
if __name__ == '__main__':
setup(**kw)
Here are a few of my setup.py files that follow this convention [2] [3] [4].[1]: http://www.scotttorborg.com/python-packaging/minimal.html#cr...
[2]: https://github.com/gvalkov/harstats-graphite/blob/master/set...
[3]: https://github.com/gvalkov/jenkins-autojobs/blob/master/setu...
[4]: https://github.com/gvalkov/python-evdev/blob/master/setup.py
Additionally, there's no point checking that the script is the main file, as there's only ever one use-case for the script, and that's to call setuptools.
One thing I think is missing is to point out not to use setuptools, but to use the less broken, more maintained, drop in replacement distribute (http://guide.python-distribute.org/). That website also has some further information on the packaging ecosystem that's worth flipping through.
Can you elaborate on the places where setuptools is broken? I wanted to keep things as simple as possible for the sake of this tutorial, and I think the described constraints should avoid any setuptools bugs.
*edit: not alone (semi-old) http://news.ycombinator.com/item?id=4164468
I'm still not sure how to do certain things "right", e.g., distribute a modified version of somebody else's package with my own package. In Ruby, I can do this with bundler specifying a git repo for my own fork of the gem (and then submit a pull request for the original fork, if it's a patch that's useful upstream).