mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-28 06:23:07 +00:00
fix(proxy): keep show_banner() SDK-free, pick the JSON banner in initialize()
Since #46803 the `lite` shell calls show_banner() against an uninitialized litellm package, and reading litellm.json_logs inside it initialized the whole SDK at the banner (0.14 s to 0.83 s for a bare `lite` here, the seconds that PR removed on small VMs). show_banner() is back to its main version; the proxy's initialize() now emits the JSON banner record itself and calls show_banner() only in plain mode. The banner unit tests move to the initialize() call site.
This commit is contained in:
parent
4fa139f8c0
commit
e2303a3925
4 changed files with 41 additions and 44 deletions
|
|
@ -11,12 +11,6 @@ LITELLM_BANNER: Final = """ ██╗ ██╗████████╗
|
|||
|
||||
def show_banner():
|
||||
"""Display the LiteLLM CLI banner."""
|
||||
import litellm
|
||||
from litellm._logging import print_startup_message
|
||||
|
||||
if litellm.json_logs:
|
||||
print_startup_message(LITELLM_BANNER)
|
||||
return
|
||||
try:
|
||||
import click
|
||||
|
||||
|
|
|
|||
|
|
@ -9550,9 +9550,14 @@ async def initialize(
|
|||
master_key, \
|
||||
user_custom_auth, \
|
||||
prisma_client
|
||||
from litellm.proxy.common_utils.banner import show_banner
|
||||
from litellm.proxy.common_utils.banner import LITELLM_BANNER, show_banner
|
||||
|
||||
show_banner()
|
||||
# show_banner() also serves the `lite` shell, which runs against an uninitialized SDK (#46803), so
|
||||
# the JSON-mode choice stays out of it.
|
||||
if litellm.json_logs:
|
||||
print_startup_message(LITELLM_BANNER)
|
||||
else:
|
||||
show_banner()
|
||||
if os.getenv("LITELLM_DONT_SHOW_FEEDBACK_BOX", "").lower() != "true":
|
||||
generate_feedback_box()
|
||||
user_model = model
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
"""The CLI banner is terminal art in plain mode and one JSON record when json_logs is on."""
|
||||
|
||||
import json
|
||||
import sys
|
||||
from typing import Final
|
||||
|
||||
import litellm
|
||||
from litellm._logging import turn_on_json
|
||||
from litellm.proxy.common_utils.banner import LITELLM_BANNER, show_banner
|
||||
|
||||
|
||||
def test_show_banner_prints_the_banner_between_blank_lines_in_plain_mode(monkeypatch, capfd):
|
||||
"""Operators without JSON logs see the banner exactly as before."""
|
||||
monkeypatch.setattr(litellm, "json_logs", False)
|
||||
|
||||
show_banner()
|
||||
|
||||
assert capfd.readouterr() == (f"\n{LITELLM_BANNER}\n\n", "")
|
||||
|
||||
|
||||
def test_show_banner_is_one_json_record_in_json_mode(monkeypatch, capfd):
|
||||
"""With JSON logs on, the six banner rows are one INFO record with their indentation kept, so the
|
||||
first line a worker writes parses like every other."""
|
||||
monkeypatch.setattr(litellm, "json_logs", True)
|
||||
monkeypatch.setattr(sys, "excepthook", sys.excepthook) # turn_on_json swaps it; put it back at teardown
|
||||
turn_on_json()
|
||||
|
||||
show_banner()
|
||||
|
||||
out, err = capfd.readouterr()
|
||||
assert err == ""
|
||||
lines: Final = [raw for raw in out.splitlines() if raw.strip()]
|
||||
assert len(lines) == 1, lines
|
||||
record: Final = json.loads(lines[0])
|
||||
assert record["message"] == LITELLM_BANNER
|
||||
assert record["level"] == "INFO"
|
||||
|
|
@ -48,6 +48,7 @@ from litellm.proxy.auth.user_api_key_auth import user_api_key_auth
|
|||
from litellm.proxy.hooks.parallel_request_limiter_v3 import RequestRateLimiterStash
|
||||
from litellm.proxy.proxy_server import app, aws_error_type_exception_handler, initialize, openai_exception_handler
|
||||
from litellm.utils import _invalidate_model_cost_lowercase_map
|
||||
from litellm.proxy.common_utils.banner import LITELLM_BANNER
|
||||
from tests._master_key import MASTER_KEY
|
||||
|
||||
PUBLICLY_KNOWN_KEY: Final = "sk-" + "1234"
|
||||
|
|
@ -15725,3 +15726,36 @@ def test_feedback_box_is_one_json_record_in_json_mode(monkeypatch, capfd):
|
|||
assert "Give Feedback / Get Help: https://github.com/BerriAI/litellm/issues/new" in record["message"]
|
||||
assert "Thank you for using LiteLLM! - Krrish & Ishaan" in record["message"]
|
||||
assert "\x1b[" not in record["message"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_initialize_prints_the_banner_between_blank_lines_in_plain_mode(monkeypatch, capfd):
|
||||
"""Operators without JSON logs see the banner exactly as before, through show_banner()'s flushing
|
||||
click.echo."""
|
||||
monkeypatch.setattr(litellm, "json_logs", False)
|
||||
monkeypatch.setenv("LITELLM_DONT_SHOW_FEEDBACK_BOX", "true")
|
||||
|
||||
await proxy_server_module.initialize()
|
||||
|
||||
out, err = capfd.readouterr()
|
||||
assert err == ""
|
||||
assert out.startswith(f"\n{LITELLM_BANNER}\n\n"), out
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_initialize_prints_the_banner_as_one_json_record_in_json_mode(monkeypatch, capfd):
|
||||
"""With JSON logs on, the six banner rows are one INFO record with their indentation kept, so the
|
||||
first line a worker writes parses like every other."""
|
||||
monkeypatch.setattr(litellm, "json_logs", True)
|
||||
monkeypatch.setattr(sys, "excepthook", sys.excepthook) # turn_on_json swaps it; put it back at teardown
|
||||
monkeypatch.setenv("LITELLM_DONT_SHOW_FEEDBACK_BOX", "true")
|
||||
turn_on_json()
|
||||
|
||||
await proxy_server_module.initialize()
|
||||
|
||||
out, err = capfd.readouterr()
|
||||
assert err == ""
|
||||
records: Final = [json.loads(raw) for raw in out.splitlines() if raw.strip()]
|
||||
banner_records: Final = [record for record in records if record["message"] == LITELLM_BANNER]
|
||||
assert len(banner_records) == 1, records
|
||||
assert banner_records[0]["level"] == "INFO"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue