diff --git a/docs/my-website/docs/enterprise.md b/docs/my-website/docs/enterprise.md index 3c5201b8c90..7035b25ce39 100644 --- a/docs/my-website/docs/enterprise.md +++ b/docs/my-website/docs/enterprise.md @@ -7,13 +7,11 @@ Interested in Enterprise? Schedule a meeting with us here 👉 ::: -## [AWS Marketplace Listing](https://aws.amazon.com/marketplace/pp/prodview-gdm3gswgjhgjo?sr=0-1&ref_=beagle&applicationId=AWSMPContessa) - Deploy managed LiteLLM Proxy within your VPC. Includes all enterprise features. -[**View Listing**](https://aws.amazon.com/marketplace/pp/prodview-gdm3gswgjhgjo?sr=0-1&ref_=beagle&applicationId=AWSMPContessa) +[**View AWS Marketplace Listing**](https://aws.amazon.com/marketplace/pp/prodview-gdm3gswgjhgjo?sr=0-1&ref_=beagle&applicationId=AWSMPContessa) [**Get early access**](https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat) @@ -26,6 +24,7 @@ This covers: - ✅ [JWT-Auth](../docs/proxy/token_auth.md) - ✅ [Control available public, private routes](./proxy/enterprise#control-available-public-private-routes) - ✅ [[BETA] AWS Key Manager v2 - Key Decryption](./proxy/enterprise#beta-aws-key-manager---key-decryption) + - ✅ Track Request IP Address - ✅ [Use LiteLLM keys/authentication on Pass Through Endpoints](./proxy/pass_through#✨-enterprise---use-litellm-keysauthentication-on-pass-through-endpoints) - ✅ [Enforce Required Params for LLM Requests (ex. Reject requests missing ["metadata"]["generation_name"])](./proxy/enterprise#enforce-required-params-for-llm-requests) - **Spend Tracking** diff --git a/docs/my-website/docs/proxy/enterprise.md b/docs/my-website/docs/proxy/enterprise.md index de1e2c9d77b..8aaf36c3e9c 100644 --- a/docs/my-website/docs/proxy/enterprise.md +++ b/docs/my-website/docs/proxy/enterprise.md @@ -18,6 +18,7 @@ Features: - ✅ [JWT-Auth](../docs/proxy/token_auth.md) - ✅ [Control available public, private routes](#control-available-public-private-routes) - ✅ [[BETA] AWS Key Manager v2 - Key Decryption](#beta-aws-key-manager---key-decryption) + - ✅ Track Request IP Address - ✅ [Use LiteLLM keys/authentication on Pass Through Endpoints](pass_through#✨-enterprise---use-litellm-keysauthentication-on-pass-through-endpoints) - ✅ [Enforce Required Params for LLM Requests (ex. Reject requests missing ["metadata"]["generation_name"])](#enforce-required-params-for-llm-requests) - **Spend Tracking** diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py index 4a15281089c..966889ee247 100644 --- a/litellm/proxy/_types.py +++ b/litellm/proxy/_types.py @@ -1319,6 +1319,7 @@ class LiteLLM_SpendLogs(LiteLLMBase): cache_hit: Optional[str] = "False" cache_key: Optional[str] = None request_tags: Optional[Json] = None + requester_ip_address: Optional[str] = None class LiteLLM_ErrorLogs(LiteLLMBase): @@ -1510,6 +1511,7 @@ class SpendLogsMetadata(TypedDict): spend_logs_metadata: Optional[ dict ] # special param to log k,v pairs to spendlogs for a call + requester_ip_address: Optional[str] class SpendLogsPayload(TypedDict): @@ -1534,6 +1536,7 @@ class SpendLogsPayload(TypedDict): request_tags: str # json str team_id: Optional[str] end_user: Optional[str] + requester_ip_address: Optional[str] class SpanAttributes(str, enum.Enum): diff --git a/litellm/proxy/litellm_pre_call_utils.py b/litellm/proxy/litellm_pre_call_utils.py index 673b027ca8c..9417731cdd7 100644 --- a/litellm/proxy/litellm_pre_call_utils.py +++ b/litellm/proxy/litellm_pre_call_utils.py @@ -65,6 +65,8 @@ async def add_litellm_data_to_request( dict: The modified data dictionary. """ + from litellm.proxy.proxy_server import premium_user + query_params = dict(request.query_params) if "api-version" in query_params: data["api_version"] = query_params["api-version"] @@ -156,6 +158,19 @@ async def add_litellm_data_to_request( if user_api_key_dict.allowed_model_region is not None: data["allowed_model_region"] = user_api_key_dict.allowed_model_region + ## [Enterprise Only] Add User-IP Address + requester_ip_address = "" + if premium_user is True: + # Only set the IP Address for Enterprise Users + if ( + request is not None + and hasattr(request, "client") + and hasattr(request.client, "host") + and request.client is not None + ): + requester_ip_address = request.client.host + data[_metadata_variable_name]["requester_ip_address"] = requester_ip_address + ### TEAM-SPECIFIC PARAMS ### if user_api_key_dict.team_id is not None: team_config = await proxy_config.load_team_config( diff --git a/litellm/proxy/schema.prisma b/litellm/proxy/schema.prisma index 4dd42feb0a2..528d7e98df8 100644 --- a/litellm/proxy/schema.prisma +++ b/litellm/proxy/schema.prisma @@ -191,6 +191,7 @@ model LiteLLM_SpendLogs { request_tags Json @default("[]") team_id String? end_user String? + requester_ip_address String? } // View spend, model, api_key per request diff --git a/litellm/proxy/spend_tracking/spend_tracking_utils.py b/litellm/proxy/spend_tracking/spend_tracking_utils.py index e4027b98482..cd7004e41d5 100644 --- a/litellm/proxy/spend_tracking/spend_tracking_utils.py +++ b/litellm/proxy/spend_tracking/spend_tracking_utils.py @@ -55,6 +55,7 @@ def get_logging_payload( user_api_key_user_id=None, user_api_key_team_alias=None, spend_logs_metadata=None, + requester_ip_address=None, ) if isinstance(metadata, dict): verbose_proxy_logger.debug( @@ -109,6 +110,7 @@ def get_logging_payload( api_base=litellm_params.get("api_base", ""), model_group=_model_group, model_id=_model_id, + requester_ip_address=clean_metadata.get("requester_ip_address", None), ) verbose_proxy_logger.debug( diff --git a/litellm/tests/test_spend_logs.py b/litellm/tests/test_spend_logs.py index 4cd43bb048b..012a1db51f6 100644 --- a/litellm/tests/test_spend_logs.py +++ b/litellm/tests/test_spend_logs.py @@ -70,6 +70,7 @@ def test_spend_logs_payload(): "user_api_key_team_id": None, "user_api_key_team_alias": None, "user_api_key_metadata": {}, + "requester_ip_address": "127.0.0.1", "spend_logs_metadata": {"hello": "world"}, "headers": { "content-type": "application/json", diff --git a/schema.prisma b/schema.prisma index 2e39348ff0c..970a1197e68 100644 --- a/schema.prisma +++ b/schema.prisma @@ -191,6 +191,7 @@ model LiteLLM_SpendLogs { request_tags Json @default("[]") team_id String? end_user String? + requester_ip_address String? } // View spend, model, api_key per request @@ -256,4 +257,4 @@ model LiteLLM_AuditLog { object_id String // id of the object being audited. This can be the key id, team id, user id, model id before_value Json? // value of the row updated_values Json? // value of the row after change -} \ No newline at end of file +}