From 1cd2eb2774223ab0b5736bf78d576b8097102c7f Mon Sep 17 00:00:00 2001 From: Dmitriy Suponitskiy Date: Mon, 22 Dec 2025 14:49:28 -0500 Subject: [PATCH 1/2] Automate openfhe-python document generation for readthedocs.org --- .readthedocs.yaml | 17 +++++++++-- docs/requirements.txt | 38 +++---------------------- docs/scripts/build-wheel-for-docs.sh | 42 ++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 37 deletions(-) create mode 100755 docs/scripts/build-wheel-for-docs.sh diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 9712e40..149741f 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -5,11 +5,22 @@ # Required version: 2 -# Set the version of Python and other tools you might need build: - os: ubuntu-22.04 + os: ubuntu-24.04 tools: - python: "3.11" + python: "3.12" + + commands: + - python -m pip install -U pip + - python -m pip install -r docs/requirements.txt + + # Build wheel using the real RTD branch name and install it + - WHEEL_PATH="$(bash docs/scripts/build-wheel-for-docs.sh)" + - echo "Installing wheel: ${WHEEL_PATH}" + - python -m pip install "${WHEEL_PATH}" + + # Build documentation + - python -m sphinx -b html docs/ "$READTHEDOCS_OUTPUT/html" # Build documentation in the docs/ directory with Sphinx sphinx: diff --git a/docs/requirements.txt b/docs/requirements.txt index 0b8d435..c9b748a 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,34 +1,4 @@ -alabaster==0.7.12 -Babel==2.9.1 -breathe==4.33.1 -certifi==2021.10.8 -charset-normalizer==2.0.12 -docutils==0.17.1 -exhale>=0.3.0 -idna==3.3 -imagesize==1.3.0 -importlib-metadata>=4.0.0 -Jinja2==3.0.3 -MarkupSafe>=2.0.0 -packaging==21.3 -pybind11>=2.10.3 -pybind11-global>=2.10.3 -Pygments==2.11.2 -pyparsing==3.0.7 -pytz==2021.3 -requests==2.27.1 -setuptools==69.0.3 -snowballstemmer==2.2.0 -Sphinx==4.4.0 -sphinx-rtd-theme==1.0.0 -sphinxcontrib-applehelp==1.0.2 -sphinxcontrib-devhelp==1.0.2 -sphinxcontrib-htmlhelp==2.0.0 -sphinxcontrib-jsmath==1.0.1 -sphinxcontrib-mermaid==0.7.1 -sphinxcontrib-qthelp==1.0.3 -sphinxcontrib-serializinghtml==1.1.5 -tomli==1.2.2 -typing-extensions==4.7.1 -wheel==0.38.4 -zipp>=3.7.0 +sphinx>=7.2,<9 +sphinx-rtd-theme>=2.0 +myst-parser>=2.0 +sphinx-autodoc-typehints>=2.0 diff --git a/docs/scripts/build-wheel-for-docs.sh b/docs/scripts/build-wheel-for-docs.sh new file mode 100755 index 0000000..7229994 --- /dev/null +++ b/docs/scripts/build-wheel-for-docs.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +# the real branch name checked out by RTD +REAL_BRANCH_NAME="${READTHEDOCS_GIT_IDENTIFIER:-}" +if [[ -z "${REAL_BRANCH_NAME}" ]]; then + echo "Error: READTHEDOCS_GIT_IDENTIFIER is empty" >&2 + exit 1 +fi + +echo "RTD REAL_BRANCH_NAME: ${REAL_BRANCH_NAME}" >&2 + +WHEEL_BUILD_DIR="${PWD}/build" +rm -rf "${WHEEL_BUILD_DIR}" +mkdir -p "${WORKDIR}" +cd "${WORKDIR}" + +# get the packager +git clone https://github.com/openfheorg/openfhe-python-packager.git +cd "openfhe-python-packager" + +# override OPENFHE_PYTHON_TAG in ci-vars.sh +sed -i "s|^OPENFHE_PYTHON_TAG=.*|OPENFHE_PYTHON_TAG=${BRANCH}|" ci-vars.sh + +# run the packager +./build_openfhe_wheel.sh + +# find the new wheel +cd build/dist/ +matches=( *.whl ) +if (( ${#matches[@]} == 0 )); then + echo "No .whl file generated" >&2 + exit 1 +elif (( ${#matches[@]} > 1 )); then + echo "Multiple .whl files generated:" >&2 + printf ' %s\n' "${matches[@]}" >&2 + exit 1 +fi + +file="${matches[0]}" + +# return the full path to the new wheel +printf '%s/%s\n' "$(pwd)" "$file" From 2d851f3d6d8773af98711f0c87748aa874238fe5 Mon Sep 17 00:00:00 2001 From: Dmitriy Suponitskiy Date: Tue, 23 Dec 2025 00:32:11 -0500 Subject: [PATCH 2/2] Corrections to document generation for readthedocs.org, added build-docs-locally.sh --- .readthedocs.yaml | 28 +++++++------ docs/requirements.txt | 1 + docs/scripts/build-docs-locally.sh | 61 ++++++++++++++++++++++++++++ docs/scripts/build-wheel-for-docs.sh | 40 ++++++++++++------ 4 files changed, 106 insertions(+), 24 deletions(-) create mode 100755 docs/scripts/build-docs-locally.sh diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 149741f..4adc91d 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -9,18 +9,22 @@ build: os: ubuntu-24.04 tools: python: "3.12" - - commands: - - python -m pip install -U pip - - python -m pip install -r docs/requirements.txt - - # Build wheel using the real RTD branch name and install it - - WHEEL_PATH="$(bash docs/scripts/build-wheel-for-docs.sh)" - - echo "Installing wheel: ${WHEEL_PATH}" - - python -m pip install "${WHEEL_PATH}" - - # Build documentation - - python -m sphinx -b html docs/ "$READTHEDOCS_OUTPUT/html" + apt_packages: + - cmake + - build-essential + # commands: + jobs: + post_install: + - python -m pip install -U pip + - python -m pip install -r docs/requirements.txt + # Build wheel using the real RTD branch name and install it + - | + set -e + WHEEL_PATH="$(bash docs/scripts/build-wheel-for-docs.sh)" + echo "Installing wheel: ${WHEEL_PATH}" + python -m pip install "${WHEEL_PATH}" + # # Build documentation + # - python -m sphinx -b html docs/ "$READTHEDOCS_OUTPUT/html" # Build documentation in the docs/ directory with Sphinx sphinx: diff --git a/docs/requirements.txt b/docs/requirements.txt index c9b748a..1ceb9ed 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -2,3 +2,4 @@ sphinx>=7.2,<9 sphinx-rtd-theme>=2.0 myst-parser>=2.0 sphinx-autodoc-typehints>=2.0 +numpy>=1.26 diff --git a/docs/scripts/build-docs-locally.sh b/docs/scripts/build-docs-locally.sh new file mode 100755 index 0000000..7bd1bc5 --- /dev/null +++ b/docs/scripts/build-docs-locally.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" +SCRIPT_NAME="$(basename -- "${BASH_SOURCE[0]}")" +SCRIPT_PATH="${SCRIPT_DIR}/${SCRIPT_NAME}" +echo "Running ${SCRIPT_PATH}" + +# get to the root directory (should be ./openfhe-python) +ROOT_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd -P)" +echo "cd ${PWD}" + +# cleanup +rm -fr .venv-docs/ build/ docs/_build/ docs/html/ docs/doctrees/ + +# preconditions: you need the same basic tools RTD uses +sudo apt update +sudo apt install -y \ + python3-venv python3-pip \ + build-essential cmake git + +# create and activate a clean venv +python3 -m venv .venv-docs +source .venv-docs/bin/activate +python3 -m pip install -U pip + +# install doc dependencies +# installs only Sphinx + runtime deps (not openfhe yet) +python3 -m pip install -r docs/requirements.txt + +# simulate RTD environment variables and build docs for the current branch +export READTHEDOCS=1 +export READTHEDOCS_GIT_IDENTIFIER="$(git branch --show-current)" +export READTHEDOCS_GIT_COMMIT_HASH="$(git rev-parse HEAD)" + +# build the wheel for docs +WHEEL_PATH="$(bash docs/scripts/build-wheel-for-docs.sh)" +# WHEEL_PATH="$(bash docs/scripts/build-wheel-for-docs.sh | tr -d '\r' | grep -E '\.whl$' | tail -n 1)" +# if [[ -z "$WHEEL_PATH" || ! -f "$WHEEL_PATH" ]]; then +# echo "ERROR: wheel path not found or file missing: '$WHEEL_PATH'" >&2 +# exit 1 +# fi +echo "--------------- Wheel built at: $WHEEL_PATH" + +# Install the built wheel +python3 -m pip install "$WHEEL_PATH" +# Sanity check +python3 - <<'EOF' +import openfhe +print("openfhe import OK") +print("version:", getattr(openfhe, "__version__", "unknown")) +EOF + +# Build the HTML docs +python3 -m sphinx -b html docs/ docs/_build/html +# # Or equivalently +# cd docs +# make html + +# View the docs +firefox docs/_build/html/index.html diff --git a/docs/scripts/build-wheel-for-docs.sh b/docs/scripts/build-wheel-for-docs.sh index 7229994..034ca10 100755 --- a/docs/scripts/build-wheel-for-docs.sh +++ b/docs/scripts/build-wheel-for-docs.sh @@ -1,42 +1,58 @@ -#!/bin/sh +#!/usr/bin/env bash +set -euo pipefail + +exec 3>&1 # save original stdout in FD 3 +exec 1>&2 # redirect all stdout to stderr from here on + +# ---- prerequisites ---- +if ! command -v cmake >/dev/null 2>&1; then + echo "ERROR: cmake is required but not installed" >&2 + exit 1 +fi # the real branch name checked out by RTD REAL_BRANCH_NAME="${READTHEDOCS_GIT_IDENTIFIER:-}" if [[ -z "${REAL_BRANCH_NAME}" ]]; then echo "Error: READTHEDOCS_GIT_IDENTIFIER is empty" >&2 - exit 1 + exit 2 fi echo "RTD REAL_BRANCH_NAME: ${REAL_BRANCH_NAME}" >&2 WHEEL_BUILD_DIR="${PWD}/build" rm -rf "${WHEEL_BUILD_DIR}" -mkdir -p "${WORKDIR}" -cd "${WORKDIR}" +mkdir -p "${WHEEL_BUILD_DIR}" +cd "${WHEEL_BUILD_DIR}" # get the packager git clone https://github.com/openfheorg/openfhe-python-packager.git cd "openfhe-python-packager" +git checkout main # override OPENFHE_PYTHON_TAG in ci-vars.sh -sed -i "s|^OPENFHE_PYTHON_TAG=.*|OPENFHE_PYTHON_TAG=${BRANCH}|" ci-vars.sh +sed -i "s|^OPENFHE_PYTHON_TAG=.*|OPENFHE_PYTHON_TAG=${REAL_BRANCH_NAME}|" ci-vars.sh # run the packager ./build_openfhe_wheel.sh # find the new wheel -cd build/dist/ -matches=( *.whl ) +WHEEL_DIR="build/dist" +if [[ ! -d "$WHEEL_DIR" ]]; then + echo "Error: expected wheel directory '$WHEEL_DIR' not found" >&2 + exit 3 +fi + +mapfile -t matches < <(cd "$WHEEL_DIR" && ls -1 *.whl 2>/dev/null || true) +# cd build/dist/ +# matches=( *.whl ) if (( ${#matches[@]} == 0 )); then echo "No .whl file generated" >&2 - exit 1 + exit 4 elif (( ${#matches[@]} > 1 )); then echo "Multiple .whl files generated:" >&2 printf ' %s\n' "${matches[@]}" >&2 - exit 1 + exit 5 fi -file="${matches[0]}" - # return the full path to the new wheel -printf '%s/%s\n' "$(pwd)" "$file" +printf '%s\n' "${WHEEL_BUILD_DIR}/openfhe-python-packager/${WHEEL_DIR}/${matches[0]}" >&3