pandaemonium
n. the abode of all the daemons
pandaemonium provides a framework for writing daemons in Python. The API is
based on the threading/multiprocessing model, so the primary way
of creating your own daemon is to either subclass and override the run
method, or provide a function as the target to the Daemon class.
Besides Daemon there is also a locking pid file -- PidLockFile.
PidLockFile can either be used manually, or, if a complete path and file
name are provided to Daemon, used automatically.
simple usage
from pandaemonium import Daemon
def DoSomethingInteresting():
"Just like it says ;)"
pass
daemon = Daemon(target=DoSomethingInteresting)
daemon.start()
#
# daemon.output will contain any stdout output generated during the
# daemonizing process, up to the stdin/stdout/stderr redirection
#
# daemon.error contains anything sent to the daemon's stderr -- which
# most likely means the daemon died due to an exception
#
# both can be parsed, examined, ignored, etc.
or:
from pandaemonium import Daemon
class MyDaemon(Daemon):
def run():
# do some interesting stuff
md = MyDaemon().start()
The sequence of events that takes place when start() is called (adapted from
The Linux Programming Interface by Michael Kerrisk) is:
- detach from the current process, creating a new session
- turn off core dumps
- set uid and gid
- set umask
- set working directory
- create pid file
- set signal handlers
- close inherited file handles
- redirect stdin/stdout/stderr
If any exceptions occur or if any feedback is generated during the start
process it will be available as the error and output attributes of the
daemon instance, where the parent process can analyze, print, etc before
quiting.
Note: Most guides on writing daemons specify setting the umask to 0, but this creates a security hole as all files become world readable/writable by default. Pandaemonium sets the umask to 077, but that can be changed if desired.
advanced usage
If more control is needed than what is provided by the parameters of Daemon then one has a couple options available:
-
if certain set up / initialization steps need to happen somewhere in the
start()sequence, such as after setting the umask and before changing the working directory::Daemon.stage4() # stages 1-4 have now been completed # do custom steps here Daemon.start() # stages 5-9 have now been completed, and run() called -
one can also override any of the stages in a subclass (make sure and decorate with
check_stage):class MyDaemon(Daemon): def run(self, ip): # do stuff @check_stage def stage7(self): # do some custom stuff with signals set up md = MyDaemon('192.168.11.1') md.start() -
or, to simplify between foreground and daemon operation:
foreground = sys.argv[2:3] == ['--foreground'] pid_file = PidLockFile('/some/path/to/lock.pid') pid_file.acquire() if foreground: pid_file.seal() else: daemon = Daemon() daemon.pid_file = pid_file daemon.activate() # at this point, in either foreground or daemon mode, the pid file has # been sealed (has our correct pid written to it, and it has been # closed) run_main_program()
If one's desire is to start the daemon and automatically have any output
printed to screen, one can use daemon.report() which prints whatever was
received from the daemon and then quits.
Daemon
Daemon(target=None, args=None, kwargs=None, working_directory='/', umask=0, prevent_core=True, process_ids=None, inherit_files=None, signal_map=None, stdin=None, stdout=None, stderr=None)
-
target: function to call when daemonized
-
args: positional args to provide to target
-
kwargs: keyword args to provide to target
-
detach:
None(default) means figure it out,Truemeans yes,Falsemeans no. Figuring it out means if the parent process isinit, or asuper server, do not detach -
working_directory: directory to change to (relative to chroot, if one is in effect)
-
umask: mask to use when creating files
-
prevent_core: prevent core dump files from being created
-
process_ids: tuple of (uid, gid) to switch process to (use (None, None) to disable)
-
pid_file:
None(default), or a PidLockFile instance, or the string of where to create a PidLockFile -
inherit_files: list of open files or file descriptors to keep open
-
signal_map: dictionary of signal names or numbers to method names or functions
-
stdin / stdout / stderr: streams to map the standard streams to. default is
Nonewhich is mapped toos.devnull
Daemon.run()
Method representing the daemon's activity.
You may override this method in a subclass. The standard run
method invokes the callable object passed to the object's constructor as
the target argument, if any, with sequential and keyword arguments taken
from the args and kwargs arguments, respectively.
Daemon.start()
Start the daemon's activity.
This may be called at most once per daemon object. It arranges for the
object's run method to be invoked as a daemon process.
Daemon.monitor()
Collects stdout and stderr from Daemon process until stage 9 and attaches
it to the daemon instance as output and error. Can be overridden
if one wants to do more interesting stuff with the daemon's output
Daemon.stage[1-9]()
One can override the various stages for even more customizations options.
Make sure and decorate such functions with check_stage.
PidLockFile
PidLockFile(file_name, timeout)
-
file_name: full path and name of file to use for locking
-
timeout: how long to wait before concluding that an existing held lock is not going to be released (default: -1, meaning conclude immediately)
PidLockFile.acquire(timeout=None)
attempt to capture the lock file; if timeout is None use the time out
specified when PidLockFile was created.
PidLockFile.seal()
write the current process' PID into the acquired file and close it -- should only be called by the daemon process or the stored PID will not be correct.
PidLockFile.release()
remove the lock file, releasing the lock.
Metadata
Release files for pandaemonium 0.9.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pandaemonium-0.9.1.tar.gz | 17.0 kB | Without provenance | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pandaemonium-0.9.1-py3-none-any.whl | Python 3 | none | any | Details |
| pandaemonium-0.9.1-py2-none-any.whl | Python 2 | none | any | Details |
Total release size: 46.3 kB
Release files / pandaemonium-0.9.1.tar.gz
| Download URL | pandaemonium-0.9.1.tar.gz |
|---|---|
| Size | 17.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9956966ee469953443ba16582bd36e8fce8e9841a0ced881ecf3c1071ab7b5fa
|
|
BLAKE2b-256 checksum How to use checksums |
12d51a9c3af5ede8cd55d3c4513a3701a61f5ae0848fc7ded611b9f05895ebb2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/58.1.0 requests-toolbelt/0.9.1 tqdm/4.57.0 CPython/3.9.13+
|
Release files / pandaemonium-0.9.1-py3-none-any.whl
| Download URL | pandaemonium-0.9.1-py3-none-any.whl |
|---|---|
| Size | 14.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0db1048ff68f41bbf19c7eb639b6178ec56bd8c8fa44d467c5bf3db258f1f684
|
|
BLAKE2b-256 checksum How to use checksums |
6adc364736c0e3b39213b5bad652b5e071a2ffcd2ac975a5fb3e4ba374ba7243
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/58.1.0 requests-toolbelt/0.9.1 tqdm/4.57.0 CPython/3.9.13+
|
Release files / pandaemonium-0.9.1-py2-none-any.whl
| Download URL | pandaemonium-0.9.1-py2-none-any.whl |
|---|---|
| Size | 14.7 kB |
| Tags | Python 2 |
|
SHA-256 checksum How to use checksums |
387b7d083812b05b25818e93e668b963d829ae5ee098abfd9f98ad4b9713e185
|
|
BLAKE2b-256 checksum How to use checksums |
79d5c5e7ef29c76586b0fce72bfd344161c4970a314751c2050faa3d818c4fae
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/58.1.0 requests-toolbelt/0.9.1 tqdm/4.57.0 CPython/3.9.13+
|
Security for pandaemonium 0.9.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.