diff --git a/litellm/router_python_core.py b/litellm/router_python_core.py index 8ca2afb9a99..11cb26fe71c 100644 --- a/litellm/router_python_core.py +++ b/litellm/router_python_core.py @@ -14035,10 +14035,10 @@ class PythonCore(DeprecatedRouterMembers): ) -> tuple[Mapping[str, Any], ...]: """ `deployments` without the ones `_pre_call_checks` keeps this request away from for being outside its allowed - region, typed for the tag routing filter + region, regardless of whether the request carries countable message or input content """ allowed_model_region: Final = None if request_kwargs is None else request_kwargs.get("allowed_model_region") - if allowed_model_region is None or not self._core_enable_pre_call_checks or not has_request_input: + if allowed_model_region is None or not self._core_enable_pre_call_checks: return tuple(deployments) if not isinstance(allowed_model_region, str): return () @@ -16089,7 +16089,7 @@ class PythonCore(DeprecatedRouterMembers): parent_otel_span=parent_otel_span, ) - if self._core_enable_pre_call_checks and (messages is not None or input is not None): + if self._core_enable_pre_call_checks: deployments_to_check: Final = healthy_deployments healthy_deployments = self._pre_call_checks( model=model, @@ -17374,7 +17374,7 @@ class PythonCore(DeprecatedRouterMembers): ) # filter pre-call checks - if self._core_enable_pre_call_checks and (messages is not None or input is not None): + if self._core_enable_pre_call_checks: healthy_deployments = self._pre_call_checks( model=model, healthy_deployments=healthy_deployments, @@ -17619,7 +17619,7 @@ class PythonCore(DeprecatedRouterMembers): pass_through_deployments = self._filter_blocked_deployments(pass_through_deployments) # 5. Apply pre-call checks (if enabled) - if self._core_enable_pre_call_checks and (messages is not None or input is not None): + if self._core_enable_pre_call_checks: pass_through_deployments = self._pre_call_checks( model=model, healthy_deployments=pass_through_deployments, diff --git a/tests/unit/test_router/test_router_region_no_input.py b/tests/unit/test_router/test_router_region_no_input.py new file mode 100644 index 00000000000..30503e1e849 --- /dev/null +++ b/tests/unit/test_router/test_router_region_no_input.py @@ -0,0 +1,69 @@ +import pytest +from litellm import Router + + +def _router_with_region_deployments(*, pass_through: bool = False) -> Router: + return Router( + model_list=[ + { + "model_name": "region-test", + "litellm_params": { + "model": "openai/gpt-4o", + "region_name": "eu", + "use_in_pass_through": pass_through, + }, + "model_info": {"id": "eu-deployment"}, + }, + { + "model_name": "region-test", + "litellm_params": { + "model": "openai/gpt-4o-mini", + "region_name": "us", + "use_in_pass_through": pass_through, + }, + "model_info": {"id": "us-deployment"}, + }, + ], + enable_pre_call_checks=True, + ) + + +@pytest.mark.asyncio +async def test_allowed_model_region_filters_async_selection_without_messages_or_input() -> None: + router = _router_with_region_deployments() + + deployments = await router.select( + model="region-test", + request_kwargs={"allowed_model_region": "eu"}, + kind="healthy", + messages=None, + input=None, + ) + + assert [deployment["model_info"]["id"] for deployment in deployments] == ["eu-deployment"] + + +def test_allowed_model_region_filters_sync_selection_without_messages_or_input() -> None: + router = _router_with_region_deployments() + + deployment = router.get_available_deployment( + model="region-test", + request_kwargs={"allowed_model_region": "eu"}, + messages=None, + input=None, + ) + + assert deployment["model_info"]["id"] == "eu-deployment" + + +def test_allowed_model_region_filters_passthrough_without_messages_or_input() -> None: + router = _router_with_region_deployments(pass_through=True) + + deployment = router.get_available_deployment_for_pass_through( + model="region-test", + request_kwargs={"allowed_model_region": "eu"}, + messages=None, + input=None, + ) + + assert deployment["model_info"]["id"] == "eu-deployment"