fix: suppress LiteLLM provider banner before import (#874)

## Summary
- set `LITELLM_SUPPRESS_DEBUG_INFO` before importing `litellm` in the
LiteLLM provider
- keep the existing post-import suppression flags as a fallback
- add a regression test that verifies the env flag exists before
`litellm` import

Fixes #613

## Tests
- `uv run pytest
tests/test_startup_log_noise.py::TestLiteLLMLogSuppression -q`
- `uv run ruff check headroom/providers/litellm.py
tests/test_startup_log_noise.py`
- `python3 -m py_compile headroom/providers/litellm.py
tests/test_startup_log_noise.py`
This commit is contained in:
Federico Rao 2026-06-11 22:10:20 +02:00 committed by GitHub
parent bfcb07d78e
commit f9384ef4b7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 43 additions and 0 deletions

View file

@ -22,6 +22,7 @@ Requires: pip install litellm
from __future__ import annotations
import logging
import os
from typing import Any
from headroom.tokenizers import EstimatingTokenCounter
@ -32,6 +33,10 @@ logger = logging.getLogger(__name__)
# Check if litellm is available
try:
# LiteLLM can print its provider-list banner during import, before the
# module-level suppression flags below can be set.
os.environ.setdefault("LITELLM_SUPPRESS_DEBUG_INFO", "True")
import litellm
# Suppress litellm's startup banner ("Provider List: https://...") and

View file

@ -9,8 +9,12 @@ Covers the fixes in:
from __future__ import annotations
import builtins
import importlib
import logging
import sys
import warnings
from types import ModuleType
class TestAnthropicWarnParameter:
@ -110,6 +114,40 @@ class TestEmbedderLogLevels:
class TestLiteLLMLogSuppression:
"""litellm startup banner suppression must be applied at import time."""
def test_litellm_suppress_env_is_set_before_import(self, monkeypatch):
"""The env flag must exist before litellm itself is imported."""
import os
monkeypatch.delenv("LITELLM_SUPPRESS_DEBUG_INFO", raising=False)
sys.modules.pop("headroom.providers.litellm", None)
sys.modules.pop("litellm", None)
original_import = builtins.__import__
fake_litellm = ModuleType("litellm")
fake_litellm.suppress_debug_info = False
fake_litellm.set_verbose = True
fake_litellm.get_model_info = lambda _model: {}
fake_litellm.model_cost = {}
fake_litellm.token_counter = lambda **_kwargs: 0
observed_env: list[str | None] = []
def import_spy(name, globals=None, locals=None, fromlist=(), level=0):
if name == "litellm":
observed_env.append(os.environ.get("LITELLM_SUPPRESS_DEBUG_INFO"))
sys.modules["litellm"] = fake_litellm
return fake_litellm
return original_import(name, globals, locals, fromlist, level)
monkeypatch.setattr(builtins, "__import__", import_spy)
try:
importlib.import_module("headroom.providers.litellm")
finally:
sys.modules.pop("headroom.providers.litellm", None)
sys.modules.pop("litellm", None)
assert observed_env
assert all(value == "True" for value in observed_env)
def test_litellm_suppress_debug_info_is_set(self):
"""litellm.suppress_debug_info must be True after importing the litellm provider."""
litellm = pytest_importorskip_litellm()