Coverage for .venv/lib/python3.13/site-packages/litellm/proxy/vector_store_files_endpoints/endpoints.py: 56%
308 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 12:01 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 12:01 +0000
1from typing import TYPE_CHECKING, Final, Optional
3from fastapi import APIRouter, Depends, Request, Response
4from fastapi.responses import ORJSONResponse
6import litellm
7from litellm.proxy._types import UserAPIKeyAuth
8from litellm.proxy.auth.user_api_key_auth import user_api_key_auth
9from litellm.proxy.common_request_processing import ProxyBaseLLMRequestProcessing
10from litellm.proxy.common_utils.openai_endpoint_utils import (
11 get_custom_llm_provider_from_request_body,
12 get_custom_llm_provider_from_request_headers,
13 get_custom_llm_provider_from_request_query,
14)
15from litellm.proxy.openai_files_endpoints.common_utils import (
16 authorize_model_for_key,
17 get_credentials_for_model,
18 handle_model_based_routing,
19 prepare_data_with_credentials,
20)
21from litellm.proxy.rag_endpoints.upload_security import safe_download_headers
22from litellm.proxy.vector_store_endpoints.utils import (
23 assert_user_can_access_vector_store_id,
24 is_allowed_to_call_vector_store_files_endpoint,
25)
26from litellm.types.utils import LlmProviders
27from litellm.types.vector_stores import LiteLLM_ManagedVectorStore
29if TYPE_CHECKING: 29 ↛ 30line 29 didn't jump to line 30 because the condition on line 29 was never true
30 from litellm.router import Router
32router: Final = APIRouter()
35async def _update_request_data_with_managed_file_id(
36 data: dict,
37 file_id: str,
38 request: Request,
39 user_api_key_dict: UserAPIKeyAuth,
40 managed_files_obj: object | None,
41 llm_router: Optional["Router"] = None,
42) -> tuple[dict, str | None]:
43 """
44 Update request data with model routing information from managed file ID.
46 This function handles two types of file IDs:
47 1. Simple encoded file IDs (format: litellm:{file_id};model,{model})
48 2. Unified managed file IDs (format: litellm_proxy:{mime};unified_id,{uuid};...;llm_output_file_id,{file_id};...)
50 For unified managed file IDs, it:
51 - Decodes the unified ID to extract the actual provider file ID (llm_output_file_id)
52 - Extracts the model routing information (target_model_names)
53 - Updates data with credentials for the correct deployment
55 Args:
56 data: Request data to update
57 file_id: File ID (can be managed/encoded or regular)
58 request: FastAPI request object
59 llm_router: LiteLLM router for credential lookup (required for managed files)
61 Returns:
62 Tuple of (updated request data, original_managed_file_id)
63 - original_managed_file_id is the original file_id if it was managed/encoded, None otherwise
64 """
65 import re
67 from litellm import verbose_logger
68 from litellm.llms.base_llm.managed_resources.utils import (
69 is_base64_encoded_unified_id,
70 parse_unified_id,
71 )
72 from litellm.proxy.openai_files_endpoints.common_utils import (
73 validate_managed_id_requirement,
74 )
76 await validate_managed_id_requirement(
77 resource_id=file_id,
78 resource_kind="file",
79 user_api_key_dict=user_api_key_dict,
80 managed_files_obj=managed_files_obj,
81 )
83 # First, check if this is a unified managed file ID (base64 encoded)
84 decoded_id: Final = is_base64_encoded_unified_id(file_id)
86 if decoded_id: 86 ↛ 88line 86 didn't jump to line 88 because the condition on line 86 was never true
87 # This is a unified managed file ID
88 verbose_logger.debug("Processing unified managed file ID: %s", file_id)
90 # Parse the unified ID to extract components
91 parsed_id: Final = parse_unified_id(file_id)
93 if parsed_id:
94 target_model_names: Final = parsed_id.get("target_model_names", [])
96 # Extract the actual provider file ID from llm_output_file_id field
97 # Format: litellm_proxy:...;llm_output_file_id,{actual_file_id};...
98 llm_output_file_id = None
99 try:
100 match: Final = re.search(r"llm_output_file_id,([^;]+)", decoded_id)
101 if match:
102 llm_output_file_id = match.group(1).strip()
103 except Exception:
104 pass
106 verbose_logger.debug(
107 "Decoded unified file ID - target_model_names: %s, llm_output_file_id: %s",
108 target_model_names,
109 llm_output_file_id,
110 )
112 # Set the model for routing
113 if target_model_names and len(target_model_names) > 0:
114 routing_model: Final = target_model_names[0]
115 data["model"] = routing_model
117 # Get credentials for the model
118 if llm_router:
119 credentials = llm_router.get_deployment_credentials_with_provider(model_id=routing_model)
120 if credentials:
121 prepare_data_with_credentials(
122 data=data,
123 credentials=credentials,
124 file_id=llm_output_file_id, # Use the actual provider file ID
125 )
126 verbose_logger.info(
127 "Routing vector store file operation to model: %s, file_id: %s -> %s",
128 routing_model,
129 file_id,
130 llm_output_file_id,
131 )
132 return data, file_id # Return original managed file ID
134 # If we extracted the provider file ID but no routing, still use it
135 if llm_output_file_id:
136 data["file_id"] = llm_output_file_id
137 verbose_logger.debug("Replaced unified file ID with provider file ID: %s", llm_output_file_id)
138 return data, file_id # Return original managed file ID
140 return data, file_id if decoded_id else None
142 # Fall back to simple encoded file ID handling (format: litellm:{file_id};model,{model})
143 (
144 should_route,
145 model_used,
146 original_file_id,
147 credentials,
148 ) = await handle_model_based_routing(
149 file_id=file_id,
150 request=request,
151 llm_router=llm_router,
152 data=data,
153 user_api_key_dict=user_api_key_dict,
154 check_file_id_encoding=True,
155 )
157 if should_route: 157 ↛ 159line 157 didn't jump to line 159 because the condition on line 157 was never true
158 # Use model-based routing with credentials from config
159 prepare_data_with_credentials(
160 data=data,
161 credentials=credentials,
162 file_id=original_file_id, # Use decoded file ID if from encoded ID
163 )
165 verbose_logger.debug(
166 f"Routing vector store file operation using model: {model_used}"
167 + (f", file_id: {file_id} -> {original_file_id}" if original_file_id else "")
168 )
169 return data, file_id # Return original file ID for response replacement
171 return data, None
174def _replace_file_id_in_response(response, original_file_id: str):
175 """
176 Replace the provider file ID in the response with the original managed file ID.
178 This ensures that when a user sends a managed file ID, they get back the same
179 managed file ID in the response, not the decoded provider file ID.
181 Args:
182 response: The response object from the provider
183 original_file_id: The original managed file ID to restore
185 Returns:
186 Modified response with original file ID
187 """
188 if response is None:
189 return response
191 # Handle different response types
192 if isinstance(response, dict):
193 # For dict responses (e.g., VectorStoreFileDeleteResponse)
194 if "id" in response:
195 response["id"] = original_file_id
196 if "file_id" in response:
197 response["file_id"] = original_file_id
198 elif hasattr(response, "id"):
199 # For object responses (e.g., VectorStoreFileObject)
200 response.id = original_file_id
201 elif hasattr(response, "file_id"):
202 response.file_id = original_file_id
204 return response
207async def _authorize_model_routing_hint(
208 *,
209 model: str,
210 llm_router: Optional["Router"],
211 user_api_key_dict: UserAPIKeyAuth | None,
212) -> None:
213 if user_api_key_dict is None:
214 return
215 await authorize_model_for_key(model_id=model, llm_router=llm_router, user_api_key_dict=user_api_key_dict)
218async def _update_request_data_with_model_routing_hint(
219 data: dict,
220 request: Request,
221 llm_router: Optional["Router"] = None,
222 user_api_key_dict: UserAPIKeyAuth | None = None,
223) -> dict:
224 if data.get("api_key") is not None or data.get("api_base") is not None: 224 ↛ 225line 224 didn't jump to line 225 because the condition on line 224 was never true
225 return data
227 user_controlled_model_hint: Final = request.query_params.get("model") or request.headers.get("x-litellm-model")
228 model_hint: Final = data.get("model") or user_controlled_model_hint
229 should_authorize_model_hint: Final = isinstance(model_hint, str) and model_hint == user_controlled_model_hint
231 caller_team_id: Final = getattr(user_api_key_dict, "team_id", None) if user_api_key_dict else None
233 should_route = False
234 credentials = None
235 if isinstance(model_hint, str) and "*" in model_hint: 235 ↛ 236line 235 didn't jump to line 236 because the condition on line 235 was never true
236 if llm_router is not None:
237 if should_authorize_model_hint:
238 await _authorize_model_routing_hint(
239 model=model_hint,
240 llm_router=llm_router,
241 user_api_key_dict=user_api_key_dict,
242 )
243 credentials = llm_router.get_deployment_credentials_with_provider(
244 model_id=model_hint, team_id=caller_team_id
245 )
246 should_route = credentials is not None
247 elif isinstance(model_hint, str): 247 ↛ 248line 247 didn't jump to line 248 because the condition on line 247 was never true
248 if should_authorize_model_hint:
249 await _authorize_model_routing_hint(
250 model=model_hint,
251 llm_router=llm_router,
252 user_api_key_dict=user_api_key_dict,
253 )
254 credentials = get_credentials_for_model(llm_router=llm_router, model_id=model_hint)
255 should_route = True
257 if should_route and credentials is not None: 257 ↛ 258line 257 didn't jump to line 258 because the condition on line 257 was never true
258 prepare_data_with_credentials(
259 data=data,
260 credentials=credentials,
261 )
262 return data
264 if llm_router is None or user_api_key_dict is None: 264 ↛ 265line 264 didn't jump to line 265 because the condition on line 264 was never true
265 return data
267 team_models: Final = getattr(user_api_key_dict, "team_models", None) or []
268 if not isinstance(team_models, list): 268 ↛ 269line 268 didn't jump to line 269 because the condition on line 268 was never true
269 return data
271 model_names_to_check: Final = []
272 for model_name in team_models: 272 ↛ 273line 272 didn't jump to line 273 because the loop on line 272 never started
273 if not isinstance(model_name, str) or model_name in {
274 "all-team-models",
275 "all-proxy-models",
276 "no-default-models",
277 }:
278 continue
279 model_names_to_check.append(model_name)
281 openai_credentials = None
282 for model_name in model_names_to_check: 282 ↛ 283line 282 didn't jump to line 283 because the loop on line 282 never started
283 credentials = llm_router.get_deployment_credentials_with_provider(model_id=model_name, team_id=caller_team_id)
284 if credentials is None:
285 continue
287 provider = credentials.get("custom_llm_provider")
288 model = credentials.get("model")
289 if provider is None and isinstance(model, str) and "/" in model:
290 provider = model.split("/", 1)[0]
291 if provider != LlmProviders.OPENAI.value:
292 continue
294 await _authorize_model_routing_hint(
295 model=model_name,
296 llm_router=llm_router,
297 user_api_key_dict=user_api_key_dict,
298 )
299 if openai_credentials is not None:
300 return data
301 openai_credentials = credentials
303 if openai_credentials is not None: 303 ↛ 304line 303 didn't jump to line 304 because the condition on line 303 was never true
304 prepare_data_with_credentials(data=data, credentials=openai_credentials)
305 elif len(model_names_to_check) == 1: 305 ↛ 306line 305 didn't jump to line 306 because the condition on line 305 was never true
306 await _authorize_model_routing_hint(
307 model=model_names_to_check[0],
308 llm_router=llm_router,
309 user_api_key_dict=user_api_key_dict,
310 )
311 data["model"] = model_names_to_check[0]
313 return data
316def _update_request_data_with_litellm_managed_vector_store_registry(
317 data: dict,
318 vector_store_id: str,
319 llm_router: Optional["Router"] = None,
320 managed_vector_store: LiteLLM_ManagedVectorStore | None = None,
321 should_lookup_registry: bool = True,
322) -> dict:
323 """
324 Update request data with model routing information from managed vector store.
326 This function handles two types of vector stores:
327 1. Legacy vector stores from registry (non-managed)
328 2. Managed vector stores with unified IDs (requires decoding)
330 For managed vector stores, this function:
331 - Decodes the unified vector store ID
332 - Extracts the model_id and provider resource ID
333 - Sets data["model"] so the router can use the correct deployment credentials
334 - Replaces the unified ID with the provider-specific ID
336 Args:
337 data: Request data to update
338 vector_store_id: Vector store ID (can be unified or legacy)
339 llm_router: LiteLLM router for credential lookup (required for managed vector stores)
341 Returns:
342 Updated request data with model routing information
343 """
344 from litellm import verbose_logger
345 from litellm.llms.base_llm.managed_resources.utils import (
346 is_base64_encoded_unified_id,
347 parse_unified_id,
348 )
350 # Check if this is a managed vector store ID (base64 encoded unified ID)
351 decoded_id: Final = is_base64_encoded_unified_id(vector_store_id)
353 if decoded_id: 353 ↛ 355line 353 didn't jump to line 355 because the condition on line 353 was never true
354 # This is a managed vector store - decode and extract routing information
355 verbose_logger.debug("Processing managed vector store ID: %s", vector_store_id)
357 parsed_id: Final = parse_unified_id(vector_store_id)
359 if parsed_id:
360 model_id: Final = parsed_id.get("model_id")
361 provider_resource_id: Final = parsed_id.get("provider_resource_id")
362 target_model_names: Final = parsed_id.get("target_model_names", [])
364 verbose_logger.debug(
365 "Decoded vector store - model_id: %s, provider_resource_id: %s, target_model_names: %s",
366 model_id,
367 provider_resource_id,
368 target_model_names,
369 )
371 # Set the model for routing - this tells the router which deployment to use
372 # The router will automatically get the credentials from the deployment
373 routing_model = None
374 if model_id:
375 routing_model = model_id
376 elif target_model_names and len(target_model_names) > 0:
377 routing_model = target_model_names[0]
379 if routing_model:
380 data["model"] = routing_model
381 verbose_logger.info("Routing vector store files operation to model: %s", routing_model)
383 # Replace unified vector store ID with provider resource ID
384 if provider_resource_id:
385 data["vector_store_id"] = provider_resource_id
386 verbose_logger.debug(
387 "Replaced unified vector store ID with provider resource ID: %s", provider_resource_id
388 )
390 return data
392 # Legacy path: Check vector store registry for non-managed vector stores.
393 vector_store_to_run = managed_vector_store
394 if vector_store_to_run is None and should_lookup_registry and litellm.vector_store_registry is not None: 394 ↛ 395line 394 didn't jump to line 395 because the condition on line 394 was never true
395 vector_store_to_run = litellm.vector_store_registry.get_litellm_managed_vector_store_from_registry(
396 vector_store_id=vector_store_id
397 )
399 if vector_store_to_run is not None:
400 if "custom_llm_provider" in vector_store_to_run: 400 ↛ 402line 400 didn't jump to line 402 because the condition on line 400 was always true
401 data["custom_llm_provider"] = vector_store_to_run.get("custom_llm_provider")
402 if "litellm_credential_name" in vector_store_to_run: 402 ↛ 404line 402 didn't jump to line 404 because the condition on line 402 was always true
403 data["litellm_credential_name"] = vector_store_to_run.get("litellm_credential_name")
404 if "litellm_params" in vector_store_to_run: 404 ↛ 408line 404 didn't jump to line 408 because the condition on line 404 was always true
405 litellm_params: Final = vector_store_to_run.get("litellm_params", {}) or {}
406 data.update(litellm_params)
408 return data
411async def _resolve_provider(
412 *,
413 data: dict,
414 request: Request,
415) -> LlmProviders | None:
416 provider = (
417 data.get("custom_llm_provider")
418 or get_custom_llm_provider_from_request_headers(request=request)
419 or get_custom_llm_provider_from_request_query(request=request)
420 )
422 if provider is None and request.method in {"POST", "PUT", "PATCH"}:
423 provider = await get_custom_llm_provider_from_request_body(request=request)
425 if provider is None:
426 provider = "openai"
428 try:
429 return LlmProviders(provider)
430 except Exception:
431 return None
434def _maybe_check_permissions(
435 *,
436 provider: LlmProviders | None,
437 vector_store_id: str,
438 request: Request,
439 user_api_key_dict: UserAPIKeyAuth,
440) -> None:
441 if provider is None:
442 return
443 metadata: Final = user_api_key_dict.metadata or {}
444 team_metadata: Final = user_api_key_dict.team_metadata or {}
445 if not metadata.get("allowed_vector_store_indexes") and not team_metadata.get("allowed_vector_store_indexes"): 445 ↛ 447line 445 didn't jump to line 447 because the condition on line 445 was always true
446 return
447 is_allowed_to_call_vector_store_files_endpoint(
448 provider=provider,
449 vector_store_id=vector_store_id,
450 request=request,
451 user_api_key_dict=user_api_key_dict,
452 )
455@router.post(
456 "/v1/vector_stores/{vector_store_id}/files",
457 dependencies=[Depends(user_api_key_auth)],
458 response_class=ORJSONResponse,
459 tags=["vector_store_files"],
460)
461@router.post(
462 "/vector_stores/{vector_store_id}/files",
463 dependencies=[Depends(user_api_key_auth)],
464 response_class=ORJSONResponse,
465 tags=["vector_store_files"],
466)
467async def vector_store_file_create(
468 vector_store_id: str,
469 request: Request,
470 fastapi_response: Response,
471 user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
472):
473 from litellm.proxy.proxy_server import (
474 _read_request_body,
475 general_settings,
476 llm_router,
477 proxy_config,
478 proxy_logging_obj,
479 select_data_generator,
480 user_api_base,
481 user_max_tokens,
482 user_model,
483 user_request_timeout,
484 user_temperature,
485 version,
486 )
488 data = await _read_request_body(request=request)
489 data["vector_store_id"] = vector_store_id
490 managed_vector_store: Final = await assert_user_can_access_vector_store_id(
491 vector_store_id=vector_store_id,
492 user_api_key_dict=user_api_key_dict,
493 )
495 # Handle managed file IDs if present in request body
496 original_managed_file_id = None
497 if "file_id" in data: 497 ↛ 498line 497 didn't jump to line 498 because the condition on line 497 was never true
498 data, original_managed_file_id = await _update_request_data_with_managed_file_id(
499 data=data,
500 file_id=data["file_id"],
501 request=request,
502 user_api_key_dict=user_api_key_dict,
503 managed_files_obj=proxy_logging_obj.get_proxy_hook("managed_files"),
504 llm_router=llm_router,
505 )
507 # Then handle managed vector store IDs
508 data = _update_request_data_with_litellm_managed_vector_store_registry(
509 data=data,
510 vector_store_id=vector_store_id,
511 llm_router=llm_router,
512 managed_vector_store=managed_vector_store,
513 should_lookup_registry=False,
514 )
516 provider_enum: Final = await _resolve_provider(data=data, request=request)
518 _maybe_check_permissions(
519 provider=provider_enum,
520 vector_store_id=vector_store_id,
521 request=request,
522 user_api_key_dict=user_api_key_dict,
523 )
524 if provider_enum is not None and "custom_llm_provider" not in data:
525 data["custom_llm_provider"] = provider_enum.value
527 processor: Final = ProxyBaseLLMRequestProcessing(data=data)
528 try:
529 response: object = await processor.base_process_llm_request(
530 request=request,
531 fastapi_response=fastapi_response,
532 user_api_key_dict=user_api_key_dict,
533 route_type="avector_store_file_create",
534 proxy_logging_obj=proxy_logging_obj,
535 llm_router=llm_router,
536 general_settings=general_settings,
537 proxy_config=proxy_config,
538 select_data_generator=select_data_generator,
539 model=None,
540 user_model=user_model,
541 user_temperature=user_temperature,
542 user_request_timeout=user_request_timeout,
543 user_max_tokens=user_max_tokens,
544 user_api_base=user_api_base,
545 version=version,
546 )
548 # Replace provider file ID with original managed file ID in response
549 if original_managed_file_id:
550 response = _replace_file_id_in_response(response, original_managed_file_id)
552 return response
553 except Exception as e: # noqa: BLE001
554 raise await processor._handle_llm_api_exception(
555 e=e,
556 user_api_key_dict=user_api_key_dict,
557 proxy_logging_obj=proxy_logging_obj,
558 version=version,
559 )
562@router.get(
563 "/v1/vector_stores/{vector_store_id}/files",
564 dependencies=[Depends(user_api_key_auth)],
565 response_class=ORJSONResponse,
566 tags=["vector_store_files"],
567)
568@router.get(
569 "/vector_stores/{vector_store_id}/files",
570 dependencies=[Depends(user_api_key_auth)],
571 response_class=ORJSONResponse,
572 tags=["vector_store_files"],
573)
574async def vector_store_file_list(
575 vector_store_id: str,
576 request: Request,
577 fastapi_response: Response,
578 user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
579):
580 from litellm.proxy.proxy_server import (
581 general_settings,
582 llm_router,
583 proxy_config,
584 proxy_logging_obj,
585 select_data_generator,
586 user_api_base,
587 user_max_tokens,
588 user_model,
589 user_request_timeout,
590 user_temperature,
591 version,
592 )
594 query_params: Final = dict(request.query_params)
595 data: dict[str, str | None] = {"vector_store_id": vector_store_id}
596 data.update(query_params)
597 data["vector_store_id"] = vector_store_id
598 managed_vector_store: Final = await assert_user_can_access_vector_store_id(
599 vector_store_id=vector_store_id,
600 user_api_key_dict=user_api_key_dict,
601 )
603 data = _update_request_data_with_litellm_managed_vector_store_registry(
604 data=data,
605 vector_store_id=vector_store_id,
606 llm_router=llm_router,
607 managed_vector_store=managed_vector_store,
608 should_lookup_registry=False,
609 )
611 data = await _update_request_data_with_model_routing_hint(
612 data=data,
613 request=request,
614 llm_router=llm_router,
615 user_api_key_dict=user_api_key_dict,
616 )
618 provider_enum: Final = await _resolve_provider(data=data, request=request)
620 _maybe_check_permissions(
621 provider=provider_enum,
622 vector_store_id=vector_store_id,
623 request=request,
624 user_api_key_dict=user_api_key_dict,
625 )
626 if provider_enum is not None and "custom_llm_provider" not in data:
627 data["custom_llm_provider"] = provider_enum.value
629 processor: Final = ProxyBaseLLMRequestProcessing(data=data)
630 try:
631 return await processor.base_process_llm_request(
632 request=request,
633 fastapi_response=fastapi_response,
634 user_api_key_dict=user_api_key_dict,
635 route_type="avector_store_file_list",
636 proxy_logging_obj=proxy_logging_obj,
637 llm_router=llm_router,
638 general_settings=general_settings,
639 proxy_config=proxy_config,
640 select_data_generator=select_data_generator,
641 model=None,
642 user_model=user_model,
643 user_temperature=user_temperature,
644 user_request_timeout=user_request_timeout,
645 user_max_tokens=user_max_tokens,
646 user_api_base=user_api_base,
647 version=version,
648 )
649 except Exception as e: # noqa: BLE001
650 raise await processor._handle_llm_api_exception(
651 e=e,
652 user_api_key_dict=user_api_key_dict,
653 proxy_logging_obj=proxy_logging_obj,
654 version=version,
655 )
658@router.get(
659 "/v1/vector_stores/{vector_store_id}/files/{file_id}",
660 dependencies=[Depends(user_api_key_auth)],
661 response_class=ORJSONResponse,
662 tags=["vector_store_files"],
663)
664@router.get(
665 "/vector_stores/{vector_store_id}/files/{file_id}",
666 dependencies=[Depends(user_api_key_auth)],
667 response_class=ORJSONResponse,
668 tags=["vector_store_files"],
669)
670async def vector_store_file_retrieve(
671 vector_store_id: str,
672 file_id: str,
673 request: Request,
674 fastapi_response: Response,
675 user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
676):
677 from litellm.proxy.proxy_server import (
678 general_settings,
679 llm_router,
680 proxy_config,
681 proxy_logging_obj,
682 select_data_generator,
683 user_api_base,
684 user_max_tokens,
685 user_model,
686 user_request_timeout,
687 user_temperature,
688 version,
689 )
691 data: dict[str, str] = {
692 "vector_store_id": vector_store_id,
693 "file_id": file_id,
694 }
695 managed_vector_store: Final = await assert_user_can_access_vector_store_id(
696 vector_store_id=vector_store_id,
697 user_api_key_dict=user_api_key_dict,
698 )
700 # Handle managed file IDs first
701 data, original_managed_file_id = await _update_request_data_with_managed_file_id(
702 data=data,
703 file_id=file_id,
704 request=request,
705 user_api_key_dict=user_api_key_dict,
706 managed_files_obj=proxy_logging_obj.get_proxy_hook("managed_files"),
707 llm_router=llm_router,
708 )
710 # Then handle managed vector store IDs
711 data = _update_request_data_with_litellm_managed_vector_store_registry(
712 data=data,
713 vector_store_id=vector_store_id,
714 llm_router=llm_router,
715 managed_vector_store=managed_vector_store,
716 should_lookup_registry=False,
717 )
719 provider_enum: Final = await _resolve_provider(data=data, request=request)
721 _maybe_check_permissions(
722 provider=provider_enum,
723 vector_store_id=vector_store_id,
724 request=request,
725 user_api_key_dict=user_api_key_dict,
726 )
727 if provider_enum is not None and "custom_llm_provider" not in data:
728 data["custom_llm_provider"] = provider_enum.value
730 processor: Final = ProxyBaseLLMRequestProcessing(data=data)
731 try:
732 response: object = await processor.base_process_llm_request(
733 request=request,
734 fastapi_response=fastapi_response,
735 user_api_key_dict=user_api_key_dict,
736 route_type="avector_store_file_retrieve",
737 proxy_logging_obj=proxy_logging_obj,
738 llm_router=llm_router,
739 general_settings=general_settings,
740 proxy_config=proxy_config,
741 select_data_generator=select_data_generator,
742 model=None,
743 user_model=user_model,
744 user_temperature=user_temperature,
745 user_request_timeout=user_request_timeout,
746 user_max_tokens=user_max_tokens,
747 user_api_base=user_api_base,
748 version=version,
749 )
751 # Replace provider file ID with original managed file ID in response
752 if original_managed_file_id: 752 ↛ 753line 752 didn't jump to line 753 because the condition on line 752 was never true
753 response = _replace_file_id_in_response(response, original_managed_file_id)
755 return response
756 except Exception as e: # noqa: BLE001
757 raise await processor._handle_llm_api_exception(
758 e=e,
759 user_api_key_dict=user_api_key_dict,
760 proxy_logging_obj=proxy_logging_obj,
761 version=version,
762 )
765@router.get(
766 "/v1/vector_stores/{vector_store_id}/files/{file_id}/content",
767 dependencies=[Depends(user_api_key_auth)],
768 response_class=ORJSONResponse,
769 tags=["vector_store_files"],
770)
771@router.get(
772 "/vector_stores/{vector_store_id}/files/{file_id}/content",
773 dependencies=[Depends(user_api_key_auth)],
774 response_class=ORJSONResponse,
775 tags=["vector_store_files"],
776)
777async def vector_store_file_content(
778 vector_store_id: str,
779 file_id: str,
780 request: Request,
781 fastapi_response: Response,
782 user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
783):
784 from litellm.proxy.proxy_server import (
785 general_settings,
786 llm_router,
787 proxy_config,
788 proxy_logging_obj,
789 select_data_generator,
790 user_api_base,
791 user_max_tokens,
792 user_model,
793 user_request_timeout,
794 user_temperature,
795 version,
796 )
798 data: dict[str, str] = {
799 "vector_store_id": vector_store_id,
800 "file_id": file_id,
801 }
802 managed_vector_store: Final = await assert_user_can_access_vector_store_id(
803 vector_store_id=vector_store_id,
804 user_api_key_dict=user_api_key_dict,
805 )
807 # Handle managed file IDs first
808 data, original_managed_file_id = await _update_request_data_with_managed_file_id(
809 data=data,
810 file_id=file_id,
811 request=request,
812 user_api_key_dict=user_api_key_dict,
813 managed_files_obj=proxy_logging_obj.get_proxy_hook("managed_files"),
814 llm_router=llm_router,
815 )
817 # Then handle managed vector store IDs
818 data = _update_request_data_with_litellm_managed_vector_store_registry(
819 data=data,
820 vector_store_id=vector_store_id,
821 llm_router=llm_router,
822 managed_vector_store=managed_vector_store,
823 should_lookup_registry=False,
824 )
826 provider_enum: Final = await _resolve_provider(data=data, request=request)
828 _maybe_check_permissions(
829 provider=provider_enum,
830 vector_store_id=vector_store_id,
831 request=request,
832 user_api_key_dict=user_api_key_dict,
833 )
834 if provider_enum is not None and "custom_llm_provider" not in data:
835 data["custom_llm_provider"] = provider_enum.value
837 processor: Final = ProxyBaseLLMRequestProcessing(data=data)
838 try:
839 response: object = await processor.base_process_llm_request(
840 request=request,
841 fastapi_response=fastapi_response,
842 user_api_key_dict=user_api_key_dict,
843 route_type="avector_store_file_content",
844 proxy_logging_obj=proxy_logging_obj,
845 llm_router=llm_router,
846 general_settings=general_settings,
847 proxy_config=proxy_config,
848 select_data_generator=select_data_generator,
849 model=None,
850 user_model=user_model,
851 user_temperature=user_temperature,
852 user_request_timeout=user_request_timeout,
853 user_max_tokens=user_max_tokens,
854 user_api_base=user_api_base,
855 version=version,
856 )
858 # Replace provider file ID with original managed file ID in response
859 if original_managed_file_id: 859 ↛ 860line 859 didn't jump to line 860 because the condition on line 859 was never true
860 response = _replace_file_id_in_response(response, original_managed_file_id)
862 for header_name, header_value in safe_download_headers(file_id).items():
863 fastapi_response.headers[header_name] = header_value
865 return response
866 except Exception as e: # noqa: BLE001
867 raise await processor._handle_llm_api_exception(
868 e=e,
869 user_api_key_dict=user_api_key_dict,
870 proxy_logging_obj=proxy_logging_obj,
871 version=version,
872 )
875@router.post(
876 "/v1/vector_stores/{vector_store_id}/files/{file_id}",
877 dependencies=[Depends(user_api_key_auth)],
878 response_class=ORJSONResponse,
879 tags=["vector_store_files"],
880)
881@router.post(
882 "/vector_stores/{vector_store_id}/files/{file_id}",
883 dependencies=[Depends(user_api_key_auth)],
884 response_class=ORJSONResponse,
885 tags=["vector_store_files"],
886)
887async def vector_store_file_update(
888 vector_store_id: str,
889 file_id: str,
890 request: Request,
891 fastapi_response: Response,
892 user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
893):
894 from litellm.proxy.proxy_server import (
895 _read_request_body,
896 general_settings,
897 llm_router,
898 proxy_config,
899 proxy_logging_obj,
900 select_data_generator,
901 user_api_base,
902 user_max_tokens,
903 user_model,
904 user_request_timeout,
905 user_temperature,
906 version,
907 )
909 data = await _read_request_body(request=request)
910 data["vector_store_id"] = vector_store_id
911 data["file_id"] = file_id
912 managed_vector_store: Final = await assert_user_can_access_vector_store_id(
913 vector_store_id=vector_store_id,
914 user_api_key_dict=user_api_key_dict,
915 )
917 # Handle managed file IDs first
918 data, original_managed_file_id = await _update_request_data_with_managed_file_id(
919 data=data,
920 file_id=file_id,
921 request=request,
922 user_api_key_dict=user_api_key_dict,
923 managed_files_obj=proxy_logging_obj.get_proxy_hook("managed_files"),
924 llm_router=llm_router,
925 )
927 # Then handle managed vector store IDs
928 data = _update_request_data_with_litellm_managed_vector_store_registry(
929 data=data,
930 vector_store_id=vector_store_id,
931 llm_router=llm_router,
932 managed_vector_store=managed_vector_store,
933 should_lookup_registry=False,
934 )
936 provider_enum: Final = await _resolve_provider(data=data, request=request)
938 _maybe_check_permissions(
939 provider=provider_enum,
940 vector_store_id=vector_store_id,
941 request=request,
942 user_api_key_dict=user_api_key_dict,
943 )
944 if provider_enum is not None and "custom_llm_provider" not in data:
945 data["custom_llm_provider"] = provider_enum.value
947 processor: Final = ProxyBaseLLMRequestProcessing(data=data)
948 try:
949 response: object = await processor.base_process_llm_request(
950 request=request,
951 fastapi_response=fastapi_response,
952 user_api_key_dict=user_api_key_dict,
953 route_type="avector_store_file_update",
954 proxy_logging_obj=proxy_logging_obj,
955 llm_router=llm_router,
956 general_settings=general_settings,
957 proxy_config=proxy_config,
958 select_data_generator=select_data_generator,
959 model=None,
960 user_model=user_model,
961 user_temperature=user_temperature,
962 user_request_timeout=user_request_timeout,
963 user_max_tokens=user_max_tokens,
964 user_api_base=user_api_base,
965 version=version,
966 )
968 # Replace provider file ID with original managed file ID in response
969 if original_managed_file_id:
970 response = _replace_file_id_in_response(response, original_managed_file_id)
972 return response
973 except Exception as e: # noqa: BLE001
974 raise await processor._handle_llm_api_exception(
975 e=e,
976 user_api_key_dict=user_api_key_dict,
977 proxy_logging_obj=proxy_logging_obj,
978 version=version,
979 )
982@router.delete(
983 "/v1/vector_stores/{vector_store_id}/files/{file_id}",
984 dependencies=[Depends(user_api_key_auth)],
985 response_class=ORJSONResponse,
986 tags=["vector_store_files"],
987)
988@router.delete(
989 "/vector_stores/{vector_store_id}/files/{file_id}",
990 dependencies=[Depends(user_api_key_auth)],
991 response_class=ORJSONResponse,
992 tags=["vector_store_files"],
993)
994async def vector_store_file_delete(
995 vector_store_id: str,
996 file_id: str,
997 request: Request,
998 fastapi_response: Response,
999 user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
1000):
1001 from litellm.proxy.proxy_server import (
1002 general_settings,
1003 llm_router,
1004 proxy_config,
1005 proxy_logging_obj,
1006 select_data_generator,
1007 user_api_base,
1008 user_max_tokens,
1009 user_model,
1010 user_request_timeout,
1011 user_temperature,
1012 version,
1013 )
1015 data: dict[str, str] = {
1016 "vector_store_id": vector_store_id,
1017 "file_id": file_id,
1018 }
1019 managed_vector_store: Final = await assert_user_can_access_vector_store_id(
1020 vector_store_id=vector_store_id,
1021 user_api_key_dict=user_api_key_dict,
1022 )
1024 # Handle managed file IDs first
1025 data, original_managed_file_id = await _update_request_data_with_managed_file_id(
1026 data=data,
1027 file_id=file_id,
1028 request=request,
1029 user_api_key_dict=user_api_key_dict,
1030 managed_files_obj=proxy_logging_obj.get_proxy_hook("managed_files"),
1031 llm_router=llm_router,
1032 )
1034 # Then handle managed vector store IDs
1035 data = _update_request_data_with_litellm_managed_vector_store_registry(
1036 data=data,
1037 vector_store_id=vector_store_id,
1038 llm_router=llm_router,
1039 managed_vector_store=managed_vector_store,
1040 should_lookup_registry=False,
1041 )
1043 provider_enum: Final = await _resolve_provider(data=data, request=request)
1045 _maybe_check_permissions(
1046 provider=provider_enum,
1047 vector_store_id=vector_store_id,
1048 request=request,
1049 user_api_key_dict=user_api_key_dict,
1050 )
1051 if provider_enum is not None and "custom_llm_provider" not in data:
1052 data["custom_llm_provider"] = provider_enum.value
1054 processor: Final = ProxyBaseLLMRequestProcessing(data=data)
1055 try:
1056 response: object = await processor.base_process_llm_request(
1057 request=request,
1058 fastapi_response=fastapi_response,
1059 user_api_key_dict=user_api_key_dict,
1060 route_type="avector_store_file_delete",
1061 proxy_logging_obj=proxy_logging_obj,
1062 llm_router=llm_router,
1063 general_settings=general_settings,
1064 proxy_config=proxy_config,
1065 select_data_generator=select_data_generator,
1066 model=None,
1067 user_model=user_model,
1068 user_temperature=user_temperature,
1069 user_request_timeout=user_request_timeout,
1070 user_max_tokens=user_max_tokens,
1071 user_api_base=user_api_base,
1072 version=version,
1073 )
1075 # Replace provider file ID with original managed file ID in response
1076 if original_managed_file_id:
1077 response = _replace_file_id_in_response(response, original_managed_file_id)
1079 return response
1080 except Exception as e: # noqa: BLE001
1081 raise await processor._handle_llm_api_exception(
1082 e=e,
1083 user_api_key_dict=user_api_key_dict,
1084 proxy_logging_obj=proxy_logging_obj,
1085 version=version,
1086 )