Simpervisor: Simple Async Process Supervisor

1.0.0 · active · verified Wed Apr 15

Simpervisor is a lightweight Python library providing an asynchronous process supervisor. It offers the `SupervisedProcess` class to manage external processes with async methods like `start`, `ready`, `terminate`, and `kill`. The library is actively maintained, with its latest major release (1.0.0) in May 2023, indicating a stable but less frequent release cadence focused on robustness.

Warnings

Install

Imports

Quickstart

This example demonstrates how to use `SupervisedProcess` to start an asynchronous Python script as a child process, monitor its status with `ready()`, and gracefully terminate it using `terminate()`. The child process simulates some work before exiting or being cancelled. The `sys.executable` is used to ensure the same Python interpreter runs the child script.

import asyncio
import sys
import os
from simpervisor import SupervisedProcess

# Create a dummy script to supervise
dummy_script_content = """
import asyncio
import sys
import time

async def child_process_task():
    print(f"Child process {os.getpid()} started.")
    try:
        for i in range(5):
            print(f"Child process {os.getpid()}: Working... {i+1}/5")
            await asyncio.sleep(1)
        print(f"Child process {os.getpid()}: Done working, exiting.")
    except asyncio.CancelledError:
        print(f"Child process {os.getpid()}: Cancelled, cleaning up.")
    except Exception as e:
        print(f"Child process {os.getpid()}: Error - {e}")
    finally:
        print(f"Child process {os.getpid()} exiting gracefully.")

if __name__ == '__main__':
    asyncio.run(child_process_task())
"""

async def main():
    script_path = "./dummy_child_script.py"
    with open(script_path, "w") as f:
        f.write(dummy_script_content)

    print("Starting supervisor example...")

    # Supervise the dummy script using python as the executable
    # This assumes 'python' is in your PATH
    process = SupervisedProcess(
        [sys.executable, script_path], # Command to run the child process
        always_restart=False # For this example, don't restart automatically
    )

    await process.start()
    print(f"Supervisor: Process started with PID {process.pid}")

    await asyncio.sleep(2) # Give child some time to work

    if await process.ready():
        print("Supervisor: Child process reports ready (or has started).")
    else:
        print("Supervisor: Child process not yet ready.")

    await asyncio.sleep(3)

    print("Supervisor: Attempting to terminate child process...")
    await process.terminate()
    # await process.wait() # Can wait for termination if needed

    if not process.running:
        print("Supervisor: Child process terminated.")
    else:
        print("Supervisor: Child process is still running after terminate attempt.")

    os.remove(script_path)
    print("Supervisor: Example finished.")

if __name__ == '__main__':
    asyncio.run(main())

view raw JSON →