mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-17 04:34:25 +00:00
fix(logging): stop the spend metadata merge from walking a dict the logging thread writes to (#46044)
This commit is contained in:
parent
3ef0b35255
commit
aa32e4cc88
2 changed files with 57 additions and 2 deletions
|
|
@ -318,7 +318,7 @@ def remove_items_at_indices(items: _PoppableByIndex | None, indices: Iterable[in
|
|||
items.pop(index)
|
||||
|
||||
|
||||
def add_missing_spend_metadata_to_litellm_metadata(litellm_metadata: dict, metadata: dict) -> dict:
|
||||
def add_missing_spend_metadata_to_litellm_metadata(litellm_metadata: dict, metadata: Mapping[str, object]) -> dict:
|
||||
"""
|
||||
Helper to get litellm metadata for spend tracking
|
||||
|
||||
|
|
@ -326,7 +326,7 @@ def add_missing_spend_metadata_to_litellm_metadata(litellm_metadata: dict, metad
|
|||
and user_api_key values are in 'metadata'.
|
||||
"""
|
||||
potential_spend_tracking_metadata_substring: Final = "user_api_key"
|
||||
for key, value in metadata.items():
|
||||
for key, value in dict(metadata).items():
|
||||
if potential_spend_tracking_metadata_substring in key:
|
||||
litellm_metadata[key] = value
|
||||
return litellm_metadata
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
"""Tests for litellm_core_utils.core_helpers module."""
|
||||
|
||||
import logging
|
||||
import threading
|
||||
from collections.abc import Iterator, Mapping
|
||||
from typing import Final
|
||||
|
||||
import httpx
|
||||
|
|
@ -13,6 +15,7 @@ from litellm.litellm_core_utils.core_helpers import (
|
|||
budget_reservation_from_metadata,
|
||||
drop_params_env_flag,
|
||||
drop_params_flag,
|
||||
get_litellm_metadata_from_kwargs,
|
||||
get_parent_otel_span_from_kwargs,
|
||||
get_or_create_metadata_bucket,
|
||||
get_provider_response_headers_from_hidden_params,
|
||||
|
|
@ -587,3 +590,55 @@ class TestProviderResponseHeadersInHiddenParams:
|
|||
|
||||
assert get_provider_response_headers_from_hidden_params(sibling) is None
|
||||
assert "additional_headers" not in sibling._hidden_params
|
||||
|
||||
|
||||
def test_spend_metadata_merge_survives_the_logging_thread_inserting_into_the_request_metadata() -> None:
|
||||
metadata: Final[dict[str, object]] = {}
|
||||
|
||||
def logging_thread_records_hidden_params() -> None:
|
||||
metadata["hidden_params"] = {"response_cost": 0.1}
|
||||
|
||||
class KeyCheckedWhileTheLoggingThreadRuns(str):
|
||||
def __contains__(self, key: str) -> bool:
|
||||
writer: Final = threading.Thread(target=logging_thread_records_hidden_params)
|
||||
writer.start()
|
||||
writer.join()
|
||||
return super().__contains__(key)
|
||||
|
||||
metadata[KeyCheckedWhileTheLoggingThreadRuns("user_api_key_alias")] = "alias"
|
||||
metadata["user_api_key_hash"] = "hash"
|
||||
metadata["requester_ip_address"] = "10.0.0.1"
|
||||
litellm_metadata: Final[dict[str, object]] = {"user_api_key_alias": "stale", "model_group": "claude"}
|
||||
|
||||
merged: Final = get_litellm_metadata_from_kwargs(
|
||||
{"litellm_params": {"metadata": metadata, "litellm_metadata": litellm_metadata}}
|
||||
)
|
||||
|
||||
assert "hidden_params" in metadata
|
||||
assert merged == {"user_api_key_alias": "alias", "user_api_key_hash": "hash", "model_group": "claude"}
|
||||
|
||||
|
||||
def test_spend_metadata_merge_reads_request_metadata_that_is_a_read_only_mapping() -> None:
|
||||
class ReadOnlyMetadata(Mapping[str, object]):
|
||||
def __init__(self, values: dict[str, object]) -> None:
|
||||
self._values: Final = values
|
||||
|
||||
def __getitem__(self, key: str) -> object:
|
||||
return self._values[key]
|
||||
|
||||
def __iter__(self) -> Iterator[str]:
|
||||
return iter(self._values)
|
||||
|
||||
def __len__(self) -> int:
|
||||
return len(self._values)
|
||||
|
||||
merged: Final = get_litellm_metadata_from_kwargs(
|
||||
{
|
||||
"litellm_params": {
|
||||
"metadata": ReadOnlyMetadata({"user_api_key_hash": "hash", "requester_ip_address": "10.0.0.1"}),
|
||||
"litellm_metadata": {"model_group": "claude"},
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
assert merged == {"user_api_key_hash": "hash", "model_group": "claude"}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue