Files
OpenShell/build/python.toml
T

176 lines
5.2 KiB
TOML

# Python development, build, lint, and format tasks
["python:dev"]
description = "Install Python package in development mode (builds CLI binary)"
depends = ["python:proto"]
run = "uv sync --group dev && uv pip install ."
["python:build"]
description = "Build Python wheel with CLI binary (native)"
depends = ["python:proto"]
run = "uv run maturin build --release"
["python:build:multiarch"]
description = "Build Python wheels for Linux amd64/arm64 with buildx"
depends = ["python:proto"]
run = """
#!/usr/bin/env bash
set -euo pipefail
PLATFORMS=${DOCKER_PLATFORMS:-linux/amd64,linux/arm64}
VERSION=${NAVIGATOR_VERSION:-}
if [ -z "$VERSION" ]; then
VERSION=$(uv run python build/scripts/release.py get-version --python)
fi
VERSION_ARGS=(--build-arg "NAVIGATOR_VERSION=${VERSION}")
if ! docker buildx inspect multiarch >/dev/null 2>&1; then
echo "Creating multi-platform buildx builder..."
docker buildx create --name multiarch --use --bootstrap
else
docker buildx use multiarch
fi
mkdir -p target/wheels
for platform in ${PLATFORMS//,/ }; do
echo "Building wheel for ${platform}..."
docker buildx build \
--builder multiarch \
--platform "${platform}" \
-f deploy/docker/Dockerfile.python-wheels \
--target wheels \
"${VERSION_ARGS[@]}" \
--output type=local,dest=target/wheels \
.
done
ls -la target/wheels/*.whl
"""
["python:build:macos"]
description = "Build Python wheel for macOS arm64"
depends = ["python:proto"]
run = """
#!/usr/bin/env bash
set -euo pipefail
if [ "$(uname -s)" = "Darwin" ]; then
# Avoid failures when RUSTC_WRAPPER is set to an unresolved `sccache` binary.
if command -v sccache >/dev/null 2>&1; then
export RUSTC_WRAPPER="$(command -v sccache)"
else
unset RUSTC_WRAPPER || true
fi
mkdir -p target/wheels
rustup target add aarch64-apple-darwin
uv run maturin build --release --target aarch64-apple-darwin --out target/wheels
else
echo "Building macOS wheel via Docker cross-toolchain"
mise run python:build:macos:docker
fi
ls -la target/wheels/*.whl
"""
["python:build:macos:docker"]
description = "Build Python wheel for macOS arm64 from Docker"
depends = ["python:proto"]
run = """
#!/usr/bin/env bash
set -euo pipefail
VERSION=${NAVIGATOR_VERSION:-}
OSXCROSS_IMAGE_REF=${OSXCROSS_IMAGE:-crazymax/osxcross:latest}
if [ -z "$VERSION" ]; then
VERSION=$(uv run python build/scripts/release.py get-version --python)
fi
mkdir -p target/wheels
docker build \
-f deploy/docker/Dockerfile.python-wheels-macos \
--target wheels \
--build-arg "OSXCROSS_IMAGE=${OSXCROSS_IMAGE_REF}" \
--build-arg "NAVIGATOR_VERSION=${VERSION}" \
--output type=local,dest=target/wheels \
.
ls -la target/wheels/*macosx*arm64.whl
"""
["python:build:all"]
description = "Build Python wheels for Linux and macOS"
depends = ["python:build", "python:build:multiarch", "python:build:macos"]
["python:lint"]
description = "Lint Python code with ruff"
depends = ["python:proto"]
env = { UV_NO_SYNC = "1" }
run = "uv run ruff check {{vars.python_paths}}"
["python:format"]
description = "Format Python code with ruff"
run = "uv run ruff format {{vars.python_paths}}"
["python:typecheck"]
description = "Type check Python code with ty"
depends = ["python:proto"]
run = "uv run ty check {{vars.python_paths}}"
["python:proto"]
description = "Generate Python protobuf stubs from .proto files"
env = { UV_NO_SYNC = "1" }
run = """
#!/usr/bin/env bash
set -euo pipefail
uv run python -m grpc_tools.protoc \
-Iproto \
--python_out=python/navigator/_proto \
--pyi_out=python/navigator/_proto \
--grpc_python_out=python/navigator/_proto \
proto/inference.proto \
proto/navigator.proto \
proto/datamodel.proto \
proto/sandbox.proto
# Fix absolute imports in generated stubs to use package-relative imports
uv run python - <<'PY'
from pathlib import Path
import re
line_rewrites = {
"python/navigator/_proto/inference_pb2_grpc.py": [
(r"^import inference_pb2 as inference__pb2$", "from . import inference_pb2 as inference__pb2"),
],
"python/navigator/_proto/navigator_pb2_grpc.py": [
(r"^import navigator_pb2 as navigator__pb2$", "from . import navigator_pb2 as navigator__pb2"),
(r"^import sandbox_pb2 as sandbox__pb2$", "from . import sandbox_pb2 as sandbox__pb2"),
],
"python/navigator/_proto/navigator_pb2.py": [
(r"^import datamodel_pb2 as datamodel__pb2$", "from . import datamodel_pb2 as datamodel__pb2"),
(r"^import sandbox_pb2 as sandbox__pb2$", "from . import sandbox_pb2 as sandbox__pb2"),
],
"python/navigator/_proto/datamodel_pb2.py": [
(r"^import sandbox_pb2 as sandbox__pb2$", "from . import sandbox_pb2 as sandbox__pb2"),
],
"python/navigator/_proto/datamodel_pb2_grpc.py": [
(r"^import datamodel_pb2 as datamodel__pb2$", "from . import datamodel_pb2 as datamodel__pb2"),
],
"python/navigator/_proto/sandbox_pb2_grpc.py": [
(r"^import sandbox_pb2 as sandbox__pb2$", "from . import sandbox_pb2 as sandbox__pb2"),
],
}
for path, rules in line_rewrites.items():
file_path = Path(path)
text = file_path.read_text()
text = text.replace("from . from . import", "from . import")
for pattern, replacement in rules:
text = re.sub(pattern, replacement, text, flags=re.MULTILINE)
file_path.write_text(text)
PY
"""