diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 85121f2e90..ac42b6d37c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1086,6 +1086,12 @@ jobs: echo "::error::Expected exactly one wheel, found ${#wheels[@]}" exit 1 fi + if [[ "${PYTHON_VERSION}" == "3.14" ]]; then + # litellm 1.92.0 builds its Rust bridge from source on Python 3.14. + # Its pinned PyO3 supports the stable ABI, but rejects 3.14 unless + # this forward-compatibility opt-in is present. + export PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 + fi WHEEL="${wheels[0]}" # Supply-chain: partial-pin the wheel's direct external deps to a committed constraints # file (deep transitives resolve normally, so they stay py3.14-compatible and can't diff --git a/README.md b/README.md index 098ef03e60..cdc1fc0cb2 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,14 @@ pip install "nemo-platform[all]" nemo setup ``` +On Python 3.14, prefix the install command with +`PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1` while the transitive `litellm` Rust +extension catches up to Python 3.14: + +```bash +PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 pip install "nemo-platform[all]" +``` + Source checkout for development: ```bash diff --git a/docs/cli/index.mdx b/docs/cli/index.mdx index 789ad763f5..0ff58c8f1b 100644 --- a/docs/cli/index.mdx +++ b/docs/cli/index.mdx @@ -42,6 +42,14 @@ Or with uv: uv pip install "nemo-platform[all]" ``` +On Python 3.14, prefix the install command with +`PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1` while the transitive `litellm` Rust +extension catches up to Python 3.14: + +```bash +PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 pip install "nemo-platform[all]" +``` + When installed in a virtual environment, the `nemo` command is only available when the environment is activated. diff --git a/docs/get-started/setup.mdx b/docs/get-started/setup.mdx index 8e85300644..995d6bdf03 100644 --- a/docs/get-started/setup.mdx +++ b/docs/get-started/setup.mdx @@ -29,6 +29,14 @@ source .venv/bin/activate pip install "nemo-platform[all]" ``` +On Python 3.14, prefix the install command with +`PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1` while the transitive `litellm` Rust +extension catches up to Python 3.14: + +```bash +PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 pip install "nemo-platform[all]" +``` + For SDK and CLI usage only, install the base package: ```bash diff --git a/docs/requirements.mdx b/docs/requirements.mdx index 2b5998e5b6..ed8326d5b2 100644 --- a/docs/requirements.mdx +++ b/docs/requirements.mdx @@ -10,7 +10,7 @@ The OSS 0.2.0 documentation is scoped to local setup with the Python package and | Component | Requirement | Notes | |-----------|-------------|-------| -| Python | 3.11, 3.12, 3.13, or 3.14 (`>=3.11,<3.15`) | Use an isolated virtual environment. Python 3.15 and later are not part of the OSS local-install support range. | +| Python | 3.11, 3.12, 3.13, or 3.14 (`>=3.11,<3.15`) | Use an isolated virtual environment. On Python 3.14, prefix `pip install "nemo-platform[all]"` with `PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1` while the transitive `litellm` Rust extension catches up to Python 3.14. Python 3.15 and later are not part of the OSS local-install support range. | | Package installer | `uv` recommended; `pip` supported | The one-line installer sets up `uv` automatically when needed. | | Operating system | Recent Linux or macOS release | See the [Support Matrix](/documentation/reference/support-matrix) for the supported OS list. | | Memory | 8 GB RAM minimum | 16 GB or more is recommended for larger local workflows. | diff --git a/docs/support-matrix.mdx b/docs/support-matrix.mdx index 8dd50d1cb3..6c9f9bd9fb 100644 --- a/docs/support-matrix.mdx +++ b/docs/support-matrix.mdx @@ -11,7 +11,7 @@ Docker Compose, Helm, Kubernetes, and OpenShift deployment paths are not part of | Area | Supported | Notes | |------|-----------|-------| | Deployment mode | `nemo setup` local install | Setup starts local services, registers a model provider, and configures the CLI and SDK. | -| Python | 3.11, 3.12, 3.13, 3.14 (`>=3.11,<3.15`) | Use an isolated virtual environment. Python 3.11 is the lowest supported Python version and Python 3.14 is the highest supported Python version for the OSS local install path. | +| Python | 3.11, 3.12, 3.13, 3.14 (`>=3.11,<3.15`) | Use an isolated virtual environment. On Python 3.14, prefix `pip install "nemo-platform[all]"` with `PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1` while the transitive `litellm` Rust extension catches up to Python 3.14. Python 3.11 is the lowest supported Python version and Python 3.14 is the highest supported Python version for the OSS local install path. | | Linux | Ubuntu 22.04 LTS, Ubuntu 24.04 LTS, RHEL 9, Rocky Linux 9, Debian 12 | Supported for CLI, SDK, local services, and NVIDIA GPU workloads. | | macOS | [macOS Tahoe 26](https://support.apple.com/en-us/122868) and macOS Sequoia 15 | Supported for CLI, SDK, local services, and cloud/provider workflows. Local NVIDIA GPU workloads are not supported on macOS. | | Architecture | x86_64 Linux; Apple Silicon and Intel macOS | NVIDIA GPU workloads require x86_64 Linux. | diff --git a/packages/nemo_platform/README.md b/packages/nemo_platform/README.md index 402d6f65fd..91a7f3aa38 100644 --- a/packages/nemo_platform/README.md +++ b/packages/nemo_platform/README.md @@ -31,6 +31,14 @@ pip install nemo-platform pip install "nemo-platform[all]" ``` +On Python 3.14, prefix the `nemo-platform[all]` install with +`PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1` while the transitive `litellm` Rust +extension catches up to Python 3.14: + +```bash +PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 pip install "nemo-platform[all]" +``` + Then bring up the platform: ```bash diff --git a/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/services/cli.py b/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/services/cli.py index f14f462b0c..d5e4a7cf66 100644 --- a/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/services/cli.py +++ b/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/services/cli.py @@ -71,7 +71,10 @@ def _require_services_extra() -> None: "Running local platform services needs extra components that aren't installed yet.\n" "\n" "Install them with:\n" - " pip install 'nemo-platform[all]'\n", + " pip install 'nemo-platform[all]'\n" + "\n" + "On Python 3.14, use:\n" + " PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 pip install 'nemo-platform[all]'\n", err=True, ) raise typer.Exit(1) diff --git a/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/setup.py b/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/setup.py index 5133eafe4d..1c52e750b1 100644 --- a/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/setup.py +++ b/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/setup.py @@ -762,6 +762,8 @@ def _maybe_start_services( console.print(f"{CROSS} Local services require extra dependencies that aren't installed.") console.print(" Install them with:") console.print(" [cyan]pip install 'nemo-platform\\[all]'[/cyan]") + console.print(" On Python 3.14, use:") + console.print(" [cyan]PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 pip install 'nemo-platform\\[all]'[/cyan]") raise typer.Exit(1) if already_running: diff --git a/packages/nemo_platform_plugin/src/nemo_platform_plugin/README.md b/packages/nemo_platform_plugin/src/nemo_platform_plugin/README.md index 730f19cb0c..251a75506f 100644 --- a/packages/nemo_platform_plugin/src/nemo_platform_plugin/README.md +++ b/packages/nemo_platform_plugin/src/nemo_platform_plugin/README.md @@ -31,6 +31,14 @@ To run a local NeMo Platform that loads and serves your plugin while you develop pip install "nemo-platform[all]" ``` +On Python 3.14, prefix the `nemo-platform[all]` install with +`PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1` while the transitive `litellm` Rust +extension catches up to Python 3.14: + +```bash +PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 pip install "nemo-platform[all]" +``` + ## A minimal plugin A complete NeMo Platform plugin that contributes one HTTP route — a `pyproject.toml` and a service module: diff --git a/sdk/python/nemo-platform/src/nemo_platform/cli/commands/services/cli.py b/sdk/python/nemo-platform/src/nemo_platform/cli/commands/services/cli.py index e9ee1b915e..4df852bb8e 100644 --- a/sdk/python/nemo-platform/src/nemo_platform/cli/commands/services/cli.py +++ b/sdk/python/nemo-platform/src/nemo_platform/cli/commands/services/cli.py @@ -71,7 +71,10 @@ def _require_services_extra() -> None: "Running local platform services needs extra components that aren't installed yet.\n" "\n" "Install them with:\n" - " pip install 'nemo-platform[all]'\n", + " pip install 'nemo-platform[all]'\n" + "\n" + "On Python 3.14, use:\n" + " PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 pip install 'nemo-platform[all]'\n", err=True, ) raise typer.Exit(1) diff --git a/sdk/python/nemo-platform/src/nemo_platform/cli/commands/setup.py b/sdk/python/nemo-platform/src/nemo_platform/cli/commands/setup.py index 03943305c9..29081aa867 100644 --- a/sdk/python/nemo-platform/src/nemo_platform/cli/commands/setup.py +++ b/sdk/python/nemo-platform/src/nemo_platform/cli/commands/setup.py @@ -762,6 +762,8 @@ def _maybe_start_services( console.print(f"{CROSS} Local services require extra dependencies that aren't installed.") console.print(" Install them with:") console.print(" [cyan]pip install 'nemo-platform\\[all]'[/cyan]") + console.print(" On Python 3.14, use:") + console.print(" [cyan]PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 pip install 'nemo-platform\\[all]'[/cyan]") raise typer.Exit(1) if already_running: