fix(proxy): warn about per-worker login counters even without general_settings

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
yucheng 2026-09-13 04:36:41 +00:00
parent 49d49b7050
commit c3a7b7c3ee
2 changed files with 31 additions and 6 deletions

View file

@ -5748,6 +5748,13 @@ class ProxyConfig:
general_settings = config.get("general_settings", {})
if general_settings is None:
general_settings = {}
### FAILED-LOGIN ACCOUNTING MULTI-INSTANCE PREREQUISITE CHECK ###
# Failed Admin UI sign-in counters live in redis_usage_cache when available so a
# brute-force run is counted once across workers instead of once per worker.
if os.getenv("NUM_WORKERS", "1") != "1" and redis_usage_cache is None:
warn_login_counters_are_per_worker(os.getenv("NUM_WORKERS", "1"))
_bg_hc_model_groups: Final = parse_background_health_check_model_groups(general_settings)
_enable_hc_routing = False
_hc_staleness = None
@ -5844,12 +5851,6 @@ class ProxyConfig:
"or ensure sticky sessions for single-instance deployments."
)
### FAILED-LOGIN ACCOUNTING MULTI-INSTANCE PREREQUISITE CHECK ###
# Failed Admin UI sign-in counters live in redis_usage_cache when available so a
# brute-force run is counted once across workers instead of once per worker.
if os.getenv("NUM_WORKERS", "1") != "1" and redis_usage_cache is None:
warn_login_counters_are_per_worker(os.getenv("NUM_WORKERS", "1"))
### STORE MODEL IN DB ### feature flag for `/model/new`
store_model_in_db = general_settings.get("store_model_in_db", False)
if store_model_in_db is None:

View file

@ -3411,6 +3411,30 @@ async def test_load_config_user_url_validation_handles_null_and_string_false(tmp
assert litellm.user_url_validation is False
@pytest.mark.asyncio
async def test_load_config_warns_per_worker_login_counters_without_general_settings(tmp_path, monkeypatch, caplog):
"""Regression: the failed-login throttle is on by default, so a multi-worker proxy with no
Redis must hear that its counters are per worker even when the config has no general_settings."""
import logging
import litellm.proxy.proxy_server as proxy_server
from litellm.proxy.auth.login_throttle import warn_login_counters_are_per_worker
from litellm.proxy.proxy_server import ProxyConfig
for redis_var in ("REDIS_HOST", "REDIS_URL", "REDIS_CLUSTER_NODES", "REDIS_SENTINEL_NODES"):
monkeypatch.delenv(redis_var, raising=False)
monkeypatch.setenv("NUM_WORKERS", "4")
monkeypatch.setattr(proxy_server, "redis_usage_cache", None)
warn_login_counters_are_per_worker.cache_clear()
config_file = tmp_path / "config.yaml"
config_file.write_text("model_list: []\n")
with caplog.at_level(logging.WARNING, logger="LiteLLM Proxy"):
await ProxyConfig().load_config(router=MagicMock(), config_file_path=str(config_file))
assert "Running 4 workers but Redis is not configured" in caplog.text
@pytest.mark.asyncio
async def test_load_environment_variables_direct_and_os_environ():
"""