Will effectively daemonize a running Python script. Tested and used with Python 2.6
NEWS: Released version 0.0.4 of Supay! We have also changed the licensing from GPL to MIT (if that is blokcing anyone to actually use Supay)
Note: When migrating the whole Supay project from SVN to Mercurial in Google Code we lost all our tests.
MethodsThere are a few methods available with the module, here a short description of each one:
start Detaches a Python script from the terminal and assigns a PID to the process stop Finds the process with the matching PID and stops it. spawn Will create a new instance of the Python script (Warning: this should time out or you will not be able to stop the process.) restart Although there is no 'restart' method, you can easily integrate the stop and restart together so they can perform a full restart of your daemon. New!status This is a very easy way to check the status your script. It will return information on the terminal about the specific PID of your process and if it is running or not. To be implementedOne of the main issues of having a Daemon with a PID is how to lock the PID file so that no other process can re-write the file while the daemon is running. Text files are not meant for effective locking. It can work, but it not as safe as data bases:
SQLITE3 PID Manager It will receive a parent PID and will show information about child PIDs. PID Lock One of the added values of a database: a parent PID will be able to lock a file to prevent PID corruption.
Some history about SUPAYIn the ancient language of Quechua (still used today in some regions of South America, like Peru, Bolivia and Ecuador) Supay was the word to refer to Demons. Although different in significance, I decided to revive a rather unknown word to refer to this small module.
InstallationIf you have Setup Tools installed (along with Python) in your machine you can do:
sudo easy_install supayIf you download the tar.gz file, uncompress everything and use the setup.py file to install it"
python setup.py installUsageStartTo use the "start" method:
from supay import Daemon
daemon = Daemon(name='thisScript')
do_something()StopEven easier to use the "stop" method:
New in version 0.0.4: We fixed a verification method when a daemon has died for some reason but the PID has been left behind. As you know, the start method will check if the PID exists so this check will remove the PID if the process does not exist.
We are also including the ability to spawn a process (also known as creating a child process). Beware! spawning processes should be able to TIME OUT. They are cut off the ability of stopping with no PID file to write. This is a good way of dealing with calls to your script that you want to handle separately.
do_something() # and then expire!
StatusCheck the process status:
daemon.status()TestsIf you download the tar.gz file, a tests directory will include all the tests. I have used Nose to run my tests and I suggest you run them with that tool within the uncompressed directory:
nosetests -vDeafultsSupay does some things by default.
Tries to write a PID file to "/var/run/scriptName" Gives an error if you do not have permissions. You can also change this when initializing the Daemon class. Stderr, Stdout and Stdin all try to write to "/var/log/scriptName" If a name for the running script is not given "PythonDaemon" is used. Verbose is set to True, this will show output when starting or stopping the daemon at the terminal.
Note on PermissionsIf you use this module with sudo or root permissions and the default values, you should see no errors. But a lot of times, using super user powers to run a simple script might be a security problem. To avoid running this module as root change the PID and LOG options when initializing the module:
from supay import Daemon
daemon = Daemon(name='myScript', pid_dir='/home/me', stdin='/home/me/logs', stdout='/home/me/logs', stderr='/home/me/logs')
Daemon or Service?A bit of inspiration came from reading PEP-3143. After talking to the author of that PEP, I was told that what I wanted to develop was not a Daemon library, but more a Service library. My reasoning behind building something more than a simple daemon library was this:
A pure Daemon libraryWould make sure to daemonize correctly a process and nothing else. What Supay is intended forDaemonize a Python process (a script or a call) Accept calls to STOP, START, SPAWN child processes. Manage processes PID numbers. Check the STATUS of a process. Redirect output (stderr, stdin, stdout) to a log file. As you can see, I am not interested in a simple standard daemonizing module, and although PEP-3143 was used as a start point, the functionality behind SUPAY goes way beyond that.
Questions? Requests?You can always send me an email: alfredodeza at gmail dot com