mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-29 01:42:19 +00:00
fix(passthrough): keep target URL query when client sends no query params
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
8aebd4ff63
commit
b6f97a51d2
2 changed files with 40 additions and 22 deletions
|
|
@ -986,7 +986,10 @@ async def pass_through_request(
|
|||
forward_headers=forward_headers,
|
||||
)
|
||||
|
||||
requested_query_params: dict | None = query_params or dict(request.query_params)
|
||||
requested_query_params: dict | None = {
|
||||
**dict(url.params),
|
||||
**(query_params or dict(request.query_params)),
|
||||
} or None
|
||||
|
||||
endpoint_type: Final[EndpointType] = HttpPassThroughEndpointHelpers.get_endpoint_type(str(url))
|
||||
|
||||
|
|
@ -1188,7 +1191,7 @@ async def pass_through_request(
|
|||
query=urlencode(
|
||||
HttpPassThroughEndpointHelpers.get_merged_query_parameters(
|
||||
existing_url=url,
|
||||
request_query_params=requested_query_params,
|
||||
request_query_params=requested_query_params or {},
|
||||
default_query_params=default_query_params,
|
||||
)
|
||||
).encode("ascii")
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ from collections.abc import Callable
|
|||
from contextlib import ExitStack, contextmanager
|
||||
from io import BytesIO
|
||||
from types import SimpleNamespace
|
||||
from typing import Optional
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import httpx
|
||||
|
|
@ -15,33 +14,31 @@ from fastapi import Request, Response, UploadFile
|
|||
from starlette.datastructures import FormData, Headers, QueryParams
|
||||
from starlette.datastructures import UploadFile as StarletteUploadFile
|
||||
|
||||
|
||||
import litellm
|
||||
from litellm.integrations.custom_logger import CustomLogger
|
||||
from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj
|
||||
from litellm.proxy._types import ProxyException, UserAPIKeyAuth
|
||||
from litellm.proxy.pass_through_endpoints.pass_through_endpoints import (
|
||||
DEFAULT_PASS_THROUGH_REQUEST_TIMEOUT_SECONDS,
|
||||
LITELLM_PASS_THROUGH_CUSTOM_BODY_STATE_KEY,
|
||||
HttpPassThroughEndpointHelpers,
|
||||
InitPassThroughEndpointHelpers,
|
||||
LITELLM_PASS_THROUGH_CUSTOM_BODY_STATE_KEY,
|
||||
_registered_pass_through_routes,
|
||||
chat_completion_pass_through_endpoint,
|
||||
create_pass_through_route,
|
||||
initialize_pass_through_endpoints,
|
||||
pass_through_request,
|
||||
resolve_pass_through_request_timeout,
|
||||
resolve_llm_passthrough_timeout,
|
||||
resolve_pass_through_request_timeout,
|
||||
websocket_passthrough_request,
|
||||
)
|
||||
from litellm.integrations.custom_logger import CustomLogger
|
||||
from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj
|
||||
from litellm.proxy._types import ProxyException, UserAPIKeyAuth
|
||||
from litellm.types.passthrough_endpoints.pass_through_endpoints import (
|
||||
LITELLM_PASS_THROUGH_DEPLOYMENT_MODEL_INFO_STATE_KEY,
|
||||
LITELLM_PASS_THROUGH_RAW_BODY_STATE_KEY,
|
||||
)
|
||||
from litellm.proxy.pass_through_endpoints.success_handler import (
|
||||
PassThroughEndpointLogging,
|
||||
)
|
||||
|
||||
import litellm
|
||||
from litellm.types.passthrough_endpoints.pass_through_endpoints import (
|
||||
LITELLM_PASS_THROUGH_DEPLOYMENT_MODEL_INFO_STATE_KEY,
|
||||
LITELLM_PASS_THROUGH_RAW_BODY_STATE_KEY,
|
||||
)
|
||||
|
||||
MESSAGE_START_SSE_FRAME = b'event: message_start\ndata: {"type": "message_start"}\n\n'
|
||||
|
||||
|
|
@ -2425,10 +2422,10 @@ async def _run_pass_through_and_capture_wire_url(
|
|||
target: str,
|
||||
incoming_query: str,
|
||||
merge_query_params: bool = False,
|
||||
default_query_params: Optional[dict] = None,
|
||||
custom_llm_provider: Optional[str] = None,
|
||||
managed_files_hook: Optional[_FakeManagedFilesHook] = None,
|
||||
user_api_key_dict: Optional[UserAPIKeyAuth] = None,
|
||||
default_query_params: dict | None = None,
|
||||
custom_llm_provider: str | None = None,
|
||||
managed_files_hook: _FakeManagedFilesHook | None = None,
|
||||
user_api_key_dict: UserAPIKeyAuth | None = None,
|
||||
) -> httpx.URL:
|
||||
import litellm
|
||||
from litellm.llms.custom_httpx.http_handler import get_async_httpx_client
|
||||
|
|
@ -2532,12 +2529,30 @@ async def test_pass_through_request_default_query_params_reach_the_wire():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_pass_through_request_without_merge_replaces_target_query():
|
||||
async def test_pass_through_request_without_merge_preserves_target_query():
|
||||
wire_url = await _run_pass_through_and_capture_wire_url(
|
||||
target="https://www.bing.com/search?setLang=en-US",
|
||||
incoming_query="q=litellm",
|
||||
)
|
||||
assert dict(wire_url.params) == {"q": "litellm"}
|
||||
assert dict(wire_url.params) == {"setLang": "en-US", "q": "litellm"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_pass_through_request_preserves_target_query_without_client_query():
|
||||
wire_url = await _run_pass_through_and_capture_wire_url(
|
||||
target="https://example.com/v1/models/gemini:streamGenerateContent?alt=sse",
|
||||
incoming_query="",
|
||||
)
|
||||
assert dict(wire_url.params) == {"alt": "sse"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_pass_through_request_preserves_target_query_with_client_query():
|
||||
wire_url = await _run_pass_through_and_capture_wire_url(
|
||||
target="https://example.com/v1/models/gemini:streamGenerateContent?alt=sse",
|
||||
incoming_query="key=abc",
|
||||
)
|
||||
assert dict(wire_url.params) == {"alt": "sse", "key": "abc"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
@ -5239,7 +5254,7 @@ async def test_websocket_passthrough_does_not_close_twice_when_success_logging_f
|
|||
|
||||
def _passthrough_kwargs_for_reservation(
|
||||
user_api_key_dict: UserAPIKeyAuth,
|
||||
parsed_body: Optional[dict] = None,
|
||||
parsed_body: dict | None = None,
|
||||
user_defined_route: bool = False,
|
||||
) -> dict:
|
||||
mock_request = MagicMock(spec=Request)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue