Skip to main content

A small python script fleet package

Project description

fleet_man

A lightweight Python library for running and monitoring scripts on Raspberry Pis from a browser. Each Pi hosts its own control panel with live log streaming. An optional fleet coordinator aggregates all Pis into a single dashboard.

Built on FastAPI + WebSockets. No external message broker. No database. Each Pi is fully autonomous.


install

pip install 'uvicorn[standard]' fastapi httpx

quick start — single Pi

# app.py
import sys
import uvicorn
from pathlib import Path
from process_manager import ProcessManager, ScriptSpec

PY = sys.executable

scripts = {
    "CAN-M":  ScriptSpec("CAN Manager",  [PY, "gc_monitor/run.py"]),
    "backup": ScriptSpec("backup",        ["bash", "jobs/backup.sh"]),
    "server": ScriptSpec("api server",    [PY, "jobs/server.py"]),
}

mgr = ProcessManager(
    name="pi-kitchen",
    scripts=scripts,
    log_dir=Path("/var/log/jobs"),
    port=5001,
)

app = mgr.create_app()

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=5001)

Open http://<pi-ip>:5001 in your browser.


ProcessManager

ProcessManager(
    scripts,                          # dict[str, ScriptSpec]  — required
    name="pi",                        # node name shown in UI
    log_dir=Path("/tmp/pm_logs"),     # where .log files are written
    coordinator_url=None,             # optional fleet coordinator URL
    host=None,                        # LAN IP advertised to coordinator (auto-detected)
    port=8000,                        # port this Pi listens on
)

ScriptSpec

ScriptSpec(label, cmd)
arg type description
label str display name shown in the UI
cmd list[str] or callable command to run

cmd can be a callable — it is invoked at start time, so it can pull config from disk or environment dynamically:

def build_cmd():
    config = load_config()
    return ["python", "worker.py", "--env", config["env"]]

ScriptSpec("worker", build_cmd)

fleet coordinator

The coordinator runs on any central machine (laptop, NAS, another Pi). It polls each registered Pi, tracks online/offline status, and serves a unified fleet dashboard where you can start and stop scripts across all nodes.

# coordinator.py
import uvicorn
from coordinator import create_coordinator_app

app = create_coordinator_app(fleet_name="home-lab")

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=9000)

Open http://<coordinator-ip>:9000.

auto-registration

Pass coordinator_url to ProcessManager and each Pi registers itself on startup and re-registers every 30 seconds — no manual steps needed. Boot order doesn't matter; Pis retry until the coordinator is reachable.

mgr = ProcessManager(
    name="pi-kitchen",
    scripts=scripts,
    coordinator_url="http://192.168.1.10:9000",
    port=5001,
)

You'll see confirmation in the Pi's console:

[pm] registered with coordinator at http://192.168.1.10:9000

If the coordinator is down at boot:

[pm] coordinator unreachable at http://192.168.1.10:9000 — will retry

Either way the Pi starts normally. The coordinator is purely additive — removing it changes nothing about how the Pi operates.

manual registration (curl)

If you're not using coordinator_url, you can register a node manually:

curl -X POST http://192.168.1.10:9000/register \
     -H "Content-Type: application/json" \
     -d '{"name":"pi-kitchen","host":"192.168.1.42","port":5001}'

log files

Each script writes stdout and stderr to a .log file in log_dir. For a script with key CAN-M the log is written to <log_dir>/CAN-M.log. Logs persist across restarts and are also tailable directly:

tail -f /var/log/jobs/CAN-M.log

The last 500 lines are buffered in memory and replayed instantly when you open the log panel in the browser. New lines stream in live via WebSocket.


API reference

Each Pi exposes the following endpoints:

method path description
GET / local dashboard UI
GET /api/status JSON status of all scripts
POST /api/start/<key> start a script
POST /api/stop/<key> stop a script
GET /api/log/<key> last 500 lines of log (plain text)
WS /ws status push every 2s + start/stop commands
WS /ws/<key> live log stream for one script

The coordinator exposes:

method path description
GET / fleet dashboard UI
POST /register register or re-register a node
GET /api/fleet full fleet status JSON
GET /api/nodes all node info
POST /api/<node>/start/<key> start a script on a specific node
POST /api/<node>/stop/<key> stop a script on a specific node
WS /ws live fleet status push + forwarded commands

architecture

[ browser ]
    │
    │  WebSocket  (live status + logs)
    │
    ├─────────────────────────┐
    │                         │
[ coordinator :9000 ]   [ Pi dashboard :5001 ]
    │                         │
    │  HTTP poll /api/status   │  asyncio subprocess
    │  every 3s                │  stdout/stderr → WS
    │                         │
    └──────── Pi nodes ────────┘
         pi-kitchen  :5001
         pi-garage   :5001
         pi-shed     :5001

Each Pi is standalone. The coordinator is optional. If the coordinator restarts, Pis re-register automatically within 30 seconds.


notes

  • Scripts must run in the foreground. Processes that daemonize (fork and detach) will not be tracked correctly.
  • State is in-memory. If the Pi's process_manager process restarts, running scripts become orphans. Use systemd to keep process_manager itself alive if uptime matters.
  • sys.executable is recommended over "python" or "python3" to ensure the correct interpreter is used, especially inside a virtualenv.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fleet_man-0.0.4.tar.gz (18.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fleet_man-0.0.4-py3-none-any.whl (18.8 kB view details)

Uploaded Python 3

File details

Details for the file fleet_man-0.0.4.tar.gz.

File metadata

  • Download URL: fleet_man-0.0.4.tar.gz
  • Upload date:
  • Size: 18.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for fleet_man-0.0.4.tar.gz
Algorithm Hash digest
SHA256 916ca2cf1d198fac861e6048764d39a116c499b1517cd8a3fda835b6adb3e019
MD5 30531307c728607ed0c434203d8c43fe
BLAKE2b-256 702fff8bd85011fcb8ba27b3cc115696bb569b916831e5737cad5a5692ba4219

See more details on using hashes here.

File details

Details for the file fleet_man-0.0.4-py3-none-any.whl.

File metadata

  • Download URL: fleet_man-0.0.4-py3-none-any.whl
  • Upload date:
  • Size: 18.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for fleet_man-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 d9fef5927bf570cb4ae2e041704eb8156faff2dab6de321bdf2128bb810131b5
MD5 0fb02b23c5a362e6b568b071339aa056
BLAKE2b-256 cda836fa91572ff0f03dacffee8c124dba7a7c98e951dc994310f60165215dc5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page