Add --version flag to litellm-proxy CLI (#10704)

* Add --version flag to litellm-proxy CLI

```shell
$ litellm-proxy --version
litellm-proxy version: 1.68.1
```

* Return both client and server version

* Update docs

* Add a test for the version command

* Add litellm/proxy/client/health.py
This commit is contained in:
Marc Abramowitz 2025-05-09 18:58:37 -07:00 committed by GitHub
parent e5a08a5ae1
commit 3d87da555a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 126 additions and 1 deletions

View file

@ -4,5 +4,6 @@ from .models import ModelsManagementClient
from .model_groups import ModelGroupsManagementClient
from .exceptions import UnauthorizedError
from .users import UsersManagementClient
from .health import HealthManagementClient
__all__ = ["Client", "ChatClient", "ModelsManagementClient", "ModelGroupsManagementClient", "UsersManagementClient", "UnauthorizedError"]
__all__ = ["Client", "ChatClient", "ModelsManagementClient", "ModelGroupsManagementClient", "UsersManagementClient", "UnauthorizedError", "HealthManagementClient"]

View file

@ -15,6 +15,20 @@ The CLI can be configured using environment variables or command-line options:
- `LITELLM_PROXY_URL`: Base URL of the LiteLLM proxy server (default: http://localhost:4000)
- `LITELLM_PROXY_API_KEY`: API key for authentication
## Global Options
- `--version`, `-v`: Print the LiteLLM Proxy client and server version and exit.
Example:
```bash
litellm-proxy version
# or
litellm-proxy --version
# or
litellm-proxy -v
```
## Commands
### Models Management

View file

@ -11,9 +11,38 @@ from .commands.chat import chat
from .commands.http import http
from .commands.keys import keys
from .commands.users import users
from litellm._version import version as litellm_version
from litellm.proxy.client.health import HealthManagementClient
def print_version(base_url: str, api_key: Optional[str]):
"""Print CLI and server version info."""
click.echo(f"LiteLLM Proxy CLI Version: {litellm_version}")
if base_url:
click.echo(f"LiteLLM Proxy Server URL: {base_url}")
try:
health_client = HealthManagementClient(base_url=base_url, api_key=api_key)
server_version = health_client.get_server_version()
if server_version:
click.echo(f"LiteLLM Proxy Server Version: {server_version}")
else:
click.echo("LiteLLM Proxy Server Version: (unavailable)")
except Exception as e:
click.echo(f"Could not retrieve server version: {e}")
@click.group()
@click.option(
"--version", "-v", is_flag=True, is_eager=True, expose_value=False,
help="Show the LiteLLM Proxy CLI and server version and exit.",
callback=lambda ctx, param, value: (
print_version(
ctx.params.get("base_url") or "http://localhost:4000",
ctx.params.get("api_key")
)
or ctx.exit()
) if value and not ctx.resilient_parsing else None,
)
@click.option(
"--base-url",
envvar="LITELLM_PROXY_URL",
@ -35,6 +64,13 @@ def cli(ctx: click.Context, base_url: str, api_key: Optional[str]) -> None:
ctx.obj["api_key"] = api_key
@cli.command()
@click.pass_context
def version(ctx: click.Context):
"""Show the LiteLLM Proxy CLI and server version."""
print_version(ctx.obj.get("base_url"), ctx.obj.get("api_key"))
# Add the models command group
cli.add_command(models)
# Add the credentials command group

View file

@ -0,0 +1,40 @@
from typing import Optional, Dict, Any
from .http_client import HTTPClient
class HealthManagementClient:
"""
Client for interacting with the health endpoints of the LiteLLM proxy server.
"""
def __init__(self, base_url: str, api_key: Optional[str] = None, timeout: int = 30):
"""
Initialize the HealthManagementClient.
Args:
base_url (str): The base URL of the LiteLLM proxy server (e.g., "http://localhost:4000")
api_key (Optional[str]): API key for authentication. If provided, it will be sent as a Bearer token.
timeout (int): Request timeout in seconds (default: 30)
"""
self._http = HTTPClient(base_url=base_url, api_key=api_key, timeout=timeout)
def get_readiness(self) -> Dict[str, Any]:
"""
Check the readiness of the LiteLLM proxy server.
Returns:
Dict[str, Any]: The readiness status and details from the server.
Raises:
requests.exceptions.RequestException: If the request fails
ValueError: If the response is not valid JSON
"""
return self._http.request("GET", "/health/readiness")
def get_server_version(self) -> Optional[str]:
"""
Get the LiteLLM server version from the readiness endpoint.
Returns:
Optional[str]: The server version if available, otherwise None.
"""
readiness = self.get_readiness()
return readiness.get("litellm_version")

View file

@ -0,0 +1,34 @@
# stdlib imports
from litellm.proxy.client.cli import cli
from litellm._version import version as litellm_version
from click.testing import CliRunner
import pytest
from unittest.mock import patch
import os
@pytest.fixture
def cli_runner():
return CliRunner()
def test_cli_version_flag(cli_runner):
"""Test that --version prints the correct version, server URL, and server version, and exits successfully"""
with patch("litellm.proxy.client.health.HealthManagementClient.get_server_version", return_value="1.2.3"), \
patch.dict(os.environ, {"LITELLM_PROXY_URL": "http://localhost:4000"}):
result = cli_runner.invoke(cli, ["--version"])
assert result.exit_code == 0
assert f"LiteLLM Proxy CLI Version: {litellm_version}" in result.output
assert "LiteLLM Proxy Server URL: http://localhost:4000" in result.output
assert "LiteLLM Proxy Server Version: 1.2.3" in result.output
def test_cli_version_command(cli_runner):
"""Test that 'version' command prints the correct version, server URL, and server version, and exits successfully"""
with patch("litellm.proxy.client.health.HealthManagementClient.get_server_version", return_value="1.2.3"), \
patch.dict(os.environ, {"LITELLM_PROXY_URL": "http://localhost:4000"}):
result = cli_runner.invoke(cli, ["version"])
assert result.exit_code == 0
assert f"LiteLLM Proxy CLI Version: {litellm_version}" in result.output
assert "LiteLLM Proxy Server URL: http://localhost:4000" in result.output
assert "LiteLLM Proxy Server Version: 1.2.3" in result.output