mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-19 00:01:29 +00:00
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:
commit
80b0a875dc
9 changed files with 57 additions and 14 deletions
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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"])
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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."
|
||||
|
|
|
|||
|
|
@ -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 = [
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 == ""
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue