mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-18 04:44:37 +00:00
fix(batches): keep the team key on the team host when a request sends only api_base
A request api_base now replaces the team deployment's api_base only when the request also brings its own api_key, and a non-string api_key or api_base is ignored, as on the merge base.
This commit is contained in:
parent
244e112599
commit
772d1ce024
2 changed files with 30 additions and 9 deletions
|
|
@ -43,7 +43,6 @@ FILE_LIST_CONTINUATION_CHUNK_SIZE: Final = 500
|
|||
BATCH_CREATE_HIDDEN_PARAM: Final = "batch_create"
|
||||
LITELLM_EXECUTED_BATCH_ID_PREFIX: Final = "litellm_batch_"
|
||||
EXPLICIT_CREDENTIAL_KEYS: Final = frozenset({"api_key", "api_base", "litellm_credential_name"})
|
||||
_REQUEST_CREDENTIAL_KEYS: Final = frozenset({"api_key", "api_base"})
|
||||
|
||||
|
||||
def validate_file_list_limit(limit: int | None) -> None:
|
||||
|
|
@ -649,8 +648,18 @@ def get_team_provider_credentials(
|
|||
return None
|
||||
|
||||
|
||||
def explicit_request_credentials(data: Mapping[str, object]) -> Mapping[str, object]:
|
||||
return MappingProxyType({key: value for key, value in data.items() if key in _REQUEST_CREDENTIAL_KEYS and value})
|
||||
def _non_empty_string(value: object) -> str | None:
|
||||
return value if isinstance(value, str) and value else None
|
||||
|
||||
|
||||
def explicit_request_credentials(data: Mapping[str, object]) -> Mapping[str, str]:
|
||||
api_key: Final = _non_empty_string(data.get("api_key"))
|
||||
if api_key is None:
|
||||
return MappingProxyType({})
|
||||
api_base: Final = _non_empty_string(data.get("api_base"))
|
||||
if api_base is None:
|
||||
return MappingProxyType({"api_key": api_key})
|
||||
return MappingProxyType({"api_key": api_key, "api_base": api_base})
|
||||
|
||||
|
||||
def apply_team_provider_credentials(
|
||||
|
|
@ -664,9 +673,10 @@ def apply_team_provider_credentials(
|
|||
``get_team_provider_credentials`` and merge them into ``data`` in-place.
|
||||
Leaves ``data`` untouched when no authorized deployment matches, so the
|
||||
caller falls back to environment-variable credentials exactly as before.
|
||||
An ``api_key`` or ``api_base`` the request carries itself (a provider key
|
||||
forwarded with ``forward_llm_provider_auth_headers``) replaces the
|
||||
deployment's, as on chat completions.
|
||||
An ``api_key`` the request carries itself (a provider key forwarded with
|
||||
``forward_llm_provider_auth_headers``) replaces the deployment's, and the
|
||||
request's ``api_base`` replaces the deployment's only alongside that key,
|
||||
so the deployment's key never goes to a host the caller picked.
|
||||
"""
|
||||
credentials: Final = get_team_provider_credentials(
|
||||
llm_router=llm_router,
|
||||
|
|
|
|||
|
|
@ -722,12 +722,23 @@ def test_a_restricted_key_outside_the_team_wildcard_never_resolves_its_credentia
|
|||
({}, "team-openai-key", "https://team.example/v1"),
|
||||
({"api_key": ""}, "team-openai-key", "https://team.example/v1"),
|
||||
({"api_key": "sk-forwarded"}, "sk-forwarded", "https://team.example/v1"),
|
||||
({"api_base": "https://caller.example/v1"}, "team-openai-key", "https://caller.example/v1"),
|
||||
({"api_base": "https://caller.example/v1"}, "team-openai-key", "https://team.example/v1"),
|
||||
(
|
||||
{"api_key": "sk-forwarded", "api_base": "https://caller.example/v1"},
|
||||
"sk-forwarded",
|
||||
"https://caller.example/v1",
|
||||
),
|
||||
({"api_key": 123}, "team-openai-key", "https://team.example/v1"),
|
||||
(
|
||||
{"api_key": "sk-forwarded", "api_base": ["https://caller.example/v1"]},
|
||||
"sk-forwarded",
|
||||
"https://team.example/v1",
|
||||
),
|
||||
({"litellm_credential_name": "no-such-credential"}, "team-openai-key", "https://team.example/v1"),
|
||||
],
|
||||
)
|
||||
def test_a_key_or_base_the_request_carries_replaces_only_that_part_of_the_team_credentials(
|
||||
request_credentials: dict[str, str], sent_api_key: str, sent_api_base: str
|
||||
def test_the_team_key_only_goes_to_the_team_host_unless_the_request_brings_its_own_key(
|
||||
request_credentials: dict[str, object], sent_api_key: str, sent_api_base: str
|
||||
):
|
||||
data: Final[dict[str, object]] = dict(request_credentials)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue