Merge pull request #41673 from BerriAI/litellm_deprecate_litellm_proxy_entrypoint

feat(cli): deprecate the litellm-proxy entrypoint in favour of lite
This commit is contained in:
Mateo Wang 2026-09-17 14:54:47 -07:00 committed by GitHub
commit 80b0a875dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 57 additions and 14 deletions

View file

@ -3,7 +3,7 @@
Example: Using CLI token with LiteLLM SDK
This example shows how to use the CLI authentication token
in your Python scripts after running `litellm-proxy login`.
in your Python scripts after running `lite login`.
"""
from textwrap import indent
@ -22,7 +22,7 @@ def main():
api_key = litellm.get_litellm_gateway_api_key()
if not api_key:
print("❌ No CLI token found. Please run 'litellm-proxy login' first.")
print("❌ No CLI token found. Please run 'lite login' first.")
return
print("✅ Found CLI token.")
@ -58,6 +58,6 @@ if __name__ == "__main__":
main()
print("\n💡 Tips:")
print("1. Run 'litellm-proxy login' to authenticate first")
print("1. Run 'lite login' to authenticate first")
print("2. Replace 'https://your-proxy.com' with your actual proxy URL")
print("3. The token is stored in your OS keychain, or in ~/.litellm/token.json when there is none")

View file

@ -1,5 +1,5 @@
"""CLI package for LiteLLM Proxy Client."""
from .main import cli
from .main import cli, litellm_proxy_cli
__all__ = ["cli"]
__all__ = ["cli", "litellm_proxy_cli"]

View file

@ -36,8 +36,8 @@ def migrate(ctx: click.Context, check_only: bool, dry_run: bool):
resumable; safe to re-run after an interruption.
Examples:
litellm-proxy encryption migrate --check # attestation scan, no writes
litellm-proxy encryption migrate # perform the migration
lite encryption migrate --check # attestation scan, no writes
lite encryption migrate # perform the migration
"""
client: Final = HTTPClient(ctx.obj["base_url"], ctx.obj["api_key"])

View file

@ -168,5 +168,16 @@ cli.add_command(configure_group)
cli.add_command(unconfigure_group)
LITELLM_PROXY_DEPRECATION_NOTICE: Final = (
"The `litellm-proxy` command is deprecated and will be removed in a future release; "
"run `lite` instead, it takes the same commands and options."
)
def litellm_proxy_cli() -> None:
click.secho(LITELLM_PROXY_DEPRECATION_NOTICE, err=True, fg="yellow")
cli()
if __name__ == "__main__":
cli()

View file

@ -354,7 +354,7 @@ def _get_cli_sso_flow_or_raise(login_id: str | None, cache: DualCache) -> dict:
status_code=400,
detail=(
"Your litellm CLI is out of date and uses a login flow this proxy no longer supports. "
"Upgrade it with `pip install -U 'litellm[proxy]'` and run `litellm-proxy login` again."
"Upgrade it with `pip install -U 'litellm[proxy]'` and run `lite login` again."
),
)
if not _is_valid_cli_sso_login_id(login_id):
@ -375,7 +375,7 @@ def _get_cli_sso_flow_or_raise(login_id: str | None, cache: DualCache) -> dict:
raise HTTPException(
status_code=400,
detail=(
"CLI login session not found or expired. Run `litellm-proxy login` again. "
"CLI login session not found or expired. Run `lite login` again. "
"If this happens immediately after starting a login, the proxy is likely running multiple "
"replicas without a shared cache; configure a Redis cache "
"so every replica can see the login session."

View file

@ -174,7 +174,7 @@ proxy-runtime = [
[project.scripts]
litellm = "litellm:run_server"
lite = "litellm.proxy.client.cli:cli"
litellm-proxy = "litellm.proxy.client.cli:cli"
litellm-proxy = "litellm.proxy.client.cli:litellm_proxy_cli"
[dependency-groups]
dev = [

View file

@ -367,7 +367,7 @@ async def obtain_cli_sso_token_via_poll_flow(
models: list[str],
) -> str:
"""
Obtain a CLI SSO JWT through the same HTTP flow as `litellm-proxy login`:
Obtain a CLI SSO JWT through the same HTTP flow as `lite login`:
/sso/cli/start -> (SSO callback) -> /sso/cli/complete -> /sso/cli/poll.
When the proxy SSO session cache is not shared with the test runner (otel CI
@ -551,7 +551,7 @@ async def test_team_budget_enforcement():
@pytest.mark.asyncio
async def test_team_budget_enforcement_cli_sso_token():
"""
Team budget enforcement for CLI SSO session tokens (litellm-proxy login JWT).
Team budget enforcement for CLI SSO session tokens (lite login JWT).
1. Create team with a tiny max_budget and a user on that team
2. Obtain a CLI SSO JWT (HTTP poll flow when Redis is shared, else mint)

View file

@ -1,4 +1,4 @@
"""CLI tests for the ``litellm-proxy encryption migrate`` command.
"""CLI tests for the ``lite encryption migrate`` command.
The HTTP client is mocked, so these assert the command's request routing (GET
check vs POST migrate, dry-run param) and its residual-state messaging without a

View file

@ -1,7 +1,9 @@
# stdlib imports
import json
import os
import sys
from pathlib import Path
from typing import Final
from unittest.mock import Mock, patch
import pytest
@ -9,7 +11,8 @@ from click.testing import CliRunner
import litellm.proxy.client.cli
from litellm._version import version as litellm_version
from litellm.proxy.client.cli import cli
from litellm.proxy.client.cli import cli, litellm_proxy_cli
from litellm.proxy.client.cli.main import LITELLM_PROXY_DEPRECATION_NOTICE
@pytest.fixture
@ -234,3 +237,32 @@ def test_version_flag_never_sends_api_key_to_unnamed_server(cli_runner, isolated
assert all(url.startswith("https://flag-proxy.example.com") for url in requested_urls)
sent_keys = [call.kwargs["headers"].get("Authorization") for call in mock_request.call_args_list]
assert sent_keys == ["Bearer sk-intended-for-flag-proxy"] * len(requested_urls)
def test_litellm_proxy_entrypoint_prints_deprecation_notice_on_stderr_and_still_runs(monkeypatch, capsys, requests_mock):
requests_mock.get("http://localhost:4000/health/readiness", json={"litellm_version": "1.2.3"})
monkeypatch.setattr(sys, "argv", ["litellm-proxy", "--version"])
monkeypatch.setenv("LITELLM_PROXY_URL", "http://localhost:4000")
with pytest.raises(SystemExit) as exit_info:
litellm_proxy_cli()
captured: Final = capsys.readouterr()
assert exit_info.value.code == 0
assert captured.err.strip() == LITELLM_PROXY_DEPRECATION_NOTICE
assert f"LiteLLM Proxy CLI Version: {litellm_version}" in captured.out
assert "LiteLLM Proxy Server Version: 1.2.3" in captured.out
assert "deprecated" not in captured.out
def test_lite_entrypoint_prints_nothing_on_stderr(monkeypatch, capsys, requests_mock):
requests_mock.get("http://localhost:4000/health/readiness", json={"litellm_version": "1.2.3"})
monkeypatch.setattr(sys, "argv", ["lite", "--version"])
monkeypatch.setenv("LITELLM_PROXY_URL", "http://localhost:4000")
with pytest.raises(SystemExit) as exit_info:
cli()
captured: Final = capsys.readouterr()
assert exit_info.value.code == 0
assert "LiteLLM Proxy Server Version: 1.2.3" in captured.out
assert f"LiteLLM Proxy CLI Version: {litellm_version}" in captured.out
assert captured.err == ""