sdnotify: Systemd Service Notification
sdnotify provides a pure Python implementation of systemd's service notification protocol (sd_notify). It allows Python services to communicate their status, readiness, and other information back to systemd, enabling robust service management. The current version is 0.3.2, with releases being infrequent, primarily for packaging or minor internal improvements.
Common errors
-
ModuleNotFoundError: No module named 'sdnotify'
cause The `sdnotify` library is not installed in the Python environment being used to run your service.fixInstall the package using pip: `pip install sdnotify`. -
Systemd service unit reports 'failed' or 'timeout' even though Python script appears to run.
cause This often happens if the systemd unit file's `Type` is not set to `notify`, or if the Python service fails to send `READY=1` to systemd upon startup.fixIn your `.service` unit file, ensure `Type=notify` is set. In your Python code, confirm that `notifier.notify('READY=1')` is called after all initialization steps are complete.
Warnings
- gotcha Notifications are silently ignored if the `NOTIFY_SOCKET` environment variable is not set. This means your Python service is likely not running under systemd, or systemd is not configured to listen for notifications (e.g., `Type=notify` is missing in the unit file).
- gotcha Systemd expects a `READY=1` notification to mark the service as successfully started. Forgetting to send this can cause systemd to prematurely consider the service failed or stalled, leading to restarts or timeouts.
- breaking Versions prior to `0.3.0` were considered experimental and may have been non-functional or had an unstable API. The `sdnotify` functionality became reliably available starting with `0.3.0`.
Install
-
pip install sdnotify
Imports
- SystemdNotifier
from sdnotify import SystemdNotifier
Quickstart
import time
from sdnotify import SystemdNotifier
def main():
notifier = SystemdNotifier()
print("Sending NOTIFY_SOCKET check (silently fails if not running under systemd)")
# Send 'READY=1' to signal that the service is initialized
notifier.notify("READY=1")
print("Service ready. Working...")
for i in range(1, 4):
status_message = f"STATUS=Working on task {i} of 3..."
print(status_message)
notifier.notify(status_message)
time.sleep(2) # Simulate work
# Send 'STOPPING=1' or just exit (systemd can infer STOPPING upon exit)
print("Service finished work. Sending STOPPING=1.")
notifier.notify("STOPPING=1")
if __name__ == "__main__":
main()