mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-03 02:22:24 +00:00
fix(proxy): forward proxy headers to files and batches API via extra_headers
Fixes #27641 When `add_user_information_to_llm_headers` or `forward_client_headers_to_llm_api` is enabled, the proxy pre-call utils store the headers under `data["headers"]`. However, the file and batch API handlers pass `**data` to TypedDicts that only have an `extra_headers` field (not `headers`), so the injected headers were silently dropped before reaching the upstream LLM provider. Fix: after each call to `add_litellm_data_to_request` / `common_processing_pre_call_logic` in every file handler (create, get, get_content, delete, list) remap `data["headers"]` into `data["extra_headers"]`.
This commit is contained in:
parent
a72414a061
commit
85abc38970
1 changed files with 40 additions and 9 deletions
|
|
@ -364,10 +364,10 @@ async def create_file( # noqa: PLR0915
|
|||
expires_after: Optional[FileExpiresAfter] = None
|
||||
form_data_raw = await request.form()
|
||||
form_data_dict: Dict[str, Any] = dict(form_data_raw)
|
||||
extracted_litellm_metadata: Optional[Dict[str, Any]] = (
|
||||
extract_nested_form_metadata(
|
||||
form_data=form_data_dict, prefix="litellm_metadata["
|
||||
)
|
||||
extracted_litellm_metadata: Optional[
|
||||
Dict[str, Any]
|
||||
] = extract_nested_form_metadata(
|
||||
form_data=form_data_dict, prefix="litellm_metadata["
|
||||
)
|
||||
expires_after_anchor = form_data_raw.get("expires_after[anchor]")
|
||||
expires_after_seconds_str = form_data_raw.get("expires_after[seconds]")
|
||||
|
|
@ -442,6 +442,13 @@ async def create_file( # noqa: PLR0915
|
|||
proxy_config=proxy_config,
|
||||
)
|
||||
|
||||
# Remap proxy-injected headers to extra_headers;
|
||||
# file/batch TypedDicts use extra_headers, not headers (fixes #27641)
|
||||
if "headers" in data:
|
||||
_proxy_headers = data.pop("headers")
|
||||
if _proxy_headers:
|
||||
data["extra_headers"] = {**(data.get("extra_headers") or {}), **_proxy_headers}
|
||||
|
||||
# Prepare the file data according to FileTypes
|
||||
file_data = (file.filename, file_content, file.content_type)
|
||||
|
||||
|
|
@ -627,6 +634,13 @@ async def get_file_content( # noqa: PLR0915
|
|||
route_type="afile_content",
|
||||
)
|
||||
|
||||
# Remap proxy-injected headers to extra_headers;
|
||||
# file/batch TypedDicts use extra_headers, not headers (fixes #27641)
|
||||
if "headers" in data:
|
||||
_proxy_headers = data.pop("headers")
|
||||
if _proxy_headers:
|
||||
data["extra_headers"] = {**(data.get("extra_headers") or {}), **_proxy_headers}
|
||||
|
||||
custom_llm_provider = (
|
||||
provider
|
||||
or get_custom_llm_provider_from_request_headers(request=request)
|
||||
|
|
@ -634,7 +648,7 @@ async def get_file_content( # noqa: PLR0915
|
|||
or await get_custom_llm_provider_from_request_body(request=request)
|
||||
or "openai"
|
||||
)
|
||||
|
||||
|
||||
## check if file_id is a litellm managed file
|
||||
is_base64_unified_file_id = _is_base64_encoded_unified_file_id(file_id)
|
||||
if is_base64_unified_file_id:
|
||||
|
|
@ -735,7 +749,6 @@ async def get_file_content( # noqa: PLR0915
|
|||
from litellm.proxy.openai_files_endpoints.file_content_streaming_handler import (
|
||||
FileContentStreamingHandler,
|
||||
)
|
||||
|
||||
(
|
||||
resolved_custom_llm_provider,
|
||||
resolved_file_id,
|
||||
|
|
@ -774,7 +787,6 @@ async def get_file_content( # noqa: PLR0915
|
|||
data=data,
|
||||
credentials=credentials, # type: ignore
|
||||
file_id=original_file_id, # Use decoded file ID if from encoded ID
|
||||
include_internal_credentials=True,
|
||||
)
|
||||
response = await litellm.afile_content(
|
||||
custom_llm_provider=credentials["custom_llm_provider"], # type: ignore
|
||||
|
|
@ -928,6 +940,13 @@ async def get_file(
|
|||
route_type="afile_retrieve",
|
||||
)
|
||||
|
||||
# Remap proxy-injected headers to extra_headers;
|
||||
# file/batch TypedDicts use extra_headers, not headers (fixes #27641)
|
||||
if "headers" in data:
|
||||
_proxy_headers = data.pop("headers")
|
||||
if _proxy_headers:
|
||||
data["extra_headers"] = {**(data.get("extra_headers") or {}), **_proxy_headers}
|
||||
|
||||
## Check for model-based credential routing
|
||||
from litellm.proxy.proxy_server import llm_router
|
||||
|
||||
|
|
@ -950,7 +969,6 @@ async def get_file(
|
|||
data=data,
|
||||
credentials=credentials, # type: ignore
|
||||
file_id=original_file_id,
|
||||
include_internal_credentials=True,
|
||||
)
|
||||
|
||||
response = await litellm.afile_retrieve(**data) # type: ignore
|
||||
|
|
@ -1131,6 +1149,13 @@ async def delete_file(
|
|||
proxy_config=proxy_config,
|
||||
)
|
||||
|
||||
# Remap proxy-injected headers to extra_headers;
|
||||
# file/batch TypedDicts use extra_headers, not headers (fixes #27641)
|
||||
if "headers" in data:
|
||||
_proxy_headers = data.pop("headers")
|
||||
if _proxy_headers:
|
||||
data["extra_headers"] = {**(data.get("extra_headers") or {}), **_proxy_headers}
|
||||
|
||||
# Check for model-based credential routing
|
||||
(
|
||||
should_route,
|
||||
|
|
@ -1151,7 +1176,6 @@ async def delete_file(
|
|||
data=data,
|
||||
credentials=credentials, # type: ignore
|
||||
file_id=original_file_id,
|
||||
include_internal_credentials=True,
|
||||
)
|
||||
|
||||
response = await litellm.afile_delete(
|
||||
|
|
@ -1315,6 +1339,13 @@ async def list_files(
|
|||
route_type=CallTypes.alist_fine_tuning_jobs.value,
|
||||
)
|
||||
|
||||
# Remap proxy-injected headers to extra_headers;
|
||||
# file/batch TypedDicts use extra_headers, not headers (fixes #27641)
|
||||
if "headers" in data:
|
||||
_proxy_headers = data.pop("headers")
|
||||
if _proxy_headers:
|
||||
data["extra_headers"] = {**(data.get("extra_headers") or {}), **_proxy_headers}
|
||||
|
||||
response: Optional[Any] = None
|
||||
|
||||
# Check for model-based credential routing (no file_id encoding check for list)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue