Pass router tags in request headers - x-litellm-tags (#8609)

* feat(litellm_pre_call_utils.py): support `x-litellm-tags` request header

allow tag based routing + spend tracking via request headers

* docs(request_headers.md): document new `x-litellm-tags` for tag based routing and spend tracking

* docs(tag_routing.md): add to docs

* fix(utils.py): only pass str values for openai metadata param

* fix(utils.py): drop non-str values for metadata param to openai

preview-feature, otel span was being sent in
This commit is contained in:
Krish Dholakia 2025-02-18 08:26:22 -08:00 committed by GitHub
parent 7bfd816d3b
commit 2340f1b31f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 122 additions and 22 deletions

View file

@ -1,7 +1,7 @@
import asyncio
import copy
import time
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
from fastapi import Request
from starlette.datastructures import Headers
@ -17,6 +17,7 @@ from litellm.proxy._types import (
TeamCallbackMetadata,
UserAPIKeyAuth,
)
from litellm.router import Router
from litellm.types.llms.anthropic import ANTHROPIC_API_HEADERS
from litellm.types.services import ServiceTypes
from litellm.types.utils import (
@ -407,6 +408,28 @@ class LiteLLMProxyRequestSetup:
callback_vars=callback_vars_dict,
)
@staticmethod
def add_request_tag_to_metadata(
llm_router: Optional[Router],
headers: dict,
data: dict,
) -> Optional[List[str]]:
tags = None
if llm_router and llm_router.enable_tag_filtering is True:
# Check request headers for tags
if "x-litellm-tags" in headers:
if isinstance(headers["x-litellm-tags"], str):
_tags = headers["x-litellm-tags"].split(",")
tags = [tag.strip() for tag in _tags]
elif isinstance(headers["x-litellm-tags"], list):
tags = headers["x-litellm-tags"]
# Check request body for tags
if "tags" in data and isinstance(data["tags"], list):
tags = data["tags"]
return tags
async def add_litellm_data_to_request( # noqa: PLR0915
data: dict,
@ -611,10 +634,15 @@ async def add_litellm_data_to_request( # noqa: PLR0915
requester_ip_address = request.client.host
data[_metadata_variable_name]["requester_ip_address"] = requester_ip_address
# Enterprise Only - Check if using tag based routing
if llm_router and llm_router.enable_tag_filtering is True:
if "tags" in data:
data[_metadata_variable_name]["tags"] = data["tags"]
# Check if using tag based routing
tags = LiteLLMProxyRequestSetup.add_request_tag_to_metadata(
llm_router=llm_router,
headers=dict(request.headers),
data=data,
)
if tags is not None:
data[_metadata_variable_name]["tags"] = tags
# Team Callbacks controls
callback_settings_obj = _get_dynamic_logging_metadata(