litellm/tests/test_litellm/proxy/proxy_server
yuneng-jiang 7899463c6a
fix(callbacks): forward callback_settings to callback initializers and guard consumers against non-dict values (#30161)
* fix(datadog): pass callback_specific_params so DatadogCostManagementLogger receives cost_tag_keys (#29590)

* fix(datadog): pass callback_specific_params so DatadogCostManagementLogger receives cost_tag_keys

* test(proxy): regression test that load_config forwards callback_specific_params

* fix(proxy): guard lakera_prompt_injection callback_specific_params against non-dict

Addresses review feedback: forwarding callback_settings as callback_specific_params
(so DatadogCostManagementLogger receives cost_tag_keys) exposed the
lakera_prompt_injection branch, which did lakeraAI_Moderation(**callback_specific_params
["lakera_prompt_injection"]) with no type guard. A config like
`callback_settings: {lakera_prompt_injection: "any-string"}` then hit `**"any-string"`
-> TypeError: argument after ** must be a mapping, not str.

Guard the lakera branch with isinstance(dict), matching the existing presidio and
datadog_cost_management branches (non-dict values fall back to {}). Add a regression
test asserting initialize_callbacks_on_proxy ignores a non-dict value instead of crashing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test: inject fake lakera_ai module to avoid importing the real one

CI fix for the lakera regression test: it stubbed litellm.proxy.proxy_server with
a SimpleNamespace and then monkeypatch.setattr'd the real lakera_ai module, which
forces importing it — and lakera_ai does `from litellm.proxy.proxy_server import
LiteLLM_TeamTable`, absent on the stub -> ImportError under proxy-infra tests.

Inject a fake lakera_ai module into sys.modules instead, so the callbacks branch's
`from ...lakera_ai import lakeraAI_Moderation` resolves to the stub without loading
the real module. The guard under test (isinstance(dict) in the lakera branch) is
unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(callbacks): guard compression/websearch interceptors against non-dict callback_settings (#30153)

#29590 forwards the full callback_settings dict into initialize_callbacks_on_proxy, which activates the compression_interception and websearch_interception consumers. Their initialize_from_proxy_config read the callback_settings subkey without an isinstance(dict) guard, so a non-dict value such as `compression_interception: true` reached from_config_yaml(...).get(...) and aborted proxy startup with AttributeError. #29590 added that guard for lakera_prompt_injection but not for these two

Mirror the isinstance(dict) guard already used by the lakera, presidio, and datadog branches so a non-dict value is ignored and the callback initializes with defaults. A parametrized test feeds every callback_settings consumer a non-dict value through initialize_callbacks_on_proxy to catch a future consumer that forgets the guard

* fix(callbacks): normalize non-dict callback_specific_params to empty dict

A blank callback_settings: key in YAML loads as None, and
config.get('callback_settings', {}) returns None because dict.get only
falls back to the default when the key is absent. Forwarding that value
verbatim to initialize_callbacks_on_proxy made the first
'<name>' in callback_specific_params membership test raise
TypeError: argument of type 'NoneType' is not iterable, aborting proxy
startup. Same failure for any non-dict root such as callback_settings: true.

Normalize the value at the function boundary so both callsites (and any
future ones) initialize callbacks with their defaults instead of crashing.

---------

Co-authored-by: Hedi Daoud <150018939+hdaoud23@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 15:22:00 -07:00
..
.coverage_baseline test(proxy): add harness for proxy_server.py behavior-pinning (#28827) 2026-05-25 20:26:44 -07:00
__init__.py test(proxy): add harness for proxy_server.py behavior-pinning (#28827) 2026-05-25 20:26:44 -07:00
_coverage_check.py test(proxy): add harness for proxy_server.py behavior-pinning (#28827) 2026-05-25 20:26:44 -07:00
_pin_check.py test(proxy): add harness for proxy_server.py behavior-pinning (#28827) 2026-05-25 20:26:44 -07:00
conftest.py test(proxy): add harness for proxy_server.py behavior-pinning (#28827) 2026-05-25 20:26:44 -07:00
test_background_health.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_exception_handlers.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_harness_smoke.py test(proxy): add harness for proxy_server.py behavior-pinning (#28827) 2026-05-25 20:26:44 -07:00
test_lifecycle.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_openapi_customization.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_proxy_config.py fix(callbacks): forward callback_settings to callback initializers and guard consumers against non-dict values (#30161) 2026-06-10 15:22:00 -07:00
test_routes_anthropic_beta.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_routes_assistants.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_routes_audio.py fix(proxy): extend response headers hook to streaming, TTS, image gen, and pass-through (#24232) 2026-06-09 22:10:23 +02:00
test_routes_chat_completions.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_routes_completions.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_routes_config.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_routes_embeddings.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_routes_invitation.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_routes_login_sso.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_routes_misc.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_routes_model_cost_map.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_routes_model_info.py feat(proxy): publish /v2/model/info in Swagger OpenAPI spec (#29900) 2026-06-08 09:33:35 -07:00
test_routes_model_metrics.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_routes_models.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_routes_moderations.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_routes_onboarding.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_routes_queue.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_routes_threads.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_routes_utils.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_spend_counters.py fix(register_model): preserve built-in cache pricing when registering custom overrides under unmapped keys (#30044) 2026-06-10 12:11:03 -07:00
test_streaming_helpers.py tests(proxy_server): surface current behavior in tests (#29309) 2026-05-29 23:17:24 -07:00
test_team_model_name_translation.py fix(proxy): stop team BYOK model name corruption on model edit (#29731) 2026-06-04 20:40:40 -07:00