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_managerprocess restarts, running scripts become orphans. Use systemd to keepprocess_manageritself alive if uptime matters. sys.executableis 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
916ca2cf1d198fac861e6048764d39a116c499b1517cd8a3fda835b6adb3e019
|
|
| MD5 |
30531307c728607ed0c434203d8c43fe
|
|
| BLAKE2b-256 |
702fff8bd85011fcb8ba27b3cc115696bb569b916831e5737cad5a5692ba4219
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d9fef5927bf570cb4ae2e041704eb8156faff2dab6de321bdf2128bb810131b5
|
|
| MD5 |
0fb02b23c5a362e6b568b071339aa056
|
|
| BLAKE2b-256 |
cda836fa91572ff0f03dacffee8c124dba7a7c98e951dc994310f60165215dc5
|