From 100cfc11acf73e6c8bd92f7f856568f7623f0d4f Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Wed, 3 Dec 2025 14:13:28 -0800 Subject: [PATCH] [Bug Fix] Parallel Request Limiter with /messages (#17426) * fix: use standard_logging_object for parallel request limiter * fix test parallel request limtier --- .../hooks/parallel_request_limiter_v3.py | 34 ++++++++++--------- .../hooks/test_parallel_request_limiter_v3.py | 10 +++--- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/litellm/proxy/hooks/parallel_request_limiter_v3.py b/litellm/proxy/hooks/parallel_request_limiter_v3.py index 9436df585a..2abba1d497 100644 --- a/litellm/proxy/hooks/parallel_request_limiter_v3.py +++ b/litellm/proxy/hooks/parallel_request_limiter_v3.py @@ -1343,19 +1343,19 @@ class _PROXY_MaxParallelRequestsHandler_v3(CustomLogger): "INSIDE parallel request limiter ASYNC SUCCESS LOGGING" ) - # Get metadata from kwargs - litellm_metadata = kwargs["litellm_params"].get( - get_metadata_variable_name_from_kwargs(kwargs), {} + # Get metadata from standard_logging_object - this correctly handles both + # 'metadata' and 'litellm_metadata' fields from litellm_params + standard_logging_object = kwargs.get("standard_logging_object") or {} + standard_logging_metadata = standard_logging_object.get("metadata") or {} + + # user_api_key_hash is the same as user_api_key (it's the hash) + user_api_key = standard_logging_metadata.get("user_api_key_hash") + user_api_key_user_id = standard_logging_metadata.get("user_api_key_user_id") + user_api_key_team_id = standard_logging_metadata.get("user_api_key_team_id") + user_api_key_organization_id = standard_logging_metadata.get( + "user_api_key_org_id" ) - if litellm_metadata is None: - return - user_api_key = litellm_metadata.get("user_api_key") - user_api_key_user_id = litellm_metadata.get("user_api_key_user_id") - user_api_key_team_id = litellm_metadata.get("user_api_key_team_id") - user_api_key_organization_id = litellm_metadata.get( - "user_api_key_organization_id" - ) - user_api_key_end_user_id = kwargs.get("user") or litellm_metadata.get( + user_api_key_end_user_id = kwargs.get("user") or standard_logging_metadata.get( "user_api_key_end_user_id" ) model_group = get_model_group_from_litellm_kwargs(kwargs) @@ -1501,10 +1501,12 @@ class _PROXY_MaxParallelRequestsHandler_v3(CustomLogger): litellm_parent_otel_span: Union[ Span, None ] = _get_parent_otel_span_from_kwargs(kwargs) - litellm_metadata = kwargs["litellm_params"]["metadata"] - user_api_key = ( - litellm_metadata.get("user_api_key") if litellm_metadata else None - ) + # Get metadata from standard_logging_object - this correctly handles both + # 'metadata' and 'litellm_metadata' fields from litellm_params + standard_logging_object = kwargs.get("standard_logging_object") or {} + standard_logging_metadata = standard_logging_object.get("metadata") or {} + user_api_key = standard_logging_metadata.get("user_api_key_hash") + pipeline_operations: List[RedisPipelineIncrementOperation] = [] if user_api_key: diff --git a/tests/test_litellm/proxy/hooks/test_parallel_request_limiter_v3.py b/tests/test_litellm/proxy/hooks/test_parallel_request_limiter_v3.py index 6574c500fc..c8c30d41b5 100644 --- a/tests/test_litellm/proxy/hooks/test_parallel_request_limiter_v3.py +++ b/tests/test_litellm/proxy/hooks/test_parallel_request_limiter_v3.py @@ -22,6 +22,7 @@ from litellm.proxy.hooks.parallel_request_limiter_v3 import ( from litellm.proxy.utils import InternalUsageCache, ProxyLogging, hash_token from litellm.types.utils import ModelResponse, Usage + class TimeController: def __init__(self): self._current = datetime.utcnow() @@ -461,10 +462,11 @@ async def test_token_rate_limit_type_respected_v3(monkeypatch, token_rate_limit_ ) # Create mock kwargs for the success event + # Use standard_logging_object which is the canonical source for metadata mock_kwargs = { - "litellm_params": { + "standard_logging_object": { "metadata": { - "user_api_key": _api_key, + "user_api_key_hash": _api_key, "user_api_key_user_id": None, "user_api_key_team_id": None, "user_api_key_end_user_id": None, @@ -532,8 +534,8 @@ async def test_async_log_failure_event_v3(): internal_usage_cache=InternalUsageCache(local_cache) ) - # Mock kwargs with user_api_key - mock_kwargs = {"litellm_params": {"metadata": {"user_api_key": _api_key}}} + # Mock kwargs with user_api_key via standard_logging_object + mock_kwargs = {"standard_logging_object": {"metadata": {"user_api_key_hash": _api_key}}} # Capture pipeline operations captured_ops = []