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

1from typing import TYPE_CHECKING, Final, Optional 

2 

3from fastapi import APIRouter, Depends, Request, Response 

4from fastapi.responses import ORJSONResponse 

5 

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 

28 

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 

31 

32router: Final = APIRouter() 

33 

34 

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. 

45 

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};...) 

49 

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 

54 

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) 

60 

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 

66 

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 ) 

75 

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 ) 

82 

83 # First, check if this is a unified managed file ID (base64 encoded) 

84 decoded_id: Final = is_base64_encoded_unified_id(file_id) 

85 

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) 

89 

90 # Parse the unified ID to extract components 

91 parsed_id: Final = parse_unified_id(file_id) 

92 

93 if parsed_id: 

94 target_model_names: Final = parsed_id.get("target_model_names", []) 

95 

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 

105 

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 ) 

111 

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 

116 

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 

133 

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 

139 

140 return data, file_id if decoded_id else None 

141 

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 ) 

156 

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 ) 

164 

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 

170 

171 return data, None 

172 

173 

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. 

177 

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. 

180 

181 Args: 

182 response: The response object from the provider 

183 original_file_id: The original managed file ID to restore 

184 

185 Returns: 

186 Modified response with original file ID 

187 """ 

188 if response is None: 

189 return response 

190 

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 

203 

204 return response 

205 

206 

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) 

216 

217 

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 

226 

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 

230 

231 caller_team_id: Final = getattr(user_api_key_dict, "team_id", None) if user_api_key_dict else None 

232 

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 

256 

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 

263 

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 

266 

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 

270 

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) 

280 

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 

286 

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 

293 

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 

302 

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] 

312 

313 return data 

314 

315 

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. 

325 

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) 

329 

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 

335 

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) 

340 

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 ) 

349 

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) 

352 

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) 

356 

357 parsed_id: Final = parse_unified_id(vector_store_id) 

358 

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", []) 

363 

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 ) 

370 

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] 

378 

379 if routing_model: 

380 data["model"] = routing_model 

381 verbose_logger.info("Routing vector store files operation to model: %s", routing_model) 

382 

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 ) 

389 

390 return data 

391 

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 ) 

398 

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) 

407 

408 return data 

409 

410 

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 ) 

421 

422 if provider is None and request.method in {"POST", "PUT", "PATCH"}: 

423 provider = await get_custom_llm_provider_from_request_body(request=request) 

424 

425 if provider is None: 

426 provider = "openai" 

427 

428 try: 

429 return LlmProviders(provider) 

430 except Exception: 

431 return None 

432 

433 

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 ) 

453 

454 

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 ) 

487 

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 ) 

494 

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 ) 

506 

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 ) 

515 

516 provider_enum: Final = await _resolve_provider(data=data, request=request) 

517 

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 

526 

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 ) 

547 

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) 

551 

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 ) 

560 

561 

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 ) 

593 

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 ) 

602 

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 ) 

610 

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 ) 

617 

618 provider_enum: Final = await _resolve_provider(data=data, request=request) 

619 

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 

628 

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 ) 

656 

657 

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 ) 

690 

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 ) 

699 

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 ) 

709 

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 ) 

718 

719 provider_enum: Final = await _resolve_provider(data=data, request=request) 

720 

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 

729 

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 ) 

750 

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) 

754 

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 ) 

763 

764 

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 ) 

797 

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 ) 

806 

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 ) 

816 

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 ) 

825 

826 provider_enum: Final = await _resolve_provider(data=data, request=request) 

827 

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 

836 

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 ) 

857 

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) 

861 

862 for header_name, header_value in safe_download_headers(file_id).items(): 

863 fastapi_response.headers[header_name] = header_value 

864 

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 ) 

873 

874 

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 ) 

908 

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 ) 

916 

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 ) 

926 

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 ) 

935 

936 provider_enum: Final = await _resolve_provider(data=data, request=request) 

937 

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 

946 

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 ) 

967 

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) 

971 

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 ) 

980 

981 

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 ) 

1014 

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 ) 

1023 

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 ) 

1033 

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 ) 

1042 

1043 provider_enum: Final = await _resolve_provider(data=data, request=request) 

1044 

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 

1053 

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 ) 

1074 

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) 

1078 

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 )