Address review comments

Signed-off-by: T K Chandra Hasan <t.k.chandra.hasan@ibm.com>
This commit is contained in:
T K Chandra Hasan 2026-05-20 22:58:18 +05:30
parent 56582e2934
commit 018ba0bc5b
No known key found for this signature in database
GPG key ID: 6ED262543ADEC5CB
3 changed files with 25 additions and 17 deletions

View file

@ -1,7 +1,7 @@
from typing import TYPE_CHECKING, List, Optional, Tuple
from litellm.llms.base_llm.passthrough.transformation import BasePassthroughConfig
from litellm.llms.watsonx.common_utils import IBMWatsonXMixin
from litellm.llms.watsonx.common_utils import IBMWatsonXMixin
from litellm.secret_managers.main import get_secret_str
if TYPE_CHECKING:
@ -28,11 +28,11 @@ class WatsonxPassthroughConfig(IBMWatsonXMixin, BasePassthroughConfig):
) -> Tuple["URL", str]:
"""
Construct complete Watsonx URL with version parameter.
This ensures the version parameter is ALWAYS included in the URL,
solving the query parameter issue.
"""
base_target_url = self.get_api_base(api_base) or self._get_base_url(api_base)
base_target_url = self.get_api_base(api_base)
# Use the format_url helper to construct URL with query params
complete_url = self.format_url(
@ -47,13 +47,20 @@ class WatsonxPassthroughConfig(IBMWatsonXMixin, BasePassthroughConfig):
def get_api_base(
api_base: Optional[str] = None,
) -> Optional[str]:
return api_base or get_secret_str("WATSONX_API_BASE")
return api_base or IBMWatsonXMixin._get_base_url(
self=IBMWatsonXMixin, api_base=api_base
)
@staticmethod
def get_api_key(
api_key: Optional[str] = None,
) -> Optional[str]:
return api_key or get_secret_str("WATSON_API_KEY")
return (
api_key
or IBMWatsonXMixin.get_watsonx_credentials(
optional_params=dict(), api_base=None, api_key=api_key
)["api_key"]
)
@staticmethod
def get_base_model(model: str) -> Optional[str]:
@ -62,4 +69,4 @@ class WatsonxPassthroughConfig(IBMWatsonXMixin, BasePassthroughConfig):
def get_models(
self, api_key: Optional[str] = None, api_base: Optional[str] = None
) -> List[str]:
return super().get_models(api_key, api_base)
return super().get_models(api_key, api_base)

View file

@ -2425,6 +2425,7 @@ def create_generic_websocket_passthrough_endpoint(
cost_per_request=cost_per_request,
)
@router.api_route(
"/watsonx/{endpoint:path}",
methods=["GET", "POST", "PUT", "DELETE", "PATCH"],
@ -2455,8 +2456,7 @@ async def watsonx_proxy_route(
if provider_config is None:
raise HTTPException(
status_code=404,
detail="Watsonx passthrough config not found"
status_code=404, detail="Watsonx passthrough config not found"
)
# Get complete URL with version parameter
@ -2465,7 +2465,7 @@ async def watsonx_proxy_route(
api_key=None,
model="",
endpoint=endpoint,
request_query_params=dict(request.query_params),
request_query_params=None,
litellm_params={},
)
@ -2491,8 +2491,9 @@ async def watsonx_proxy_route(
if _request_body.get("stream"):
is_streaming_request = True
request_query_params = dict()
request_query_params["version"] = litellm.WATSONX_DEFAULT_API_VERSION
request_query_params = dict(request.query_params)
if request_query_params.get("version") is None:
request_query_params["version"] = litellm.WATSONX_DEFAULT_API_VERSION
# Create pass-through endpoint
endpoint_func = create_pass_through_route(

View file

@ -76,7 +76,7 @@ class TestWatsonxPassthroughConfig:
assert "version=2024-03-19" in str(complete_url)
assert base_target_url == api_base
@patch("litellm.llms.watsonx.passthrough.transformation.get_secret_str")
@patch("litellm.llms.watsonx.common_utils.get_secret_str")
def test_get_complete_url_with_env_api_base(self, mock_get_secret):
"""Test URL construction with api_base from environment."""
config = WatsonxPassthroughConfig()
@ -141,7 +141,7 @@ class TestWatsonxPassthroughConfig:
assert base_target_url == api_base
assert "version=2024-03-19" not in str(complete_url)
@patch("litellm.llms.watsonx.passthrough.transformation.get_secret_str")
@patch("litellm.llms.watsonx.common_utils.get_secret_str")
def test_get_api_base_with_explicit_value(self, mock_get_secret):
"""Test get_api_base returns explicit value when provided."""
explicit_base = "https://custom.watsonx.com"
@ -151,7 +151,7 @@ class TestWatsonxPassthroughConfig:
assert result == explicit_base
mock_get_secret.assert_not_called()
@patch("litellm.llms.watsonx.passthrough.transformation.get_secret_str")
@patch("litellm.llms.watsonx.common_utils.get_secret_str")
def test_get_api_base_from_environment(self, mock_get_secret):
"""Test get_api_base retrieves from environment when not provided."""
env_base = "https://env.watsonx.com"
@ -162,7 +162,7 @@ class TestWatsonxPassthroughConfig:
assert result == env_base
mock_get_secret.assert_called_once_with("WATSONX_API_BASE")
@patch("litellm.llms.watsonx.passthrough.transformation.get_secret_str")
@patch("litellm.llms.watsonx.common_utils.get_secret_str")
def test_get_api_key_with_explicit_value(self, mock_get_secret):
"""Test get_api_key returns explicit value when provided."""
explicit_key = "test-api-key-123"
@ -172,7 +172,7 @@ class TestWatsonxPassthroughConfig:
assert result == explicit_key
mock_get_secret.assert_not_called()
@patch("litellm.llms.watsonx.passthrough.transformation.get_secret_str")
@patch("litellm.llms.watsonx.common_utils.get_secret_str")
def test_get_api_key_from_environment(self, mock_get_secret):
"""Test get_api_key retrieves from environment when not provided."""
env_key = "env-api-key-456"
@ -181,7 +181,7 @@ class TestWatsonxPassthroughConfig:
result = WatsonxPassthroughConfig.get_api_key(api_key=None)
assert result == env_key
mock_get_secret.assert_called_once_with("WATSON_API_KEY")
mock_get_secret.assert_any_call("WATSONX_APIKEY")
def test_get_base_model_returns_model(self):
"""Test get_base_model returns the model as-is."""