mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-29 01:42:19 +00:00
fix(logging): read used_client_oauth_token from the proxy-stamped metadata slot
On routes that carry proxy metadata in litellm_metadata, metadata is the caller's own body field, and merge_litellm_metadata lets it win. Resolve the flag from litellm_metadata when the proxy stamped it there so a caller cannot set it in the standard logging payload
This commit is contained in:
parent
f538d135f0
commit
c4f6d82a4f
2 changed files with 44 additions and 1 deletions
|
|
@ -288,6 +288,13 @@ _STANDARD_LOGGING_METADATA_KEYS: Final[frozenset[str]] = (
|
|||
)
|
||||
|
||||
|
||||
def _proxy_stamped_used_client_oauth_token(metadata: object, litellm_params: Mapping[str, object] | None) -> object:
|
||||
litellm_metadata: Final = litellm_params.get("litellm_metadata") if litellm_params is not None else None
|
||||
if isinstance(litellm_metadata, Mapping) and "used_client_oauth_token" in litellm_metadata:
|
||||
return litellm_metadata["used_client_oauth_token"]
|
||||
return metadata.get("used_client_oauth_token") if isinstance(metadata, Mapping) else None
|
||||
|
||||
|
||||
def _get_provider_request_id(original_exception: Exception) -> str | None:
|
||||
try:
|
||||
error_response: Final = getattr(original_exception, "response", None)
|
||||
|
|
@ -5786,7 +5793,7 @@ class StandardLoggingPayloadSetup:
|
|||
team_alias=None,
|
||||
team_id=None,
|
||||
used_client_oauth_token=resolve_used_client_oauth_token(
|
||||
metadata.get("used_client_oauth_token") if isinstance(metadata, dict) else None,
|
||||
_proxy_stamped_used_client_oauth_token(metadata, litellm_params),
|
||||
custom_llm_provider,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4891,6 +4891,42 @@ def test_get_standard_logging_object_payload_resolves_used_client_oauth_token_ag
|
|||
assert payload["metadata"]["used_client_oauth_token"] is expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"metadata, litellm_metadata, expected",
|
||||
[
|
||||
({"used_client_oauth_token": True}, {"used_client_oauth_token": False}, False),
|
||||
({"used_client_oauth_token": False}, {"used_client_oauth_token": True}, True),
|
||||
({"used_client_oauth_token": True}, {"compression_savings": 1}, True),
|
||||
],
|
||||
)
|
||||
def test_get_standard_logging_object_payload_takes_used_client_oauth_token_from_the_proxy_stamped_slot(
|
||||
logging_obj, metadata: dict, litellm_metadata: dict, expected: bool
|
||||
):
|
||||
"""On routes that carry proxy metadata in `litellm_metadata`, `metadata` is the caller's own body field,
|
||||
so a caller writing the flag there must not override what the proxy stamped."""
|
||||
from datetime import datetime
|
||||
|
||||
from litellm.litellm_core_utils.litellm_logging import get_standard_logging_object_payload
|
||||
|
||||
now = datetime.now()
|
||||
payload = get_standard_logging_object_payload(
|
||||
kwargs={
|
||||
"model": "claude-sonnet-5",
|
||||
"messages": [],
|
||||
"custom_llm_provider": "anthropic",
|
||||
"litellm_params": {"metadata": metadata, "litellm_metadata": litellm_metadata},
|
||||
},
|
||||
init_response_obj={},
|
||||
start_time=now,
|
||||
end_time=now,
|
||||
logging_obj=logging_obj,
|
||||
status="success",
|
||||
)
|
||||
|
||||
assert payload is not None
|
||||
assert payload["metadata"]["used_client_oauth_token"] is expected
|
||||
|
||||
|
||||
def test_get_standard_logging_object_payload_carries_matched_access_groups(logging_obj):
|
||||
"""Access groups stamped at auth time reach the logging payload, so integrations see what a request billed."""
|
||||
from datetime import datetime
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue