diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index d9bc978d1..802f7c3d4 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -17,10 +17,8 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: '3.10' + - name: Install uv + uses: astral-sh/setup-uv@v7 - name: Generate Python bindings run: ./scripts/uniffi_bindgen_generate_python.sh @@ -28,10 +26,6 @@ jobs: - name: Start bitcoind and electrs run: docker compose up -d - - name: Install testing prerequisites - run: | - pip3 install requests - - name: Run Python unit tests env: BITCOIN_CLI_BIN: "docker exec ldk-node-bitcoin-1 bitcoin-cli" @@ -40,4 +34,4 @@ jobs: ESPLORA_ENDPOINT: "http://127.0.0.1:3002" run: | cd $LDK_NODE_PYTHON_DIR - python3 -m unittest discover -s src/ldk_node + uv run --group dev python -m unittest discover -s src/ldk_node diff --git a/bindings/python/hatch_build.py b/bindings/python/hatch_build.py new file mode 100644 index 000000000..bd5f54d24 --- /dev/null +++ b/bindings/python/hatch_build.py @@ -0,0 +1,7 @@ +from hatchling.builders.hooks.plugin.interface import BuildHookInterface + + +class CustomBuildHook(BuildHookInterface): + def initialize(self, version, build_data): + build_data["pure_python"] = False + build_data["infer_tag"] = True diff --git a/bindings/python/pyproject.toml b/bindings/python/pyproject.toml index 18ba319c4..b77801d45 100644 --- a/bindings/python/pyproject.toml +++ b/bindings/python/pyproject.toml @@ -1,3 +1,7 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + [project] name = "ldk_node" version = "0.7.0" @@ -5,8 +9,8 @@ authors = [ { name="Elias Rohrer", email="dev@tnull.de" }, ] description = "A ready-to-go Lightning node library built using LDK and BDK." -readme = "README.md" -requires-python = ">=3.6" +readme = "../../README.md" +requires-python = ">=3.8" classifiers = [ "Topic :: Software Development :: Libraries", "Topic :: Security :: Cryptography", @@ -19,3 +23,11 @@ classifiers = [ "Homepage" = "https://lightningdevkit.org/" "Github" = "https://github.com/lightningdevkit/ldk-node" "Bug Tracker" = "https://github.com/lightningdevkit/ldk-node/issues" + +[dependency-groups] +dev = ["requests"] + +[tool.hatch.build.targets.wheel] +packages = ["src/ldk_node"] + +[tool.hatch.build.hooks.custom] diff --git a/bindings/python/setup.cfg b/bindings/python/setup.cfg deleted file mode 100644 index bd4e64216..000000000 --- a/bindings/python/setup.cfg +++ /dev/null @@ -1,13 +0,0 @@ -[options] -packages = find: -package_dir = - = src -include_package_data = True - -[options.packages.find] -where = src - -[options.package_data] -ldk_node = - *.so - *.dylib diff --git a/scripts/python_build_wheel.sh b/scripts/python_build_wheel.sh new file mode 100755 index 000000000..4bae18479 --- /dev/null +++ b/scripts/python_build_wheel.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# Build a Python wheel for the current platform. +# +# This script compiles the Rust library, generates Python bindings via UniFFI, +# and builds a platform-specific wheel using uv + hatchling. +# +# Run this on each target platform (Linux, macOS) to collect wheels, then use +# scripts/python_publish_package.sh to publish them. + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +cd "$REPO_ROOT" + +# Generate bindings and compile the native library +echo "Generating Python bindings..." +./scripts/uniffi_bindgen_generate_python.sh + +# Build the wheel +echo "Building wheel..." +cd bindings/python +uv build --wheel + +echo "" +echo "Wheel built successfully:" +ls -1 dist/*.whl +echo "" +echo "Collect wheels from all target platforms into dist/, then run:" +echo " ./scripts/python_publish_package.sh" diff --git a/scripts/python_create_package.sh b/scripts/python_create_package.sh deleted file mode 100755 index 0a993c9cb..000000000 --- a/scripts/python_create_package.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -cd bindings/python || exit 1 -python3 -m build diff --git a/scripts/python_publish_package.sh b/scripts/python_publish_package.sh new file mode 100755 index 000000000..971a4edda --- /dev/null +++ b/scripts/python_publish_package.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Publish Python wheels to PyPI (or TestPyPI). +# +# Usage: +# ./scripts/python_publish_package.sh # publish to PyPI +# ./scripts/python_publish_package.sh --index testpypi # publish to TestPyPI +# +# Before running, collect wheels from all target platforms into bindings/python/dist/. + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +DIST_DIR="$REPO_ROOT/bindings/python/dist" + +if [ ! -d "$DIST_DIR" ] || [ -z "$(ls -A "$DIST_DIR"/*.whl 2>/dev/null)" ]; then + echo "Error: No wheels found in $DIST_DIR" + echo "Run ./scripts/python_build_wheel.sh on each target platform first." + exit 1 +fi + +echo "Wheels to publish:" +ls -1 "$DIST_DIR"/*.whl +echo "" + +uv publish "$@" "$DIST_DIR"/*.whl