From 28d468174af74ac5b0a7057d092e12eae5e014f7 Mon Sep 17 00:00:00 2001 From: Adarsh Divakaran Date: Fri, 14 Aug 2026 15:47:41 +0530 Subject: [PATCH] fix(search): remove SerpApi API base overrides --- litellm/llms/serpapi/search/transformation.py | 14 ++++++-------- .../search/test_base_search_transformation.py | 4 ---- .../llms/serpapi/test_serpapi_search.py | 14 -------------- 3 files changed, 6 insertions(+), 26 deletions(-) diff --git a/litellm/llms/serpapi/search/transformation.py b/litellm/llms/serpapi/search/transformation.py index 5900a61cde4..cb46dcd37cc 100644 --- a/litellm/llms/serpapi/search/transformation.py +++ b/litellm/llms/serpapi/search/transformation.py @@ -19,7 +19,6 @@ from litellm.llms.base_llm.search.transformation import ( SearchResponse, SearchResult, ) -from litellm.secret_managers.main import get_secret_str _SERPAPI_PARAMS_KEY: Final = "_serpapi_params" _SERPAPI_REQUEST_KEYS: Final = frozenset(("engine", "q", "num", "gl")) @@ -73,16 +72,15 @@ class SerpApiSearchConfig(BaseSearchConfig): def _resolve_api_key( self, api_key: str | None, - api_base: str | None, ) -> str: """ - Resolve a caller or configured SerpApi key for the target API base. + Resolve a caller or configured SerpApi key. """ resolved_key: Final = self.resolve_server_api_key( caller_api_key=api_key, - caller_api_base=api_base, + caller_api_base=None, key_env_vars=("SERPAPI_KEY", "SERPAPI_API_KEY"), - base_env_var="SERPAPI_API_BASE", + base_env_var=None, default_api_base=self.SERPAPI_API_BASE, ) if not resolved_key: @@ -99,7 +97,7 @@ class SerpApiSearchConfig(BaseSearchConfig): """ Validate SerpApi credentials and return request headers. """ - self._resolve_api_key(api_key=api_key, api_base=api_base) + self._resolve_api_key(api_key=api_key) resolved_headers: Final = MappingProxyType({**headers, "Content-Type": "application/json"}) return resolved_headers.copy() @@ -118,7 +116,7 @@ class SerpApiSearchConfig(BaseSearchConfig): SerpApi uses GET requests and includes api_key in query params. """ - resolved_base: Final = api_base or get_secret_str("SERPAPI_API_BASE") or self.SERPAPI_API_BASE + resolved_base: Final = self.SERPAPI_API_BASE if not isinstance(data, Mapping) or _SERPAPI_PARAMS_KEY not in data: return resolved_base @@ -131,7 +129,7 @@ class SerpApiSearchConfig(BaseSearchConfig): raise ValueError( f"Invalid SerpApi URL parameter value for: {invalid_params or 'request parameters'}" ) from None - resolved_key: Final = self._resolve_api_key(api_key=api_key, api_base=api_base) + resolved_key: Final = self._resolve_api_key(api_key=api_key) query_params: Final = tuple( ( key, diff --git a/tests/test_litellm/llms/base_llm/search/test_base_search_transformation.py b/tests/test_litellm/llms/base_llm/search/test_base_search_transformation.py index 1f05914ea00..a1353d57038 100644 --- a/tests/test_litellm/llms/base_llm/search/test_base_search_transformation.py +++ b/tests/test_litellm/llms/base_llm/search/test_base_search_transformation.py @@ -31,7 +31,6 @@ from litellm.llms.parallel_ai.search.transformation import ParallelAISearchConfi from litellm.llms.perplexity.search.transformation import PerplexitySearchConfig from litellm.llms.searchapi.search.transformation import SearchAPIConfig from litellm.llms.searxng.search.transformation import SearXNGSearchConfig -from litellm.llms.serpapi.search.transformation import SerpApiSearchConfig from litellm.llms.serper.search.transformation import SerperSearchConfig from litellm.llms.tavily.search.transformation import TavilySearchConfig from litellm.llms.tinyfish.search.transformation import TinyfishSearchConfig @@ -51,7 +50,6 @@ _BASE_ENV_VARS = ( "FIRECRAWL_API_BASE", "LINKUP_API_BASE", "SEARCHAPI_API_BASE", - "SERPAPI_API_BASE", "GOOGLE_PSE_API_BASE", "PARALLEL_AI_API_BASE", "YOUCOM_API_BASE", @@ -81,7 +79,6 @@ PROVIDERS: Tuple[ProviderSpec, ...] = ( (FirecrawlSearchConfig, {"FIRECRAWL_API_KEY": "srv"}, "caller-key", {}), (LinkupSearchConfig, {"LINKUP_API_KEY": "srv"}, "caller-key", {}), (SearchAPIConfig, {"SEARCHAPI_API_KEY": "srv"}, "caller-key", {}), - (SerpApiSearchConfig, {"SERPAPI_KEY": "srv"}, "caller-key", {}), ( GooglePSESearchConfig, {"GOOGLE_PSE_API_KEY": "srv"}, @@ -285,7 +282,6 @@ async def test_asearch_does_not_leak_server_key_to_caller_api_base( "provider, key_env, server_key, extra_env", [ ("searchapi", "SEARCHAPI_API_KEY", "sk-server-searchapi", {}), - ("serpapi", "SERPAPI_KEY", "sk-server-serpapi", {}), ( "google_pse", "GOOGLE_PSE_API_KEY", diff --git a/tests/test_litellm/llms/serpapi/test_serpapi_search.py b/tests/test_litellm/llms/serpapi/test_serpapi_search.py index cba8e12832d..072964f6cc3 100644 --- a/tests/test_litellm/llms/serpapi/test_serpapi_search.py +++ b/tests/test_litellm/llms/serpapi/test_serpapi_search.py @@ -210,20 +210,6 @@ def test_serpapi_rejects_unencodable_passthrough_param( assert str(exc_info.value) == "Invalid SerpApi URL parameter value for: nested" -def test_serpapi_rejects_server_key_for_untrusted_api_base( - monkeypatch: pytest.MonkeyPatch, -) -> None: - monkeypatch.delenv("SERPAPI_API_KEY", raising=False) - monkeypatch.setenv("SERPAPI_KEY", "server-api-key") - config = SerpApiSearchConfig() - - with pytest.raises(ValueError, match="Refusing to send"): - config.validate_environment( - headers={}, - api_base="https://example.com/search.json", - ) - - def test_serpapi_missing_api_key(monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.delenv("SERPAPI_KEY", raising=False) monkeypatch.delenv("SERPAPI_API_KEY", raising=False)