diff --git a/docs/reference/cli-commands.md b/docs/reference/cli-commands.md index 0e6d6dce9..8982cda6d 100644 --- a/docs/reference/cli-commands.md +++ b/docs/reference/cli-commands.md @@ -547,6 +547,44 @@ ng_version +json=true --- +### `ng_pip_list` / `nemo_gym_pip_list` + +Each server has its own isolated virtual environment. To inspect the packages: + +**Parameters** + +```{list-table} +:header-rows: 1 +:widths: 20 10 70 + +* - Parameter + - Type + - Description +* - `entrypoint` + - str + - The relative entrypoint path to the server directory +* - `format` + - Optional[str] + - Output format for pip list. Options: 'columns' (default), 'freeze', 'json'. Default: `None`. +* - `outdated` + - bool + - List outdated packages. Default: `False`. +``` + +**Examples** + +```bash +# List all packages +ng_pip_list +entrypoint=resources_servers/example_single_tool_call + +# Output as JSON +ng_pip_list +entrypoint=resources_servers/example_single_tool_call +format=json + +# Check for outdated packages +ng_pip_list +entrypoint=resources_servers/example_single_tool_call +outdated=true +``` + + ## Getting Help For detailed help on any command, run it with `+help=true` or `+h=true`: diff --git a/nemo_gym/cli.py b/nemo_gym/cli.py index 40e1ac447..d7d4c5f0b 100644 --- a/nemo_gym/cli.py +++ b/nemo_gym/cli.py @@ -791,6 +791,50 @@ def display_help(): # pragma: no cover print(script) +class PipListConfig(RunConfig): + format: Optional[str] = Field( + default=None, + description="Output format for pip list. Options: 'columns' (default), 'freeze', 'json'", + ) + outdated: bool = Field( + default=False, + description="List outdated packages", + ) + + +def pip_list(): # pragma: no cover + """List packages installed in a server's virtual environment.""" + global_config_dict = get_global_config_dict() + config = PipListConfig.model_validate(global_config_dict) + + dir_path = Path(config.entrypoint) + venv_path = dir_path / ".venv" + + if not venv_path.exists(): + print(f" Virtual environment not found at: {venv_path}") + print(" Run tests or setup the server first using:") + print(f" ng_test +entrypoint={config.entrypoint}") + exit(1) + + pip_list_cmd = "uv pip list" + if config.format: + pip_list_cmd += f" --format={config.format}" + if config.outdated: + pip_list_cmd += " --outdated" + + command = f"""cd {dir_path} \\ + && source .venv/bin/activate \\ + && {pip_list_cmd}""" + + print(f" Package list for: {config.entrypoint}") + print(f"Virtual environment: {venv_path.absolute()}") + print("-" * 72) + + proc = _run_command(command, dir_path) + return_code = proc.wait() + exit(return_code) + + class VersionConfig(BaseNeMoGymCLIConfig): """ Display gym version and system information. diff --git a/pyproject.toml b/pyproject.toml index e211d6f24..29d0c5003 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -284,11 +284,14 @@ ng_dump_config = "nemo_gym.cli:dump_config" nemo_gym_help = "nemo_gym.cli:display_help" ng_help = "nemo_gym.cli:display_help" +# Environment-specific uv pip list +nemo_gym_pip_list = "nemo_gym.cli:pip_list" +ng_pip_list = "nemo_gym.cli:pip_list" + # Display version nemo_gym_version = "nemo_gym.cli:version" ng_version = "nemo_gym.cli:version" - [tool.setuptools.packages.find] where = ["."] include = ["resources_servers", "responses_api_agents", "responses_api_models", "nemo_gym"]