How to Package a Python Daemon with Setuptools

Python Daemon Packaging Best Practices

To answer one part of your question, there are no tools I know of that will do daemon setup portably even across Linux systems let alone Windows or Mac OS X.

Most Linux distributions seem to be using start-stop-daemon within init scripts now, but you're still going to have minor difference in filesystem layout and big differences in packaging. Using autotools/configure, or distutils/easy_install if your project is all Python, will go a long way to making it easier to build packages for different Linux/BSD distributions.

Windows is a whole different game and will require Mark Hammond's win32 extensions and maybe Tim Golden's WMI extensions.

I don't know Launchd except that "none of the above" are relevant.

For tips on daemonizing Python scripts, I would look to Python apps that are actually doing it in the real world, for example inside Twisted.

python2.7 install python daemon package using pip

Just write pip install python-daemon==2.1.2

No need to download python-daemon-2.1.2.tar.gz file while installing from PyPI using pip.

If you want to install using downloaded package follow these steps

  1. tar xvf python-daemon-2.1.2.tar.gz
  2. cd python-daemon-2.1.2
  3. python setup.py install

How to declare build-time dependencies without breaking other packages?

(This behaviour is corrected in python-daemon version 2.0.4 and later.)

There are two sides to this:

  • Setuptools assumes it is the centre of everything.
  • Version 2.0.3 of python-daemon doesn't take that into account.

A more detailed explanation: There is some complex code using Docutils involved in the python-daemon build process, that isn't needed after install and isn't part of the library code.

It's too complex to leave in the un-importable (and therefore not-unit-testable) setup.py, so that build code is shunted to a separate testable module, version (in the file version.py), which itself uses Docutils.

But then the setup.py has a circular dependency: How to import version, when Docutils isn't yet installed? How to use Setuptools to ensure Docutils is installed, when running setup.py to completion will need version? All the feasible solutions are ugly and confusing.

The approach taken in ‘python-daemon’ 2.0.3 is to declare Docutils required for setup, and declare a Setuptools entry point for the work that needs version. That way setup.py gets to install Docutils before any of the entry points that will use version.

But now we come to the first point, that Setuptools arrogates itself as the centre of everything. By declaring an entry point, setup.py has modified every Setuptools action thereafter, and every package will fail if it can't find the entry points. And, since most of them don't have version or the specified functions in that module, they crash Setuptools.

What is essentially a bug to be fixed, reveals a poorly-understood corner case in Setuptools. So I'm voting your question up.

There doesn't seem to be a good solution to this: having modules available for setup.py but ensuring requirements are met first. Setuptools assumes it is the only build system needed to satisfy all dependencies for everything, and when that assumption fails it's very difficult to get around.

Thanks to the Python Packaging Authority folks, and the distutils-sig forum, for explaining this to me.

How to fix paths in the python code using setuptools to build a portable package?

To fix this in build time, we can add a custom build step in setup.py, iterate through all the python files in the project and replace the patterns, but the best solution I found is to fix the paths in runtime using global variables:

In my __init__.py I have:

import platform

if platform.system() == 'FreeBSD':
PREFIX = '/usr/local'
else:
PREFIX = ''

Then I can reference the file locations by using:

my_cmd_path = PREFIX + '/bin/my-cmd'

Python: setup.py - want to make sure the correct version of python-daemonize is installed

It is unfortunate that both projects picked a generic name. This makes it almost impossible to correctly specify which one you need to install.

A workaround would be to specify a minimum version; python-daemon is up to version 1.5.5 at the time of writing, while daemon only ever released version 1.0, over 3 years ago.

Pin your requirement to 1.5 and newer and setuptools will go looking for python-daemon even if daemon is installed:

setup(
install_requires=['python-daemon >= 1.5']
)

This workaround will fail, of course, the day daemon releases a 1.5 or newer version.



Related Topics



Leave a reply



Submit