litellm-enterprise 0.1.20__py3-none-any.whl → 0.1.21__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- litellm_enterprise/enterprise_callbacks/.pytest_cache/.gitignore +2 -0
- litellm_enterprise/enterprise_callbacks/.pytest_cache/CACHEDIR.TAG +4 -0
- litellm_enterprise/enterprise_callbacks/.pytest_cache/README.md +8 -0
- litellm_enterprise/enterprise_callbacks/.pytest_cache/v/cache/nodeids +1 -0
- litellm_enterprise/enterprise_callbacks/.pytest_cache/v/cache/stepwise +1 -0
- litellm_enterprise/enterprise_callbacks/generic_api_callback.py +1 -1
- litellm_enterprise/enterprise_callbacks/llama_guard.py +2 -10
- litellm_enterprise/enterprise_callbacks/llm_guard.py +2 -9
- litellm_enterprise/enterprise_callbacks/pagerduty/pagerduty.py +9 -12
- litellm_enterprise/enterprise_callbacks/send_emails/base_email.py +61 -1
- litellm_enterprise/integrations/custom_guardrail.py +1 -2
- litellm_enterprise/proxy/common_utils/check_batch_cost.py +3 -4
- litellm_enterprise/proxy/hooks/managed_files.py +6 -24
- litellm_enterprise/proxy/management_endpoints/internal_user_endpoints.py +0 -1
- litellm_enterprise/proxy/management_endpoints/key_management_endpoints.py +12 -0
- litellm_enterprise/proxy/vector_stores/endpoints.py +49 -7
- litellm_enterprise/types/enterprise_callbacks/send_emails.py +14 -2
- {litellm_enterprise-0.1.20.dist-info → litellm_enterprise-0.1.21.dist-info}/METADATA +1 -1
- {litellm_enterprise-0.1.20.dist-info → litellm_enterprise-0.1.21.dist-info}/RECORD +21 -18
- litellm_enterprise/integrations/prometheus.py +0 -2361
- litellm_enterprise/proxy/guardrails/endpoints.py +0 -41
- {litellm_enterprise-0.1.20.dist-info → litellm_enterprise-0.1.21.dist-info}/LICENSE.md +0 -0
- {litellm_enterprise-0.1.20.dist-info → litellm_enterprise-0.1.21.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# pytest cache directory #
|
|
2
|
+
|
|
3
|
+
This directory contains data from the pytest's cache plugin,
|
|
4
|
+
which provides the `--lf` and `--ff` options, as well as the `cache` fixture.
|
|
5
|
+
|
|
6
|
+
**Do not** commit this to version control.
|
|
7
|
+
|
|
8
|
+
See [the docs](https://docs.pytest.org/en/stable/how-to/cache.html) for more information.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[]
|
|
@@ -23,7 +23,7 @@ import litellm
|
|
|
23
23
|
from litellm._logging import verbose_proxy_logger
|
|
24
24
|
from litellm.integrations.custom_logger import CustomLogger
|
|
25
25
|
from litellm.proxy._types import UserAPIKeyAuth
|
|
26
|
-
from litellm.types.utils import Choices, ModelResponse
|
|
26
|
+
from litellm.types.utils import CallTypesLiteral, Choices, ModelResponse
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
class _ENTERPRISE_LlamaGuard(CustomLogger):
|
|
@@ -98,15 +98,7 @@ class _ENTERPRISE_LlamaGuard(CustomLogger):
|
|
|
98
98
|
self,
|
|
99
99
|
data: dict,
|
|
100
100
|
user_api_key_dict: UserAPIKeyAuth,
|
|
101
|
-
call_type:
|
|
102
|
-
"completion",
|
|
103
|
-
"embeddings",
|
|
104
|
-
"image_generation",
|
|
105
|
-
"moderation",
|
|
106
|
-
"audio_transcription",
|
|
107
|
-
"responses",
|
|
108
|
-
"mcp_call",
|
|
109
|
-
],
|
|
101
|
+
call_type: CallTypesLiteral,
|
|
110
102
|
):
|
|
111
103
|
"""
|
|
112
104
|
- Calls the Llama Guard Endpoint
|
|
@@ -17,6 +17,7 @@ from litellm._logging import verbose_proxy_logger
|
|
|
17
17
|
from litellm.integrations.custom_logger import CustomLogger
|
|
18
18
|
from litellm.proxy._types import UserAPIKeyAuth
|
|
19
19
|
from litellm.secret_managers.main import get_secret_str
|
|
20
|
+
from litellm.types.utils import CallTypesLiteral
|
|
20
21
|
from litellm.utils import get_formatted_prompt
|
|
21
22
|
|
|
22
23
|
|
|
@@ -120,15 +121,7 @@ class _ENTERPRISE_LLMGuard(CustomLogger):
|
|
|
120
121
|
self,
|
|
121
122
|
data: dict,
|
|
122
123
|
user_api_key_dict: UserAPIKeyAuth,
|
|
123
|
-
call_type:
|
|
124
|
-
"completion",
|
|
125
|
-
"embeddings",
|
|
126
|
-
"image_generation",
|
|
127
|
-
"moderation",
|
|
128
|
-
"audio_transcription",
|
|
129
|
-
"responses",
|
|
130
|
-
"mcp_call",
|
|
131
|
-
],
|
|
124
|
+
call_type: CallTypesLiteral,
|
|
132
125
|
):
|
|
133
126
|
"""
|
|
134
127
|
- Calls the LLM Guard Endpoint
|
|
@@ -31,6 +31,7 @@ from litellm.types.integrations.pagerduty import (
|
|
|
31
31
|
PagerDutyRequestBody,
|
|
32
32
|
)
|
|
33
33
|
from litellm.types.utils import (
|
|
34
|
+
CallTypesLiteral,
|
|
34
35
|
StandardLoggingPayload,
|
|
35
36
|
StandardLoggingPayloadErrorInformation,
|
|
36
37
|
)
|
|
@@ -119,6 +120,7 @@ class PagerDutyAlerting(SlackAlerting):
|
|
|
119
120
|
user_api_key_end_user_id=_meta.get("user_api_key_end_user_id"),
|
|
120
121
|
user_api_key_user_email=_meta.get("user_api_key_user_email"),
|
|
121
122
|
user_api_key_request_route=_meta.get("user_api_key_request_route"),
|
|
123
|
+
user_api_key_auth_metadata=_meta.get("user_api_key_auth_metadata"),
|
|
122
124
|
)
|
|
123
125
|
)
|
|
124
126
|
|
|
@@ -141,17 +143,7 @@ class PagerDutyAlerting(SlackAlerting):
|
|
|
141
143
|
user_api_key_dict: UserAPIKeyAuth,
|
|
142
144
|
cache: DualCache,
|
|
143
145
|
data: dict,
|
|
144
|
-
call_type:
|
|
145
|
-
"completion",
|
|
146
|
-
"text_completion",
|
|
147
|
-
"embeddings",
|
|
148
|
-
"image_generation",
|
|
149
|
-
"moderation",
|
|
150
|
-
"audio_transcription",
|
|
151
|
-
"pass_through_endpoint",
|
|
152
|
-
"rerank",
|
|
153
|
-
"mcp_call",
|
|
154
|
-
],
|
|
146
|
+
call_type: CallTypesLiteral,
|
|
155
147
|
) -> Optional[Union[Exception, str, dict]]:
|
|
156
148
|
"""
|
|
157
149
|
Example of detecting hanging requests by waiting a given threshold.
|
|
@@ -196,7 +188,11 @@ class PagerDutyAlerting(SlackAlerting):
|
|
|
196
188
|
user_api_key_alias=user_api_key_dict.key_alias,
|
|
197
189
|
user_api_key_spend=user_api_key_dict.spend,
|
|
198
190
|
user_api_key_max_budget=user_api_key_dict.max_budget,
|
|
199
|
-
user_api_key_budget_reset_at=
|
|
191
|
+
user_api_key_budget_reset_at=(
|
|
192
|
+
user_api_key_dict.budget_reset_at.isoformat()
|
|
193
|
+
if user_api_key_dict.budget_reset_at
|
|
194
|
+
else None
|
|
195
|
+
),
|
|
200
196
|
user_api_key_org_id=user_api_key_dict.org_id,
|
|
201
197
|
user_api_key_team_id=user_api_key_dict.team_id,
|
|
202
198
|
user_api_key_user_id=user_api_key_dict.user_id,
|
|
@@ -204,6 +200,7 @@ class PagerDutyAlerting(SlackAlerting):
|
|
|
204
200
|
user_api_key_end_user_id=user_api_key_dict.end_user_id,
|
|
205
201
|
user_api_key_user_email=user_api_key_dict.user_email,
|
|
206
202
|
user_api_key_request_route=user_api_key_dict.request_route,
|
|
203
|
+
user_api_key_auth_metadata=user_api_key_dict.metadata,
|
|
207
204
|
)
|
|
208
205
|
)
|
|
209
206
|
|
|
@@ -11,6 +11,7 @@ from litellm_enterprise.types.enterprise_callbacks.send_emails import (
|
|
|
11
11
|
EmailEvent,
|
|
12
12
|
EmailParams,
|
|
13
13
|
SendKeyCreatedEmailEvent,
|
|
14
|
+
SendKeyRotatedEmailEvent,
|
|
14
15
|
)
|
|
15
16
|
|
|
16
17
|
from litellm._logging import verbose_proxy_logger
|
|
@@ -19,10 +20,14 @@ from litellm.integrations.email_templates.email_footer import EMAIL_FOOTER
|
|
|
19
20
|
from litellm.integrations.email_templates.key_created_email import (
|
|
20
21
|
KEY_CREATED_EMAIL_TEMPLATE,
|
|
21
22
|
)
|
|
23
|
+
from litellm.integrations.email_templates.key_rotated_email import (
|
|
24
|
+
KEY_ROTATED_EMAIL_TEMPLATE,
|
|
25
|
+
)
|
|
22
26
|
from litellm.integrations.email_templates.user_invitation_email import (
|
|
23
27
|
USER_INVITATION_EMAIL_TEMPLATE,
|
|
24
28
|
)
|
|
25
29
|
from litellm.proxy._types import InvitationNew, UserAPIKeyAuth, WebhookEvent
|
|
30
|
+
from litellm.secret_managers.main import get_secret_bool
|
|
26
31
|
from litellm.types.integrations.slack_alerting import LITELLM_LOGO_URL
|
|
27
32
|
|
|
28
33
|
|
|
@@ -32,6 +37,7 @@ class BaseEmailLogger(CustomLogger):
|
|
|
32
37
|
DEFAULT_SUBJECT_TEMPLATES = {
|
|
33
38
|
EmailEvent.new_user_invitation: "LiteLLM: {event_message}",
|
|
34
39
|
EmailEvent.virtual_key_created: "LiteLLM: {event_message}",
|
|
40
|
+
EmailEvent.virtual_key_rotated: "LiteLLM: {event_message}",
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
async def send_user_invitation_email(self, event: WebhookEvent):
|
|
@@ -83,11 +89,58 @@ class BaseEmailLogger(CustomLogger):
|
|
|
83
89
|
f"send_key_created_email_event: {json.dumps(send_key_created_email_event, indent=4, default=str)}"
|
|
84
90
|
)
|
|
85
91
|
|
|
92
|
+
# Check if API key should be included in email
|
|
93
|
+
include_api_key = get_secret_bool(secret_name="EMAIL_INCLUDE_API_KEY", default_value=True)
|
|
94
|
+
if include_api_key is None:
|
|
95
|
+
include_api_key = True # Default to True if not set
|
|
96
|
+
key_token_display = send_key_created_email_event.virtual_key if include_api_key else "[Key hidden for security - retrieve from dashboard]"
|
|
97
|
+
|
|
86
98
|
email_html_content = KEY_CREATED_EMAIL_TEMPLATE.format(
|
|
87
99
|
email_logo_url=email_params.logo_url,
|
|
88
100
|
recipient_email=email_params.recipient_email,
|
|
89
101
|
key_budget=self._format_key_budget(send_key_created_email_event.max_budget),
|
|
90
|
-
key_token=
|
|
102
|
+
key_token=key_token_display,
|
|
103
|
+
base_url=email_params.base_url,
|
|
104
|
+
email_support_contact=email_params.support_contact,
|
|
105
|
+
email_footer=email_params.signature,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
await self.send_email(
|
|
109
|
+
from_email=self.DEFAULT_LITELLM_EMAIL,
|
|
110
|
+
to_email=[email_params.recipient_email],
|
|
111
|
+
subject=email_params.subject,
|
|
112
|
+
html_body=email_html_content,
|
|
113
|
+
)
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
async def send_key_rotated_email(
|
|
117
|
+
self, send_key_rotated_email_event: SendKeyRotatedEmailEvent
|
|
118
|
+
):
|
|
119
|
+
"""
|
|
120
|
+
Send email to user after rotating key for the user
|
|
121
|
+
"""
|
|
122
|
+
email_params = await self._get_email_params(
|
|
123
|
+
user_id=send_key_rotated_email_event.user_id,
|
|
124
|
+
user_email=send_key_rotated_email_event.user_email,
|
|
125
|
+
email_event=EmailEvent.virtual_key_rotated,
|
|
126
|
+
event_message=send_key_rotated_email_event.event_message,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
verbose_proxy_logger.debug(
|
|
130
|
+
f"send_key_rotated_email_event: {json.dumps(send_key_rotated_email_event, indent=4, default=str)}"
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
# Check if API key should be included in email
|
|
134
|
+
include_api_key = get_secret_bool(secret_name="EMAIL_INCLUDE_API_KEY", default_value=True)
|
|
135
|
+
if include_api_key is None:
|
|
136
|
+
include_api_key = True # Default to True if not set
|
|
137
|
+
key_token_display = send_key_rotated_email_event.virtual_key if include_api_key else "[Key hidden for security - retrieve from dashboard]"
|
|
138
|
+
|
|
139
|
+
email_html_content = KEY_ROTATED_EMAIL_TEMPLATE.format(
|
|
140
|
+
email_logo_url=email_params.logo_url,
|
|
141
|
+
recipient_email=email_params.recipient_email,
|
|
142
|
+
key_budget=self._format_key_budget(send_key_rotated_email_event.max_budget),
|
|
143
|
+
key_token=key_token_display,
|
|
91
144
|
base_url=email_params.base_url,
|
|
92
145
|
email_support_contact=email_params.support_contact,
|
|
93
146
|
email_footer=email_params.signature,
|
|
@@ -159,6 +212,13 @@ class BaseEmailLogger(CustomLogger):
|
|
|
159
212
|
self.DEFAULT_SUBJECT_TEMPLATES[EmailEvent.virtual_key_created],
|
|
160
213
|
"key created subject template"
|
|
161
214
|
)
|
|
215
|
+
elif email_event == EmailEvent.virtual_key_rotated:
|
|
216
|
+
custom_subject_key_rotated = os.getenv("EMAIL_SUBJECT_KEY_ROTATED", None)
|
|
217
|
+
subject_template = get_custom_or_default(
|
|
218
|
+
custom_subject_key_rotated,
|
|
219
|
+
self.DEFAULT_SUBJECT_TEMPLATES[EmailEvent.virtual_key_rotated],
|
|
220
|
+
"key rotated subject template"
|
|
221
|
+
)
|
|
162
222
|
else:
|
|
163
223
|
subject_template = "LiteLLM: {event_message}"
|
|
164
224
|
|
|
@@ -29,11 +29,10 @@ class EnterpriseCustomGuardrailHelper:
|
|
|
29
29
|
if event_hook is None or not isinstance(event_hook, Mode):
|
|
30
30
|
return None
|
|
31
31
|
|
|
32
|
-
metadata: dict = data.get("litellm_metadata") or data.get("metadata", {})
|
|
33
32
|
proxy_server_request = data.get("proxy_server_request", {})
|
|
34
33
|
|
|
35
34
|
request_tags = StandardLoggingPayloadSetup._get_request_tags(
|
|
36
|
-
|
|
35
|
+
litellm_params=data,
|
|
37
36
|
proxy_server_request=proxy_server_request,
|
|
38
37
|
)
|
|
39
38
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Polls LiteLLM_ManagedObjectTable to check if the batch job is complete, and if the cost has been tracked.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
import uuid
|
|
5
|
+
from litellm._uuid import uuid
|
|
6
6
|
from datetime import datetime
|
|
7
7
|
from typing import TYPE_CHECKING, Optional, cast
|
|
8
8
|
|
|
@@ -57,7 +57,6 @@ class CheckBatchCost:
|
|
|
57
57
|
"file_purpose": "batch",
|
|
58
58
|
}
|
|
59
59
|
)
|
|
60
|
-
|
|
61
60
|
completed_jobs = []
|
|
62
61
|
|
|
63
62
|
for job in jobs:
|
|
@@ -139,7 +138,7 @@ class CheckBatchCost:
|
|
|
139
138
|
custom_llm_provider = deployment_info.litellm_params.custom_llm_provider
|
|
140
139
|
litellm_model_name = deployment_info.litellm_params.model
|
|
141
140
|
|
|
142
|
-
|
|
141
|
+
model_name, llm_provider, _, _ = get_llm_provider(
|
|
143
142
|
model=litellm_model_name,
|
|
144
143
|
custom_llm_provider=custom_llm_provider,
|
|
145
144
|
)
|
|
@@ -148,9 +147,9 @@ class CheckBatchCost:
|
|
|
148
147
|
await calculate_batch_cost_and_usage(
|
|
149
148
|
file_content_dictionary=file_content_as_dict,
|
|
150
149
|
custom_llm_provider=llm_provider, # type: ignore
|
|
150
|
+
model_name=model_name,
|
|
151
151
|
)
|
|
152
152
|
)
|
|
153
|
-
|
|
154
153
|
logging_obj = LiteLLMLogging(
|
|
155
154
|
model=batch_models[0],
|
|
156
155
|
messages=[{"role": "user", "content": "<retrieve_batch>"}],
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
import asyncio
|
|
5
5
|
import base64
|
|
6
6
|
import json
|
|
7
|
-
import uuid
|
|
8
7
|
from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional, Union, cast
|
|
9
8
|
|
|
10
9
|
from fastapi import HTTPException
|
|
11
10
|
|
|
12
11
|
from litellm import Router, verbose_logger
|
|
12
|
+
from litellm._uuid import uuid
|
|
13
13
|
from litellm.caching.caching import DualCache
|
|
14
14
|
from litellm.integrations.custom_logger import CustomLogger
|
|
15
15
|
from litellm.litellm_core_utils.prompt_templates.common_utils import extract_file_data
|
|
@@ -36,6 +36,7 @@ from litellm.types.llms.openai import (
|
|
|
36
36
|
OpenAIFilesPurpose,
|
|
37
37
|
)
|
|
38
38
|
from litellm.types.utils import (
|
|
39
|
+
CallTypesLiteral,
|
|
39
40
|
LiteLLMBatch,
|
|
40
41
|
LiteLLMFineTuningJob,
|
|
41
42
|
LLMResponseTypes,
|
|
@@ -152,7 +153,7 @@ class _PROXY_LiteLLMManagedFiles(CustomLogger, BaseFileEndpoints):
|
|
|
152
153
|
"status": file_object.status,
|
|
153
154
|
},
|
|
154
155
|
"update": {}, # don't do anything if it already exists
|
|
155
|
-
}
|
|
156
|
+
},
|
|
156
157
|
)
|
|
157
158
|
|
|
158
159
|
async def get_unified_file_id(
|
|
@@ -224,9 +225,10 @@ class _PROXY_LiteLLMManagedFiles(CustomLogger, BaseFileEndpoints):
|
|
|
224
225
|
where={"unified_object_id": unified_object_id}
|
|
225
226
|
)
|
|
226
227
|
)
|
|
228
|
+
|
|
227
229
|
if managed_object:
|
|
228
230
|
return managed_object.created_by == user_id
|
|
229
|
-
return
|
|
231
|
+
return True # don't raise error if managed object is not found
|
|
230
232
|
|
|
231
233
|
async def get_user_created_file_ids(
|
|
232
234
|
self, user_api_key_dict: UserAPIKeyAuth, model_object_ids: List[str]
|
|
@@ -271,27 +273,7 @@ class _PROXY_LiteLLMManagedFiles(CustomLogger, BaseFileEndpoints):
|
|
|
271
273
|
user_api_key_dict: UserAPIKeyAuth,
|
|
272
274
|
cache: DualCache,
|
|
273
275
|
data: Dict,
|
|
274
|
-
call_type:
|
|
275
|
-
"completion",
|
|
276
|
-
"text_completion",
|
|
277
|
-
"embeddings",
|
|
278
|
-
"image_generation",
|
|
279
|
-
"moderation",
|
|
280
|
-
"audio_transcription",
|
|
281
|
-
"pass_through_endpoint",
|
|
282
|
-
"rerank",
|
|
283
|
-
"acreate_batch",
|
|
284
|
-
"aretrieve_batch",
|
|
285
|
-
"acreate_file",
|
|
286
|
-
"afile_list",
|
|
287
|
-
"afile_delete",
|
|
288
|
-
"afile_content",
|
|
289
|
-
"acreate_fine_tuning_job",
|
|
290
|
-
"aretrieve_fine_tuning_job",
|
|
291
|
-
"alist_fine_tuning_jobs",
|
|
292
|
-
"acancel_fine_tuning_job",
|
|
293
|
-
"mcp_call",
|
|
294
|
-
],
|
|
276
|
+
call_type: CallTypesLiteral,
|
|
295
277
|
) -> Union[Exception, str, Dict, None]:
|
|
296
278
|
"""
|
|
297
279
|
- Detect litellm_proxy/ file_id
|
|
@@ -22,9 +22,21 @@ def add_team_member_key_duration(
|
|
|
22
22
|
return data
|
|
23
23
|
|
|
24
24
|
|
|
25
|
+
def add_team_organization_id(
|
|
26
|
+
team_table: Optional[LiteLLM_TeamTable],
|
|
27
|
+
data: GenerateKeyRequest,
|
|
28
|
+
) -> GenerateKeyRequest:
|
|
29
|
+
if team_table is None:
|
|
30
|
+
return data
|
|
31
|
+
setattr(data, "organization_id", team_table.organization_id)
|
|
32
|
+
return data
|
|
33
|
+
|
|
34
|
+
|
|
25
35
|
def apply_enterprise_key_management_params(
|
|
26
36
|
data: GenerateKeyRequest,
|
|
27
37
|
team_table: Optional[LiteLLM_TeamTable],
|
|
28
38
|
) -> GenerateKeyRequest:
|
|
39
|
+
|
|
29
40
|
data = add_team_member_key_duration(team_table, data)
|
|
41
|
+
data = add_team_organization_id(team_table, data)
|
|
30
42
|
return data
|
|
@@ -9,14 +9,19 @@ All /vector_store management endpoints
|
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
import copy
|
|
12
|
+
import json
|
|
12
13
|
from typing import List, Optional
|
|
13
14
|
|
|
14
|
-
from fastapi import APIRouter, Depends, HTTPException
|
|
15
|
+
from fastapi import APIRouter, Depends, HTTPException
|
|
15
16
|
|
|
16
17
|
import litellm
|
|
17
18
|
from litellm._logging import verbose_proxy_logger
|
|
18
19
|
from litellm.litellm_core_utils.safe_json_dumps import safe_dumps
|
|
19
|
-
from litellm.proxy._types import
|
|
20
|
+
from litellm.proxy._types import (
|
|
21
|
+
LiteLLM_ManagedVectorStoresTable,
|
|
22
|
+
ResponseLiteLLM_ManagedVectorStore,
|
|
23
|
+
UserAPIKeyAuth,
|
|
24
|
+
)
|
|
20
25
|
from litellm.proxy.auth.user_api_key_auth import user_api_key_auth
|
|
21
26
|
from litellm.types.vector_stores import (
|
|
22
27
|
LiteLLM_ManagedVectorStore,
|
|
@@ -29,6 +34,7 @@ from litellm.vector_stores.vector_store_registry import VectorStoreRegistry
|
|
|
29
34
|
|
|
30
35
|
router = APIRouter()
|
|
31
36
|
|
|
37
|
+
|
|
32
38
|
########################################################
|
|
33
39
|
# Management Endpoints
|
|
34
40
|
########################################################
|
|
@@ -79,7 +85,9 @@ async def new_vector_store(
|
|
|
79
85
|
litellm_params_json: Optional[str] = None
|
|
80
86
|
_input_litellm_params: dict = vector_store.get("litellm_params", {}) or {}
|
|
81
87
|
if _input_litellm_params is not None:
|
|
82
|
-
litellm_params_dict = GenericLiteLLMParams(
|
|
88
|
+
litellm_params_dict = GenericLiteLLMParams(
|
|
89
|
+
**_input_litellm_params
|
|
90
|
+
).model_dump(exclude_none=True)
|
|
83
91
|
litellm_params_json = safe_dumps(litellm_params_dict)
|
|
84
92
|
del vector_store["litellm_params"]
|
|
85
93
|
|
|
@@ -227,6 +235,7 @@ async def delete_vector_store(
|
|
|
227
235
|
"/vector_store/info",
|
|
228
236
|
tags=["vector store management"],
|
|
229
237
|
dependencies=[Depends(user_api_key_auth)],
|
|
238
|
+
response_model=ResponseLiteLLM_ManagedVectorStore,
|
|
230
239
|
)
|
|
231
240
|
async def get_vector_store_info(
|
|
232
241
|
data: VectorStoreInfoRequest,
|
|
@@ -239,8 +248,39 @@ async def get_vector_store_info(
|
|
|
239
248
|
raise HTTPException(status_code=500, detail="Database not connected")
|
|
240
249
|
|
|
241
250
|
try:
|
|
242
|
-
|
|
243
|
-
|
|
251
|
+
if litellm.vector_store_registry is not None:
|
|
252
|
+
vector_store = litellm.vector_store_registry.get_litellm_managed_vector_store_from_registry(
|
|
253
|
+
vector_store_id=data.vector_store_id
|
|
254
|
+
)
|
|
255
|
+
if vector_store is not None:
|
|
256
|
+
vector_store_metadata = vector_store.get("vector_store_metadata")
|
|
257
|
+
# Parse metadata if it's a JSON string
|
|
258
|
+
parsed_metadata: Optional[dict] = None
|
|
259
|
+
if isinstance(vector_store_metadata, str):
|
|
260
|
+
parsed_metadata = json.loads(vector_store_metadata)
|
|
261
|
+
elif isinstance(vector_store_metadata, dict):
|
|
262
|
+
parsed_metadata = vector_store_metadata
|
|
263
|
+
|
|
264
|
+
vector_store_pydantic_obj = LiteLLM_ManagedVectorStoresTable(
|
|
265
|
+
vector_store_id=vector_store.get("vector_store_id") or "",
|
|
266
|
+
custom_llm_provider=vector_store.get("custom_llm_provider") or "",
|
|
267
|
+
vector_store_name=vector_store.get("vector_store_name") or None,
|
|
268
|
+
vector_store_description=vector_store.get(
|
|
269
|
+
"vector_store_description"
|
|
270
|
+
)
|
|
271
|
+
or None,
|
|
272
|
+
vector_store_metadata=parsed_metadata,
|
|
273
|
+
created_at=vector_store.get("created_at") or None,
|
|
274
|
+
updated_at=vector_store.get("updated_at") or None,
|
|
275
|
+
litellm_credential_name=vector_store.get("litellm_credential_name"),
|
|
276
|
+
litellm_params=vector_store.get("litellm_params") or None,
|
|
277
|
+
)
|
|
278
|
+
return {"vector_store": vector_store_pydantic_obj}
|
|
279
|
+
|
|
280
|
+
vector_store = (
|
|
281
|
+
await prisma_client.db.litellm_managedvectorstorestable.find_unique(
|
|
282
|
+
where={"vector_store_id": data.vector_store_id}
|
|
283
|
+
)
|
|
244
284
|
)
|
|
245
285
|
if vector_store is None:
|
|
246
286
|
raise HTTPException(
|
|
@@ -248,7 +288,7 @@ async def get_vector_store_info(
|
|
|
248
288
|
detail=f"Vector store with ID {data.vector_store_id} not found",
|
|
249
289
|
)
|
|
250
290
|
|
|
251
|
-
vector_store_dict = vector_store.model_dump()
|
|
291
|
+
vector_store_dict = vector_store.model_dump() # type: ignore[attr-defined]
|
|
252
292
|
return {"vector_store": vector_store_dict}
|
|
253
293
|
except Exception as e:
|
|
254
294
|
verbose_proxy_logger.exception(f"Error getting vector store info: {str(e)}")
|
|
@@ -274,7 +314,9 @@ async def update_vector_store(
|
|
|
274
314
|
update_data = data.model_dump(exclude_unset=True)
|
|
275
315
|
vector_store_id = update_data.pop("vector_store_id")
|
|
276
316
|
if update_data.get("vector_store_metadata") is not None:
|
|
277
|
-
update_data["vector_store_metadata"] = safe_dumps(
|
|
317
|
+
update_data["vector_store_metadata"] = safe_dumps(
|
|
318
|
+
update_data["vector_store_metadata"]
|
|
319
|
+
)
|
|
278
320
|
|
|
279
321
|
updated = await prisma_client.db.litellm_managedvectorstorestable.update(
|
|
280
322
|
where={"vector_store_id": vector_store_id},
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import enum
|
|
2
|
-
from typing import Dict, List
|
|
2
|
+
from typing import Dict, List, Optional
|
|
3
3
|
|
|
4
4
|
from pydantic import BaseModel, Field
|
|
5
5
|
|
|
6
6
|
from litellm.proxy._types import WebhookEvent
|
|
7
7
|
|
|
8
|
+
|
|
8
9
|
class EmailParams(BaseModel):
|
|
9
10
|
logo_url: str
|
|
10
11
|
support_contact: str
|
|
@@ -22,9 +23,19 @@ class SendKeyCreatedEmailEvent(WebhookEvent):
|
|
|
22
23
|
"""
|
|
23
24
|
|
|
24
25
|
|
|
26
|
+
class SendKeyRotatedEmailEvent(WebhookEvent):
|
|
27
|
+
virtual_key: str
|
|
28
|
+
key_alias: Optional[str] = None
|
|
29
|
+
"""
|
|
30
|
+
The virtual key that was rotated
|
|
31
|
+
this will be sk-123xxx, since we will be emailing this to the user to start using the new key
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
|
|
25
35
|
class EmailEvent(str, enum.Enum):
|
|
26
36
|
virtual_key_created = "Virtual Key Created"
|
|
27
37
|
new_user_invitation = "New User Invitation"
|
|
38
|
+
virtual_key_rotated = "Virtual Key Rotated"
|
|
28
39
|
|
|
29
40
|
class EmailEventSettings(BaseModel):
|
|
30
41
|
event: EmailEvent
|
|
@@ -37,8 +48,9 @@ class DefaultEmailSettings(BaseModel):
|
|
|
37
48
|
"""Default settings for email events"""
|
|
38
49
|
settings: Dict[EmailEvent, bool] = Field(
|
|
39
50
|
default_factory=lambda: {
|
|
40
|
-
EmailEvent.virtual_key_created:
|
|
51
|
+
EmailEvent.virtual_key_created: True, # On by default
|
|
41
52
|
EmailEvent.new_user_invitation: True, # On by default
|
|
53
|
+
EmailEvent.virtual_key_rotated: True, # On by default
|
|
42
54
|
}
|
|
43
55
|
)
|
|
44
56
|
def to_dict(self) -> Dict[str, bool]:
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
litellm_enterprise/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
litellm_enterprise/enterprise_callbacks/.pytest_cache/.gitignore,sha256=Ptcxtl0GFQwTji2tsL4Gl1UIiKa0frjEXsya26i46b0,37
|
|
3
|
+
litellm_enterprise/enterprise_callbacks/.pytest_cache/CACHEDIR.TAG,sha256=N9yI75oKvt2-gQU6bdj9-xOvthMEXqHrSlyBWnSjveQ,191
|
|
4
|
+
litellm_enterprise/enterprise_callbacks/.pytest_cache/README.md,sha256=c_1vzN2ALEGaay2YPWwxc7fal1WKxLWJ7ewt_kQ9ua0,302
|
|
5
|
+
litellm_enterprise/enterprise_callbacks/.pytest_cache/v/cache/nodeids,sha256=T1PNoYwrqgwDVLtfmj7L5e0Sq02OEbqHPC8RFhICuUU,2
|
|
6
|
+
litellm_enterprise/enterprise_callbacks/.pytest_cache/v/cache/stepwise,sha256=T1PNoYwrqgwDVLtfmj7L5e0Sq02OEbqHPC8RFhICuUU,2
|
|
2
7
|
litellm_enterprise/enterprise_callbacks/callback_controls.py,sha256=BhUOHoqR5u8ANaSweKnzgw96Zqu7Eh4mXXUfYQH9Xe4,4756
|
|
3
8
|
litellm_enterprise/enterprise_callbacks/example_logging_api.py,sha256=06CM6wa5CC7Mal3Gm-P6m6tJuikbcg5BJ9-kzfpl_Y4,776
|
|
4
|
-
litellm_enterprise/enterprise_callbacks/generic_api_callback.py,sha256=
|
|
5
|
-
litellm_enterprise/enterprise_callbacks/llama_guard.py,sha256=
|
|
6
|
-
litellm_enterprise/enterprise_callbacks/llm_guard.py,sha256=
|
|
7
|
-
litellm_enterprise/enterprise_callbacks/pagerduty/pagerduty.py,sha256=
|
|
9
|
+
litellm_enterprise/enterprise_callbacks/generic_api_callback.py,sha256=8x_ghfAvG72A4wrzeWcz5PVo6DhMPQjKUmrwsb-tuig,9180
|
|
10
|
+
litellm_enterprise/enterprise_callbacks/llama_guard.py,sha256=9GSYTujO2bI6jWmtpTYz1UcOpJfBNSuAVWrl4rJIXO0,4839
|
|
11
|
+
litellm_enterprise/enterprise_callbacks/llm_guard.py,sha256=AXqlcct74S7N6DHAxYbh6icrsQ-7umIyOkOuZAmXD-w,6453
|
|
12
|
+
litellm_enterprise/enterprise_callbacks/pagerduty/pagerduty.py,sha256=40UI8RjRZ-lfoCyCITipHHK6CmYR5iOI27F48cvc-xk,12400
|
|
8
13
|
litellm_enterprise/enterprise_callbacks/secret_detection.py,sha256=D5h5dS4T5PM-zWqUy-svTfZrxDGbJQbFFJExofXX4_o,19640
|
|
9
14
|
litellm_enterprise/enterprise_callbacks/secrets_plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
15
|
litellm_enterprise/enterprise_callbacks/secrets_plugins/adafruit.py,sha256=djYtVMzXF21ay1w6cg-oT6D0f3b-Aa_5Bh29OiOD_O4,596
|
|
@@ -100,33 +105,31 @@ litellm_enterprise/enterprise_callbacks/secrets_plugins/typeform_api_token.py,sh
|
|
|
100
105
|
litellm_enterprise/enterprise_callbacks/secrets_plugins/vault.py,sha256=fqtHTQTC6QaNMIZpuvntBnCSAgAhY2Ka-XOz4ZLafGk,653
|
|
101
106
|
litellm_enterprise/enterprise_callbacks/secrets_plugins/yandex.py,sha256=BVtFVzCTtpAkRJVudeZIEBBz1W8wueDzpu6TBvxngxo,1183
|
|
102
107
|
litellm_enterprise/enterprise_callbacks/secrets_plugins/zendesk_secret_key.py,sha256=3E21lWz12WUAmdnKDZH8znfTp6hRJbE3yImtfEP52qE,613
|
|
103
|
-
litellm_enterprise/enterprise_callbacks/send_emails/base_email.py,sha256=
|
|
108
|
+
litellm_enterprise/enterprise_callbacks/send_emails/base_email.py,sha256=w4omD5Z7gMZABxn7DmAlOiCX6f7VwJ1KMKq_NXpdkLc,15523
|
|
104
109
|
litellm_enterprise/enterprise_callbacks/send_emails/endpoints.py,sha256=hOEpM_q8MJAXlKMOtC9KbgvDVr_YFtF3reu9bjXkpsI,7017
|
|
105
110
|
litellm_enterprise/enterprise_callbacks/send_emails/resend_email.py,sha256=lLG9W2hEOjn7lvMDKoaZGVCzr72HfreJuScMNOkE7FQ,1426
|
|
106
111
|
litellm_enterprise/enterprise_callbacks/send_emails/smtp_email.py,sha256=_K3vGhyALVJWIzIk2oiHQbQPlYARdpPe-GA9hdl0vTg,1130
|
|
107
|
-
litellm_enterprise/integrations/custom_guardrail.py,sha256=
|
|
108
|
-
litellm_enterprise/integrations/prometheus.py,sha256=1WLELwsCCrmQWqKucbNFmmCUpoT4NJCZ8eoG9HHbG6o,91704
|
|
112
|
+
litellm_enterprise/integrations/custom_guardrail.py,sha256=ZLVpqUZq9bR0vEFqVrlTJk0bYCZuFsXlw9XsdyK9t2E,1555
|
|
109
113
|
litellm_enterprise/litellm_core_utils/litellm_logging.py,sha256=BKkQLPqebFbN-KeCbipGIPgdxHEfQkczImdhhzxKoFg,868
|
|
110
114
|
litellm_enterprise/proxy/audit_logging_endpoints.py,sha256=BnHczmi4bnW1GpMNsq4CvnbwL3rgQ-pnrtFd5WBbbHY,5304
|
|
111
115
|
litellm_enterprise/proxy/auth/__init__.py,sha256=wTXtbDcLrD_qecxJfEJtraeCvGfldDgLz8qdVggLoSI,301
|
|
112
116
|
litellm_enterprise/proxy/auth/custom_sso_handler.py,sha256=ITML9dRKL-LuJhU3WKKVPDp0ECfYxvxTvuX8GpSM0gE,3439
|
|
113
117
|
litellm_enterprise/proxy/auth/route_checks.py,sha256=FbXwbrOkFr1dODH6XxoIpLG1nKowC7kyNaRR0WR6ujU,2490
|
|
114
118
|
litellm_enterprise/proxy/auth/user_api_key_auth.py,sha256=7t5Q-JoKFyoymylaOT8KWAAOFVz0JOTl7PPOmTkpj5c,1144
|
|
115
|
-
litellm_enterprise/proxy/common_utils/check_batch_cost.py,sha256=
|
|
119
|
+
litellm_enterprise/proxy/common_utils/check_batch_cost.py,sha256=V0CCHtN-JV-_d-ydXV-cVs3zCImt1699JnICGF3oPOk,7360
|
|
116
120
|
litellm_enterprise/proxy/enterprise_routes.py,sha256=TkFeQa6mtVIvEhTP7X5dcSDKTOks0hG_dWrL1_oCU4w,1122
|
|
117
|
-
litellm_enterprise/proxy/
|
|
118
|
-
litellm_enterprise/proxy/hooks/managed_files.py,sha256=8WtFarjtVzREgMCXmgmcm720Bx_F3UdQg8Ry8zbVznM,32690
|
|
121
|
+
litellm_enterprise/proxy/hooks/managed_files.py,sha256=E5yY9qza6HzcOtAI_9zgHLV_F-dz8VpOM3KoEhGKp2E,32195
|
|
119
122
|
litellm_enterprise/proxy/management_endpoints/__init__.py,sha256=zfaqryxzmFu6se-w4yR2nlHKxDOOtHAWEehA2xFbFNg,270
|
|
120
|
-
litellm_enterprise/proxy/management_endpoints/internal_user_endpoints.py,sha256=
|
|
121
|
-
litellm_enterprise/proxy/management_endpoints/key_management_endpoints.py,sha256
|
|
123
|
+
litellm_enterprise/proxy/management_endpoints/internal_user_endpoints.py,sha256=GEoOVujrtKXDHfko2KQaLn-ms64zkutFE9PP5IhBBLM,2175
|
|
124
|
+
litellm_enterprise/proxy/management_endpoints/key_management_endpoints.py,sha256=-IXRzVrNQ3_krL-gxngelYQftwyPlB_HmgI3RN-HdvM,1147
|
|
122
125
|
litellm_enterprise/proxy/proxy_server.py,sha256=fzOeTyiyevLWi2767-2W1Co7reR-0wnoUIhOgVlJFQc,1183
|
|
123
126
|
litellm_enterprise/proxy/readme.md,sha256=ZcigMJYSHWs4SWnYriWjrSVDJKsu44c2HsbYbma0EHU,397
|
|
124
127
|
litellm_enterprise/proxy/utils.py,sha256=y4ADfhlEG_mH0x5rfIg7D9FjS586lVgQ9DL0tTdgrMQ,962
|
|
125
|
-
litellm_enterprise/proxy/vector_stores/endpoints.py,sha256=
|
|
126
|
-
litellm_enterprise/types/enterprise_callbacks/send_emails.py,sha256=
|
|
128
|
+
litellm_enterprise/proxy/vector_stores/endpoints.py,sha256=AkP503_JQY0DCFk_kPVYh7xSqSBabVBIphjRiAA0GvA,12445
|
|
129
|
+
litellm_enterprise/types/enterprise_callbacks/send_emails.py,sha256=XLhpdGvBFxPkV7hcgQ1gELVF0vTs5d2LLOoXPzjr4K4,1929
|
|
127
130
|
litellm_enterprise/types/proxy/audit_logging_endpoints.py,sha256=oSJVAuRD9r6ZjRCqNBFM-J5HSgOltsXts400b2aynRE,894
|
|
128
131
|
litellm_enterprise/types/proxy/proxy_server.py,sha256=kdhtxsU2uok6-XO_ebugCv7PzYYmGgv4vh-XemHJnpM,146
|
|
129
|
-
litellm_enterprise-0.1.
|
|
130
|
-
litellm_enterprise-0.1.
|
|
131
|
-
litellm_enterprise-0.1.
|
|
132
|
-
litellm_enterprise-0.1.
|
|
132
|
+
litellm_enterprise-0.1.21.dist-info/LICENSE.md,sha256=nq3D9ZqOvRDT6hLkypQFTc3XsE15kbkg5rkkLJVSqKY,2251
|
|
133
|
+
litellm_enterprise-0.1.21.dist-info/METADATA,sha256=frIz5pheYia1kG7hBurrsgEvN--feEe46C3V4o0_ru8,1314
|
|
134
|
+
litellm_enterprise-0.1.21.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
135
|
+
litellm_enterprise-0.1.21.dist-info/RECORD,,
|