From c17ee1bf5ac2c1fb1b14a7a692e4109e76c1cbf7 Mon Sep 17 00:00:00 2001 From: William FH <13333726+hinthornw@users.noreply.github.com> Date: Mon, 9 Jun 2025 08:57:29 -0700 Subject: [PATCH] feat: [CLI] Add support for building deps with uv (#4995) --- libs/cli/langgraph_cli/config.py | 40 ++++++- libs/cli/pyproject.toml | 2 +- libs/cli/tests/unit_tests/cli/test_cli.py | 8 +- libs/cli/tests/unit_tests/test_config.py | 133 +++++++++++++++------- libs/cli/uv.lock | 2 +- 5 files changed, 132 insertions(+), 53 deletions(-) diff --git a/libs/cli/langgraph_cli/config.py b/libs/cli/langgraph_cli/config.py index e9f679247..4660e3223 100644 --- a/libs/cli/langgraph_cli/config.py +++ b/libs/cli/langgraph_cli/config.py @@ -1,6 +1,7 @@ import json import os import pathlib +import re import textwrap from collections import Counter from typing import Any, Literal, NamedTuple, Optional, TypedDict, Union @@ -461,7 +462,7 @@ class Config(TypedDict, total=False): PIP_CLEANUP_LINES = """# -- Ensure user deps didn't inadvertently overwrite langgraph-api RUN mkdir -p /api/langgraph_api /api/langgraph_runtime /api/langgraph_license && \ touch /api/langgraph_api/__init__.py /api/langgraph_runtime/__init__.py /api/langgraph_license/__init__.py -RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir --no-deps -e /api +RUN PYTHONDONTWRITEBYTECODE=1 {install_cmd} --no-cache-dir --no-deps -e /api # -- End of ensuring user deps didn't inadvertently overwrite langgraph-api -- # -- Removing pip from the final image ~<:===~~~ -- RUN pip uninstall -y pip setuptools wheel && \ @@ -470,6 +471,7 @@ RUN pip uninstall -y pip setuptools wheel && \ # pip removal for wolfi RUN rm -rf /usr/lib/python*/site-packages/pip* /usr/lib/python*/site-packages/setuptools* /usr/lib/python*/site-packages/wheel* && \ find /usr/bin -name "pip*" -delete || true +{uv_removal} # -- End of pip removal --""" @@ -1089,16 +1091,38 @@ def _get_node_pm_install_cmd(config_path: pathlib.Path, config: Config) -> str: return install_cmd +semver_pattern = re.compile(r":(\d+(?:\.\d+)?(?:\.\d+)?)(?:-|$)") + + +def _image_supports_uv(base_image: str) -> bool: + if base_image == "langchain/langgraph-trial": + return False + match = semver_pattern.search(base_image) + if not match: + # Default image (langchain/langgraph-api) supports it. + return True + + version_str = match.group(1) + version = tuple(map(int, version_str.split("."))) + min_uv = (0, 2, 47) + return version >= min_uv + + def python_config_to_docker( config_path: pathlib.Path, config: Config, base_image: str, ) -> tuple[str, dict[str, str]]: """Generate a Dockerfile from the configuration.""" + if _image_supports_uv(base_image): + install_cmd = "uv pip install --system" + uv_removal = "RUN uv pip uninstall --system pip setuptools wheel && rm /usr/bin/uv /usr/bin/uvx" + else: + install_cmd = "pip install" + uv_removal = "" + # configure pip - pip_install = ( - "PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt" - ) + pip_install = f"PYTHONDONTWRITEBYTECODE=1 {install_cmd} --no-cache-dir -c /api/constraints.txt" if config.get("pip_config_file"): pip_install = f"PIP_CONFIG_FILE=/pipconfig.txt {pip_install}" pip_config_file_str = ( @@ -1151,7 +1175,10 @@ RUN set -ex && \\ 'name = "{fullpath.name}"' \\ 'version = "0.1"' \\ '[tool.setuptools.package-data]' \\ - '"*" = ["**/*"]'; do \\ + '"*" = ["**/*"]' \\ + '[build-system]' \\ + 'requires = ["setuptools>=61"]' \\ + 'build-backend = "setuptools.build_meta"'; do \\ echo "$line" >> /deps/__outer_{fullpath.name}/pyproject.toml; \\ done # -- End of non-package dependency {fullpath.name} --""" @@ -1240,7 +1267,8 @@ ADD {relpath} /deps/{name} "", js_inst_str, "", - PIP_CLEANUP_LINES, # Add pip cleanup after all installations are complete + # Add pip cleanup after all installations are complete + PIP_CLEANUP_LINES.format(install_cmd=install_cmd, uv_removal=uv_removal), "", f"WORKDIR {local_deps.working_dir}" if local_deps.working_dir else "", ] diff --git a/libs/cli/pyproject.toml b/libs/cli/pyproject.toml index e1e729fab..0756c8bfe 100644 --- a/libs/cli/pyproject.toml +++ b/libs/cli/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "langgraph-cli" -version = "0.2.12" +version = "0.3.1" description = "CLI for interacting with LangGraph API" authors = [] requires-python = ">=3.9" diff --git a/libs/cli/tests/unit_tests/cli/test_cli.py b/libs/cli/tests/unit_tests/cli/test_cli.py index c68c13227..d07d6f7a8 100644 --- a/libs/cli/tests/unit_tests/cli/test_cli.py +++ b/libs/cli/tests/unit_tests/cli/test_cli.py @@ -14,6 +14,10 @@ from langgraph_cli.config import PIP_CLEANUP_LINES, Config, validate_config from langgraph_cli.docker import DEFAULT_POSTGRES_URI, DockerCapabilities, Version from langgraph_cli.util import clean_empty_lines +FORMATTED_CLEANUP_LINES = PIP_CLEANUP_LINES.format( + install_cmd="uv pip install --system", + uv_removal="RUN uv pip uninstall --system pip setuptools wheel && rm /usr/bin/uv /usr/bin/uvx", +) DEFAULT_DOCKER_CAPABILITIES = DockerCapabilities( version_docker=Version(26, 1, 1), version_compose=Version(2, 27, 0), @@ -144,10 +148,10 @@ services: COPY --from=cli_1 . /deps/cli_1 # -- End of local package ../../.. -- # -- Installing all local dependencies -- - RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/* + RUN PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e /deps/* # -- End of local dependencies install -- ENV LANGSERVE_GRAPHS='{{"agent": "agent.py:graph"}}' -{textwrap.indent(textwrap.dedent(PIP_CLEANUP_LINES), " ")} +{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")} WORKDIR /deps/cli develop: diff --git a/libs/cli/tests/unit_tests/test_config.py b/libs/cli/tests/unit_tests/test_config.py index 060b4ab0d..112f16443 100644 --- a/libs/cli/tests/unit_tests/test_config.py +++ b/libs/cli/tests/unit_tests/test_config.py @@ -17,6 +17,11 @@ from langgraph_cli.config import ( ) from langgraph_cli.util import clean_empty_lines +FORMATTED_CLEANUP_LINES = PIP_CLEANUP_LINES.format( + install_cmd="uv pip install --system", + uv_removal="RUN uv pip uninstall --system pip setuptools wheel && rm /usr/bin/uv /usr/bin/uvx", +) + PATH_TO_CONFIG = pathlib.Path(__file__).parent / "test_config.json" @@ -345,7 +350,7 @@ def test_config_to_docker_simple(): FROM langchain/langgraph-api:3.11 # -- Installing local requirements -- COPY --from=__outer_requirements.txt requirements.txt /deps/__outer_graphs_reqs_a/graphs_reqs_a/requirements.txt -RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -r /deps/__outer_graphs_reqs_a/graphs_reqs_a/requirements.txt +RUN PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -r /deps/__outer_graphs_reqs_a/graphs_reqs_a/requirements.txt # -- End of local requirements install -- # -- Adding local package ../../examples -- COPY --from=examples . /deps/examples @@ -357,7 +362,10 @@ RUN set -ex && \\ 'name = "unit_tests"' \\ 'version = "0.1"' \\ '[tool.setuptools.package-data]' \\ - '"*" = ["**/*"]'; do \\ + '"*" = ["**/*"]' \\ + '[build-system]' \\ + 'requires = ["setuptools>=61"]' \\ + 'build-backend = "setuptools.build_meta"'; do \\ echo "$line" >> /deps/__outer_unit_tests/pyproject.toml; \\ done # -- End of non-package dependency unit_tests -- @@ -368,16 +376,19 @@ RUN set -ex && \\ 'name = "graphs_reqs_a"' \\ 'version = "0.1"' \\ '[tool.setuptools.package-data]' \\ - '"*" = ["**/*"]'; do \\ + '"*" = ["**/*"]' \\ + '[build-system]' \\ + 'requires = ["setuptools>=61"]' \\ + 'build-backend = "setuptools.build_meta"'; do \\ echo "$line" >> /deps/__outer_graphs_reqs_a/pyproject.toml; \\ done # -- End of non-package dependency graphs_reqs_a -- # -- Installing all local dependencies -- -RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/* +RUN PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e /deps/* # -- End of local dependencies install -- ENV LANGGRAPH_HTTP='{{"app": "/deps/examples/my_app.py:app"}}' ENV LANGSERVE_GRAPHS='{{"agent": "/deps/__outer_unit_tests/unit_tests/agent.py:graph"}}' -{PIP_CLEANUP_LINES} +{FORMATTED_CLEANUP_LINES} WORKDIR /deps/__outer_unit_tests/unit_tests\ """ assert clean_empty_lines(actual_docker_stdin) == expected_docker_stdin @@ -407,7 +418,10 @@ RUN set -ex && \\ 'name = "unit_tests"' \\ 'version = "0.1"' \\ '[tool.setuptools.package-data]' \\ - '"*" = ["**/*"]'; do \\ + '"*" = ["**/*"]' \\ + '[build-system]' \\ + 'requires = ["setuptools>=61"]' \\ + 'build-backend = "setuptools.build_meta"'; do \\ echo "$line" >> /deps/__outer_unit_tests/pyproject.toml; \\ done # -- End of non-package dependency unit_tests -- @@ -418,16 +432,19 @@ RUN set -ex && \\ 'name = "tests"' \\ 'version = "0.1"' \\ '[tool.setuptools.package-data]' \\ - '"*" = ["**/*"]'; do \\ + '"*" = ["**/*"]' \\ + '[build-system]' \\ + 'requires = ["setuptools>=61"]' \\ + 'build-backend = "setuptools.build_meta"'; do \\ echo "$line" >> /deps/__outer_tests/pyproject.toml; \\ done # -- End of non-package dependency tests -- # -- Installing all local dependencies -- -RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/* +RUN PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e /deps/* # -- End of local dependencies install -- ENV LANGSERVE_GRAPHS='{"agent": "/deps/__outer_unit_tests/unit_tests/agent.py:graph"}' """ - + PIP_CLEANUP_LINES + + FORMATTED_CLEANUP_LINES + """ WORKDIR /deps/__outer_unit_tests/unit_tests\ """ @@ -462,16 +479,19 @@ RUN set -ex && \\ 'name = "unit_tests"' \\ 'version = "0.1"' \\ '[tool.setuptools.package-data]' \\ - '"*" = ["**/*"]'; do \\ + '"*" = ["**/*"]' \\ + '[build-system]' \\ + 'requires = ["setuptools>=61"]' \\ + 'build-backend = "setuptools.build_meta"'; do \\ echo "$line" >> /deps/__outer_unit_tests/pyproject.toml; \\ done # -- End of non-package dependency unit_tests -- # -- Installing all local dependencies -- -RUN PIP_CONFIG_FILE=/pipconfig.txt PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/* +RUN PIP_CONFIG_FILE=/pipconfig.txt PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e /deps/* # -- End of local dependencies install -- ENV LANGSERVE_GRAPHS='{"agent": "/deps/__outer_unit_tests/unit_tests/agent.py:graph"}' """ - + PIP_CLEANUP_LINES + + FORMATTED_CLEANUP_LINES + """ WORKDIR /deps/__outer_unit_tests/unit_tests\ """ @@ -521,15 +541,18 @@ RUN set -ex && \\ 'name = "graphs"' \\ 'version = "0.1"' \\ '[tool.setuptools.package-data]' \\ - '"*" = ["**/*"]'; do \\ + '"*" = ["**/*"]' \\ + '[build-system]' \\ + 'requires = ["setuptools>=61"]' \\ + 'build-backend = "setuptools.build_meta"'; do \\ echo "$line" >> /deps/__outer_graphs/pyproject.toml; \\ done # -- End of non-package dependency graphs -- # -- Installing all local dependencies -- -RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/* +RUN PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e /deps/* # -- End of local dependencies install -- ENV LANGSERVE_GRAPHS='{{"agent": "/deps/__outer_graphs/src/agent.py:graph"}}' -{PIP_CLEANUP_LINES}\ +{FORMATTED_CLEANUP_LINES}\ """ assert clean_empty_lines(actual_docker_stdin) == expected_docker_stdin assert additional_contexts == {} @@ -562,11 +585,11 @@ dependencies = ["langchain"]""" ADD . /deps/unit_tests # -- End of local package . -- # -- Installing all local dependencies -- -RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/* +RUN PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e /deps/* # -- End of local dependencies install -- ENV LANGSERVE_GRAPHS='{"agent": "/deps/unit_tests/graphs/agent.py:graph"}' """ - + PIP_CLEANUP_LINES + + FORMATTED_CLEANUP_LINES + "\n" + "WORKDIR /deps/unit_tests" "" @@ -594,7 +617,7 @@ def test_config_to_docker_end_to_end(): ARG meow ARG foo ADD pipconfig.txt /pipconfig.txt -RUN PIP_CONFIG_FILE=/pipconfig.txt PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt langchain langchain_openai +RUN PIP_CONFIG_FILE=/pipconfig.txt PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt langchain langchain_openai # -- Adding non-package dependency graphs -- ADD ./graphs/ /deps/__outer_graphs/src RUN set -ex && \\ @@ -602,15 +625,18 @@ RUN set -ex && \\ 'name = "graphs"' \\ 'version = "0.1"' \\ '[tool.setuptools.package-data]' \\ - '"*" = ["**/*"]'; do \\ + '"*" = ["**/*"]' \\ + '[build-system]' \\ + 'requires = ["setuptools>=61"]' \\ + 'build-backend = "setuptools.build_meta"'; do \\ echo "$line" >> /deps/__outer_graphs/pyproject.toml; \\ done # -- End of non-package dependency graphs -- # -- Installing all local dependencies -- -RUN PIP_CONFIG_FILE=/pipconfig.txt PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/* +RUN PIP_CONFIG_FILE=/pipconfig.txt PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e /deps/* # -- End of local dependencies install -- ENV LANGSERVE_GRAPHS='{{"agent": "/deps/__outer_graphs/src/agent.py:graph"}}' -{PIP_CLEANUP_LINES}""" +{FORMATTED_CLEANUP_LINES}""" assert clean_empty_lines(actual_docker_stdin) == expected_docker_stdin assert additional_contexts == {} @@ -705,12 +731,15 @@ RUN set -ex && \\ 'name = "unit_tests"' \\ 'version = "0.1"' \\ '[tool.setuptools.package-data]' \\ - '"*" = ["**/*"]'; do \\ + '"*" = ["**/*"]' \\ + '[build-system]' \\ + 'requires = ["setuptools>=61"]' \\ + 'build-backend = "setuptools.build_meta"'; do \\ echo "$line" >> /deps/__outer_unit_tests/pyproject.toml; \\ done # -- End of non-package dependency unit_tests -- # -- Installing all local dependencies -- -RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/* +RUN PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e /deps/* # -- End of local dependencies install -- ENV LANGGRAPH_UI='{{"agent": "./graphs/agent.ui.jsx"}}' ENV LANGGRAPH_UI_CONFIG='{{"shared": ["nuqs"]}}' @@ -719,7 +748,7 @@ ENV LANGSERVE_GRAPHS='{{"agent": "/deps/__outer_unit_tests/unit_tests/agent.py:g ENV NODE_VERSION=20 RUN cd /deps/__outer_unit_tests/unit_tests && npm i && tsx /api/langgraph_api/js/build.mts # -- End of JS dependencies install -- -{PIP_CLEANUP_LINES} +{FORMATTED_CLEANUP_LINES} WORKDIR /deps/__outer_unit_tests/unit_tests""" assert clean_empty_lines(actual_docker_stdin) == expected_docker_stdin @@ -748,19 +777,22 @@ RUN set -ex && \\ 'name = "unit_tests"' \\ 'version = "0.1"' \\ '[tool.setuptools.package-data]' \\ - '"*" = ["**/*"]'; do \\ + '"*" = ["**/*"]' \\ + '[build-system]' \\ + 'requires = ["setuptools>=61"]' \\ + 'build-backend = "setuptools.build_meta"'; do \\ echo "$line" >> /deps/__outer_unit_tests/pyproject.toml; \\ done # -- End of non-package dependency unit_tests -- # -- Installing all local dependencies -- -RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/* +RUN PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e /deps/* # -- End of local dependencies install -- ENV LANGSERVE_GRAPHS='{{"python": "/deps/__outer_unit_tests/unit_tests/multiplatform/python.py:graph", "js": "/deps/__outer_unit_tests/unit_tests/multiplatform/js.mts:graph"}}' # -- Installing JS dependencies -- ENV NODE_VERSION=22 RUN cd /deps/__outer_unit_tests/unit_tests && npm i && tsx /api/langgraph_api/js/build.mts # -- End of JS dependencies install -- -{PIP_CLEANUP_LINES} +{FORMATTED_CLEANUP_LINES} WORKDIR /deps/__outer_unit_tests/unit_tests""" assert clean_empty_lines(actual_docker_stdin) == expected_docker_stdin @@ -770,7 +802,7 @@ WORKDIR /deps/__outer_unit_tests/unit_tests""" # config_to_compose def test_config_to_compose_simple_config(): graphs = {"agent": "./agent.py:graph"} - # Create a properly indented version of PIP_CLEANUP_LINES for compose files + # Create a properly indented version of FORMATTED_CLEANUP_LINES for compose files expected_compose_stdin = f""" pull_policy: build build: @@ -784,15 +816,18 @@ def test_config_to_compose_simple_config(): 'name = "unit_tests"' \\ 'version = "0.1"' \\ '[tool.setuptools.package-data]' \\ - '"*" = ["**/*"]'; do \\ + '"*" = ["**/*"]' \\ + '[build-system]' \\ + 'requires = ["setuptools>=61"]' \\ + 'build-backend = "setuptools.build_meta"'; do \\ echo "$line" >> /deps/__outer_unit_tests/pyproject.toml; \\ done # -- End of non-package dependency unit_tests -- # -- Installing all local dependencies -- - RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/* + RUN PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e /deps/* # -- End of local dependencies install -- ENV LANGSERVE_GRAPHS='{{"agent": "/deps/__outer_unit_tests/unit_tests/agent.py:graph"}}' -{textwrap.indent(textwrap.dedent(PIP_CLEANUP_LINES), " ")} +{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")} WORKDIR /deps/__outer_unit_tests/unit_tests """ actual_compose_stdin = config_to_compose( @@ -822,15 +857,18 @@ def test_config_to_compose_env_vars(): 'name = "unit_tests"' \\ 'version = "0.1"' \\ '[tool.setuptools.package-data]' \\ - '"*" = ["**/*"]'; do \\ + '"*" = ["**/*"]' \\ + '[build-system]' \\ + 'requires = ["setuptools>=61"]' \\ + 'build-backend = "setuptools.build_meta"'; do \\ echo "$line" >> /deps/__outer_unit_tests/pyproject.toml; \\ done # -- End of non-package dependency unit_tests -- # -- Installing all local dependencies -- - RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/* + RUN PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e /deps/* # -- End of local dependencies install -- ENV LANGSERVE_GRAPHS='{{"agent": "/deps/__outer_unit_tests/unit_tests/agent.py:graph"}}' -{textwrap.indent(textwrap.dedent(PIP_CLEANUP_LINES), " ")} +{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")} WORKDIR /deps/__outer_unit_tests/unit_tests """ openai_api_key = "key" @@ -864,15 +902,18 @@ def test_config_to_compose_env_file(): 'name = "unit_tests"' \\ 'version = "0.1"' \\ '[tool.setuptools.package-data]' \\ - '"*" = ["**/*"]'; do \\ + '"*" = ["**/*"]' \\ + '[build-system]' \\ + 'requires = ["setuptools>=61"]' \\ + 'build-backend = "setuptools.build_meta"'; do \\ echo "$line" >> /deps/__outer_unit_tests/pyproject.toml; \\ done # -- End of non-package dependency unit_tests -- # -- Installing all local dependencies -- - RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/* + RUN PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e /deps/* # -- End of local dependencies install -- ENV LANGSERVE_GRAPHS='{{"agent": "/deps/__outer_unit_tests/unit_tests/agent.py:graph"}}' -{textwrap.indent(textwrap.dedent(PIP_CLEANUP_LINES), " ")} +{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")} WORKDIR /deps/__outer_unit_tests/unit_tests """ actual_compose_stdin = config_to_compose( @@ -899,15 +940,18 @@ def test_config_to_compose_watch(): 'name = "unit_tests"' \\ 'version = "0.1"' \\ '[tool.setuptools.package-data]' \\ - '"*" = ["**/*"]'; do \\ + '"*" = ["**/*"]' \\ + '[build-system]' \\ + 'requires = ["setuptools>=61"]' \\ + 'build-backend = "setuptools.build_meta"'; do \\ echo "$line" >> /deps/__outer_unit_tests/pyproject.toml; \\ done # -- End of non-package dependency unit_tests -- # -- Installing all local dependencies -- - RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/* + RUN PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e /deps/* # -- End of local dependencies install -- ENV LANGSERVE_GRAPHS='{{"agent": "/deps/__outer_unit_tests/unit_tests/agent.py:graph"}}' -{textwrap.indent(textwrap.dedent(PIP_CLEANUP_LINES), " ")} +{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")} WORKDIR /deps/__outer_unit_tests/unit_tests develop: @@ -943,15 +987,18 @@ def test_config_to_compose_end_to_end(): 'name = "unit_tests"' \\ 'version = "0.1"' \\ '[tool.setuptools.package-data]' \\ - '"*" = ["**/*"]'; do \\ + '"*" = ["**/*"]' \\ + '[build-system]' \\ + 'requires = ["setuptools>=61"]' \\ + 'build-backend = "setuptools.build_meta"'; do \\ echo "$line" >> /deps/__outer_unit_tests/pyproject.toml; \\ done # -- End of non-package dependency unit_tests -- # -- Installing all local dependencies -- - RUN PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/* + RUN PYTHONDONTWRITEBYTECODE=1 uv pip install --system --no-cache-dir -c /api/constraints.txt -e /deps/* # -- End of local dependencies install -- ENV LANGSERVE_GRAPHS='{{"agent": "/deps/__outer_unit_tests/unit_tests/agent.py:graph"}}' -{textwrap.indent(textwrap.dedent(PIP_CLEANUP_LINES), " ")} +{textwrap.indent(textwrap.dedent(FORMATTED_CLEANUP_LINES), " ")} WORKDIR /deps/__outer_unit_tests/unit_tests develop: diff --git a/libs/cli/uv.lock b/libs/cli/uv.lock index 7962a806e..114732bbe 100644 --- a/libs/cli/uv.lock +++ b/libs/cli/uv.lock @@ -501,7 +501,7 @@ wheels = [ [[package]] name = "langgraph-cli" -version = "0.2.12" +version = "0.3.1" source = { editable = "." } dependencies = [ { name = "click" },