maestro/scripts/prebake-python.sh
clade 7049a874f3 feat: initial public release (MAESTRO v0.1.0)
Open-source release of MAESTRO, an agent orchestration platform that runs
LLM-driven tasks through sandboxed tools, with a web UI. Apache-2.0.
See README.md and docs/ (getting-started, configuration, architecture).
2026-06-03 04:01:14 +00:00

79 lines
3.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Pre-bake the Python packages the agent Bash sandbox needs.
#
# These are installed into the SYSTEM python's site-packages, because that is
# what bwrap read-only bind-mounts (/usr) into every Bash sandbox. A `--user`
# install (~/.local) is NOT visible inside the sandbox (/home is not mounted),
# so it must be a system install.
#
# Idempotent and safe to re-run. Non-fatal by default (prints a warning and
# exits 0 so it does not break a build); pass --strict to fail on error.
#
# See docs/operations/bash-sandbox-provisioning.md.
set -uo pipefail
PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
REQ="$PROJECT_DIR/runtime/python-requirements.txt"
STRICT=0
for arg in "$@"; do
case "$arg" in
--strict) STRICT=1 ;;
-h|--help) echo "Usage: $0 [--strict]"; exit 0 ;;
*) echo "Unknown option: $arg" >&2; exit 2 ;;
esac
done
soft_fail() {
echo "[prebake-python] $1" >&2
if [ "$STRICT" -eq 1 ]; then exit 1; fi
echo "[prebake-python] continuing (non-strict); Bash-tool python packages may be unavailable." >&2
exit 0
}
[ -f "$REQ" ] || soft_fail "requirements file not found: $REQ"
if command -v pip3 >/dev/null 2>&1; then PIP="pip3"
elif command -v pip >/dev/null 2>&1; then PIP="pip"
elif command -v python3 >/dev/null 2>&1; then PIP="python3 -m pip"
else soft_fail "no pip / python3 found — skipping python pre-bake"; fi
echo "[prebake-python] installing $REQ into the system python via: $PIP"
# PEP668 distros (Debian/Ubuntu/alpine) mark the system python "externally
# managed"; --break-system-packages is required there. Older pip rejects that
# flag, so retry without it.
if $PIP install --break-system-packages -r "$REQ"; then
:
elif $PIP install -r "$REQ"; then
:
else
soft_fail "pip install failed. If this is a permission error, retry as: sudo $PIP install --break-system-packages -r runtime/python-requirements.txt"
fi
echo "[prebake-python] done. Verifying imports..."
if command -v python3 >/dev/null 2>&1; then
python3 - <<'PYEOF' || echo "[prebake-python] WARNING: some packages failed to import (see above)." >&2
import importlib, sys
# import-name : pip-name (for the warning message)
mods = {
"pypdf": "pypdf", "fitz": "pymupdf", "pdfplumber": "pdfplumber",
"docx": "python-docx", "pptx": "python-pptx", "openpyxl": "openpyxl",
"xlsxwriter": "xlsxwriter", "xlrd": "xlrd", "odf": "odfpy", "striprtf": "striprtf",
"bs4": "beautifulsoup4", "lxml": "lxml", "markdownify": "markdownify",
"markdown": "markdown", "numpy": "numpy", "pandas": "pandas", "tabulate": "tabulate",
"dateutil": "python-dateutil", "matplotlib": "matplotlib", "PIL": "Pillow",
"charset_normalizer": "charset-normalizer", "yaml": "PyYAML",
}
missing = []
for mod, pkg in mods.items():
try:
importlib.import_module(mod)
except Exception:
missing.append(f"{pkg} (import {mod})")
if missing:
print("[prebake-python] MISSING: " + ", ".join(missing), file=sys.stderr)
sys.exit(1)
print(f"[prebake-python] all {len(mods)} packages import OK.")
PYEOF
fi