diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index ac7f86b202..ed8365f95c 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -953,8 +953,9 @@ async def proxy_startup_event(app: FastAPI): # noqa: PLR0915 def _generate_stable_operation_id(route: Any) -> str: operation_id = re.sub(r"\W", "_", f"{route.name}{route.path_format}") - if route.methods: - operation_id = f"{operation_id}_{sorted(route.methods)[0].lower()}" + route_methods = sorted(route.methods or []) + if len(route_methods) == 1: + operation_id = f"{operation_id}_{route_methods[0].lower()}" return operation_id diff --git a/tests/test_litellm/proxy/test_swagger_chat_completions.py b/tests/test_litellm/proxy/test_swagger_chat_completions.py index 2a773bd316..36ead2f41c 100644 --- a/tests/test_litellm/proxy/test_swagger_chat_completions.py +++ b/tests/test_litellm/proxy/test_swagger_chat_completions.py @@ -460,6 +460,31 @@ class TestSwaggerChatCompletions: ] assert len(operation_ids) == len(set(operation_ids)) + def test_should_not_add_method_suffix_to_multi_method_route_base_id(self): + from types import SimpleNamespace + + from litellm.proxy.proxy_server import _generate_stable_operation_id + + multi_method_route = SimpleNamespace( + name="anthropic_proxy_route", + path_format="/anthropic/{endpoint}", + methods={"DELETE", "GET", "POST"}, + ) + single_method_route = SimpleNamespace( + name="list_models", + path_format="/models", + methods={"GET"}, + ) + + assert ( + _generate_stable_operation_id(multi_method_route) + == "anthropic_proxy_route_anthropic__endpoint_" + ) + assert ( + _generate_stable_operation_id(single_method_route) + == "list_models_models_get" + ) + def test_should_reserve_operation_ids_across_lazy_fragments(self): from litellm.proxy.proxy_server import ensure_unique_openapi_operation_ids