diff --git a/litellm/proxy/route_llm_request.py b/litellm/proxy/route_llm_request.py index f611384b7ae..bfe6b8484fa 100644 --- a/litellm/proxy/route_llm_request.py +++ b/litellm/proxy/route_llm_request.py @@ -1,17 +1,21 @@ import asyncio -from dataclasses import fields as _dc_fields from typing import TYPE_CHECKING, Any, Literal, Optional from fastapi import HTTPException, status import litellm from litellm.proxy._types import UserAPIKeyAuth -from litellm.types.router import MockRouterTestingParams -# Router-internal mock_testing_* flag names. Single source of truth so a -# new flag added to ``MockRouterTestingParams`` is automatically stripped. -_MOCK_TESTING_KWARG_NAMES: tuple = tuple( - f.name for f in _dc_fields(MockRouterTestingParams) +# Router-internal mock_testing_* flag names — kept in sync with +# ``litellm.types.router.MockRouterTestingParams`` by the test +# ``test_mock_testing_kwarg_names_matches_dataclass``. Hardcoding (rather +# than deriving via ``dataclasses.fields(MockRouterTestingParams)`` at +# import time) avoids a cyclic import: ``litellm.types.router`` imports +# back into proxy modules before this module finishes loading. +_MOCK_TESTING_KWARG_NAMES: tuple = ( + "mock_testing_fallbacks", + "mock_testing_context_fallbacks", + "mock_testing_content_policy_fallbacks", ) if TYPE_CHECKING: diff --git a/tests/test_litellm/proxy/test_route_llm_request.py b/tests/test_litellm/proxy/test_route_llm_request.py index 9ef90085e41..98b0b6be025 100644 --- a/tests/test_litellm/proxy/test_route_llm_request.py +++ b/tests/test_litellm/proxy/test_route_llm_request.py @@ -241,6 +241,21 @@ async def test_route_request_with_router_settings_override_preserves_existing(): assert call_kwargs["timeout"] == 30 +def test_mock_testing_kwarg_names_matches_dataclass(): + """``_MOCK_TESTING_KWARG_NAMES`` is hardcoded to avoid a cyclic import + against ``litellm.types.router``. This test guards against drift — + if a new ``mock_testing_*`` field is added to ``MockRouterTestingParams`` + the strip list must be updated to keep covering it.""" + from dataclasses import fields + + from litellm.proxy.route_llm_request import _MOCK_TESTING_KWARG_NAMES + from litellm.types.router import MockRouterTestingParams + + assert set(_MOCK_TESTING_KWARG_NAMES) == { + f.name for f in fields(MockRouterTestingParams) + } + + @pytest.mark.asyncio @pytest.mark.parametrize( "mock_flag",