Coverage for .venv/lib/python3.13/site-packages/litellm/proxy/video_endpoints/endpoints.py: 68%

207 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-10 12:01 +0000

1#### Video Endpoints ##### 

2 

3from typing import Final 

4 

5from fastapi import APIRouter, Depends, File, Form, Request, Response, UploadFile 

6from fastapi.responses import ORJSONResponse 

7from starlette.datastructures import UploadFile as StarletteUploadFile 

8 

9from litellm.proxy._types import * 

10from litellm.proxy.auth.user_api_key_auth import UserAPIKeyAuth, user_api_key_auth 

11from litellm.proxy.common_request_processing import ProxyBaseLLMRequestProcessing 

12from litellm.proxy.common_utils.http_parsing_utils import _read_request_body 

13from litellm.proxy.common_utils.openai_endpoint_utils import ( 

14 get_custom_llm_provider_from_request_body, 

15 get_custom_llm_provider_from_request_headers, 

16 get_custom_llm_provider_from_request_query, 

17) 

18from litellm.proxy.image_endpoints.endpoints import batch_to_bytesio 

19from litellm.proxy.video_endpoints.utils import ( 

20 encode_character_id_in_response, 

21 extract_model_from_target_model_names, 

22 get_custom_provider_from_data, 

23 video_reference_to_id, 

24) 

25from litellm.types.videos.utils import ( 

26 decode_character_id_with_provider, 

27 decode_video_id_with_provider, 

28) 

29 

30router: Final = APIRouter() 

31 

32 

33@router.post( 

34 "/v1/videos", 

35 dependencies=[Depends(user_api_key_auth)], 

36 response_class=ORJSONResponse, 

37 tags=["videos"], 

38) 

39@router.post( 

40 "/videos", 

41 dependencies=[Depends(user_api_key_auth)], 

42 response_class=ORJSONResponse, 

43 tags=["videos"], 

44) 

45async def video_generation( 

46 request: Request, 

47 fastapi_response: Response, 

48 input_reference: UploadFile | None = File(None), 

49 user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), 

50): 

51 """ 

52 Video generation endpoint for creating videos from text prompts. 

53  

54 Follows the OpenAI Videos API spec: 

55 https://platform.openai.com/docs/api-reference/videos 

56  

57 Example: 

58 ```bash 

59 curl -X POST "http://localhost:4000/v1/videos" \ 

60 -H "Authorization: Bearer sk-1234" \ 

61 -H "Content-Type: application/json" \ 

62 -d '{ 

63 "model": "sora-2", 

64 "prompt": "A beautiful sunset over the ocean" 

65 }' 

66 ``` 

67 """ 

68 from litellm.proxy.proxy_server import ( 

69 general_settings, 

70 llm_router, 

71 proxy_config, 

72 proxy_logging_obj, 

73 select_data_generator, 

74 user_api_base, 

75 user_max_tokens, 

76 user_model, 

77 user_request_timeout, 

78 user_temperature, 

79 version, 

80 ) 

81 

82 # Read request body 

83 data: Final = await _read_request_body(request=request) 

84 if input_reference is not None: 84 ↛ 85line 84 didn't jump to line 85 because the condition on line 84 was never true

85 input_reference_file: Final = await batch_to_bytesio([input_reference]) 

86 if input_reference_file: 

87 data["input_reference"] = input_reference_file[0] 

88 

89 # Process request using ProxyBaseLLMRequestProcessing 

90 processor: Final = ProxyBaseLLMRequestProcessing(data=data) 

91 try: 

92 generated: Final[object] = await processor.base_process_llm_request( 

93 request=request, 

94 fastapi_response=fastapi_response, 

95 user_api_key_dict=user_api_key_dict, 

96 route_type="avideo_generation", 

97 proxy_logging_obj=proxy_logging_obj, 

98 llm_router=llm_router, 

99 general_settings=general_settings, 

100 proxy_config=proxy_config, 

101 select_data_generator=select_data_generator, 

102 model=None, 

103 user_model=user_model, 

104 user_temperature=user_temperature, 

105 user_request_timeout=user_request_timeout, 

106 user_max_tokens=user_max_tokens, 

107 user_api_base=user_api_base, 

108 version=version, 

109 ) 

110 except Exception as e: 

111 raise await processor._handle_llm_api_exception( 

112 e=e, 

113 user_api_key_dict=user_api_key_dict, 

114 proxy_logging_obj=proxy_logging_obj, 

115 version=version, 

116 ) 

117 else: 

118 return generated 

119 

120 

121@router.get( 

122 "/v1/videos", 

123 dependencies=[Depends(user_api_key_auth)], 

124 response_class=ORJSONResponse, 

125 tags=["videos"], 

126) 

127@router.get( 

128 "/videos", 

129 dependencies=[Depends(user_api_key_auth)], 

130 response_class=ORJSONResponse, 

131 tags=["videos"], 

132) 

133async def video_list( 

134 request: Request, 

135 fastapi_response: Response, 

136 user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), 

137): 

138 """ 

139 Video list endpoint for retrieving a list of videos. 

140  

141 Follows the OpenAI Videos API spec: 

142 https://platform.openai.com/docs/api-reference/videos 

143  

144 Example: 

145 ```bash 

146 curl -X GET "http://localhost:4000/v1/videos" \ 

147 -H "Authorization: Bearer sk-1234" 

148 ``` 

149 """ 

150 from litellm.proxy.proxy_server import ( 

151 general_settings, 

152 llm_router, 

153 proxy_config, 

154 proxy_logging_obj, 

155 select_data_generator, 

156 user_api_base, 

157 user_max_tokens, 

158 user_model, 

159 user_request_timeout, 

160 user_temperature, 

161 version, 

162 ) 

163 

164 # Read query parameters 

165 query_params: Final = dict(request.query_params) 

166 data: Final[dict[str, object]] = {"query_params": query_params} 

167 

168 # Extract custom_llm_provider from headers, query params, or body 

169 custom_llm_provider: Final = ( 

170 get_custom_llm_provider_from_request_headers(request=request) 

171 or get_custom_llm_provider_from_request_query(request=request) 

172 or await get_custom_llm_provider_from_request_body(request=request) 

173 ) 

174 if custom_llm_provider: 174 ↛ 175line 174 didn't jump to line 175 because the condition on line 174 was never true

175 data["custom_llm_provider"] = custom_llm_provider 

176 # Process request using ProxyBaseLLMRequestProcessing 

177 processor: Final = ProxyBaseLLMRequestProcessing(data=data) 

178 try: 

179 listed: Final[object] = await processor.base_process_llm_request( 

180 request=request, 

181 fastapi_response=fastapi_response, 

182 user_api_key_dict=user_api_key_dict, 

183 route_type="avideo_list", 

184 proxy_logging_obj=proxy_logging_obj, 

185 llm_router=llm_router, 

186 general_settings=general_settings, 

187 proxy_config=proxy_config, 

188 select_data_generator=select_data_generator, 

189 model=None, 

190 user_model=user_model, 

191 user_temperature=user_temperature, 

192 user_request_timeout=user_request_timeout, 

193 user_max_tokens=user_max_tokens, 

194 user_api_base=user_api_base, 

195 version=version, 

196 ) 

197 except Exception as e: 

198 raise await processor._handle_llm_api_exception( 

199 e=e, 

200 user_api_key_dict=user_api_key_dict, 

201 proxy_logging_obj=proxy_logging_obj, 

202 version=version, 

203 ) 

204 else: 

205 return listed 

206 

207 

208@router.get( 

209 "/v1/videos/{video_id}", 

210 dependencies=[Depends(user_api_key_auth)], 

211 response_class=ORJSONResponse, 

212 tags=["videos"], 

213) 

214@router.get( 

215 "/videos/{video_id}", 

216 dependencies=[Depends(user_api_key_auth)], 

217 response_class=ORJSONResponse, 

218 tags=["videos"], 

219) 

220async def video_status( 

221 video_id: str, 

222 request: Request, 

223 fastapi_response: Response, 

224 user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), 

225): 

226 """ 

227 Video status endpoint for retrieving video status and metadata. 

228  

229 Follows the OpenAI Videos API spec: 

230 https://platform.openai.com/docs/api-reference/videos 

231  

232 Example: 

233 ```bash 

234 curl -X GET "http://localhost:4000/v1/videos/video_123" \ 

235 -H "Authorization: Bearer sk-1234" 

236 ``` 

237 """ 

238 from litellm.proxy.proxy_server import ( 

239 general_settings, 

240 llm_router, 

241 proxy_config, 

242 proxy_logging_obj, 

243 select_data_generator, 

244 user_api_base, 

245 user_max_tokens, 

246 user_model, 

247 user_request_timeout, 

248 user_temperature, 

249 version, 

250 ) 

251 

252 # Create data with video_id 

253 data: Final[dict[str, object]] = {"video_id": video_id} 

254 

255 decoded: Final = decode_video_id_with_provider(video_id) 

256 provider_from_id: Final = decoded.get("custom_llm_provider") 

257 model_id_from_decoded: Final = decoded.get("model_id") 

258 

259 custom_llm_provider: Final = ( 

260 get_custom_llm_provider_from_request_headers(request=request) 

261 or get_custom_llm_provider_from_request_query(request=request) 

262 or await get_custom_llm_provider_from_request_body(request=request) 

263 or provider_from_id 

264 or "openai" 

265 ) 

266 if custom_llm_provider: 266 ↛ 271line 266 didn't jump to line 271 because the condition on line 266 was always true

267 data["custom_llm_provider"] = custom_llm_provider 

268 

269 # Resolve model_name from model_id if available 

270 # This allows the router to automatically inject litellm_params from the model config 

271 if model_id_from_decoded and llm_router: 271 ↛ 272line 271 didn't jump to line 272 because the condition on line 271 was never true

272 resolved_model: Final = llm_router.resolve_model_name_from_model_id(model_id_from_decoded) 

273 if resolved_model: 

274 data["model"] = resolved_model 

275 

276 # Process request using ProxyBaseLLMRequestProcessing 

277 processor: Final = ProxyBaseLLMRequestProcessing(data=data) 

278 try: 

279 status: Final[object] = await processor.base_process_llm_request( 

280 request=request, 

281 fastapi_response=fastapi_response, 

282 user_api_key_dict=user_api_key_dict, 

283 route_type="avideo_status", 

284 proxy_logging_obj=proxy_logging_obj, 

285 llm_router=llm_router, 

286 general_settings=general_settings, 

287 proxy_config=proxy_config, 

288 select_data_generator=select_data_generator, 

289 model=None, 

290 user_model=user_model, 

291 user_temperature=user_temperature, 

292 user_request_timeout=user_request_timeout, 

293 user_max_tokens=user_max_tokens, 

294 user_api_base=user_api_base, 

295 version=version, 

296 ) 

297 except Exception as e: 

298 raise await processor._handle_llm_api_exception( 

299 e=e, 

300 user_api_key_dict=user_api_key_dict, 

301 proxy_logging_obj=proxy_logging_obj, 

302 version=version, 

303 ) 

304 else: 

305 return status 

306 

307 

308@router.get( 

309 "/v1/videos/{video_id}/content", 

310 dependencies=[Depends(user_api_key_auth)], 

311 response_class=Response, 

312 tags=["videos"], 

313) 

314@router.get( 

315 "/videos/{video_id}/content", 

316 dependencies=[Depends(user_api_key_auth)], 

317 response_class=Response, 

318 tags=["videos"], 

319) 

320async def video_content( 

321 video_id: str, 

322 request: Request, 

323 fastapi_response: Response, 

324 user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), 

325): 

326 """ 

327 Video content endpoint for downloading video content. 

328  

329 Follows the OpenAI Videos API spec: 

330 https://platform.openai.com/docs/api-reference/videos 

331  

332 Example: 

333 ```bash 

334 curl -X GET "http://localhost:4000/v1/videos/{video_id}/content" \ 

335 -H "Authorization: Bearer sk-1234" \ 

336 --output video.mp4 

337 ``` 

338 """ 

339 from litellm.proxy.proxy_server import ( 

340 general_settings, 

341 llm_router, 

342 proxy_config, 

343 proxy_logging_obj, 

344 select_data_generator, 

345 user_api_base, 

346 user_max_tokens, 

347 user_model, 

348 user_request_timeout, 

349 user_temperature, 

350 version, 

351 ) 

352 

353 # Create data with video_id 

354 data: Final[dict[str, object]] = {"video_id": video_id} 

355 

356 decoded: Final = decode_video_id_with_provider(video_id) 

357 provider_from_id: Final = decoded.get("custom_llm_provider") 

358 model_id_from_decoded: Final = decoded.get("model_id") 

359 

360 custom_llm_provider: Final = ( 

361 get_custom_llm_provider_from_request_headers(request=request) 

362 or get_custom_llm_provider_from_request_query(request=request) 

363 or await get_custom_llm_provider_from_request_body(request=request) 

364 or provider_from_id 

365 ) 

366 if custom_llm_provider: 366 ↛ 367line 366 didn't jump to line 367 because the condition on line 366 was never true

367 data["custom_llm_provider"] = custom_llm_provider 

368 

369 # Resolve model_name from model_id if available 

370 # This allows the router to automatically inject litellm_params from the model config 

371 if model_id_from_decoded and llm_router: 371 ↛ 372line 371 didn't jump to line 372 because the condition on line 371 was never true

372 resolved_model: Final = llm_router.resolve_model_name_from_model_id(model_id_from_decoded) 

373 if resolved_model: 

374 data["model"] = resolved_model 

375 # Process request using ProxyBaseLLMRequestProcessing 

376 processor: Final = ProxyBaseLLMRequestProcessing(data=data) 

377 try: 

378 # Call the video content function directly to get raw bytes 

379 video_bytes: Final = await processor.base_process_llm_request( 

380 request=request, 

381 fastapi_response=fastapi_response, 

382 user_api_key_dict=user_api_key_dict, 

383 route_type="avideo_content", 

384 proxy_logging_obj=proxy_logging_obj, 

385 llm_router=llm_router, 

386 general_settings=general_settings, 

387 proxy_config=proxy_config, 

388 select_data_generator=select_data_generator, 

389 model=None, 

390 user_model=user_model, 

391 user_temperature=user_temperature, 

392 user_request_timeout=user_request_timeout, 

393 user_max_tokens=user_max_tokens, 

394 user_api_base=user_api_base, 

395 version=version, 

396 ) 

397 

398 # Return raw video bytes with proper content type 

399 return Response( 

400 content=video_bytes, 

401 media_type="video/mp4", 

402 headers={"Content-Disposition": f"attachment; filename=video_{video_id}.mp4"}, 

403 ) 

404 except Exception as e: 

405 raise await processor._handle_llm_api_exception( 

406 e=e, 

407 user_api_key_dict=user_api_key_dict, 

408 proxy_logging_obj=proxy_logging_obj, 

409 version=version, 

410 ) 

411 

412 

413@router.post( 

414 "/v1/videos/{video_id}/remix", 

415 dependencies=[Depends(user_api_key_auth)], 

416 response_class=ORJSONResponse, 

417 tags=["videos"], 

418) 

419@router.post( 

420 "/videos/{video_id}/remix", 

421 dependencies=[Depends(user_api_key_auth)], 

422 response_class=ORJSONResponse, 

423 tags=["videos"], 

424) 

425async def video_remix( 

426 video_id: str, 

427 request: Request, 

428 fastapi_response: Response, 

429 user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), 

430): 

431 """ 

432 Video remix endpoint for remixing existing videos with new prompts. 

433  

434 Follows the OpenAI Videos API spec: 

435 https://platform.openai.com/docs/api-reference/videos 

436  

437 Example: 

438 ```bash 

439 curl -X POST "http://localhost:4000/v1/videos/video_123/remix" \ 

440 -H "Authorization: Bearer sk-1234" \ 

441 -H "Content-Type: application/json" \ 

442 -d '{ 

443 "prompt": "A new version with different colors" 

444 }' 

445 ``` 

446 """ 

447 from litellm.proxy.proxy_server import ( 

448 general_settings, 

449 llm_router, 

450 proxy_config, 

451 proxy_logging_obj, 

452 select_data_generator, 

453 user_api_base, 

454 user_max_tokens, 

455 user_model, 

456 user_request_timeout, 

457 user_temperature, 

458 version, 

459 ) 

460 

461 data: Final = await _read_request_body(request=request) 

462 data["video_id"] = video_id 

463 

464 decoded: Final = decode_video_id_with_provider(video_id) 

465 provider_from_id: Final = decoded.get("custom_llm_provider") 

466 model_id_from_decoded: Final = decoded.get("model_id") 

467 

468 custom_llm_provider: Final = ( 

469 get_custom_llm_provider_from_request_headers(request=request) 

470 or get_custom_llm_provider_from_request_query(request=request) 

471 or data.get("custom_llm_provider") 

472 or provider_from_id 

473 ) 

474 if custom_llm_provider: 474 ↛ 475line 474 didn't jump to line 475 because the condition on line 474 was never true

475 data["custom_llm_provider"] = custom_llm_provider 

476 

477 # Resolve model_name from model_id if available 

478 # This allows the router to automatically inject litellm_params from the model config 

479 if model_id_from_decoded and llm_router: 479 ↛ 480line 479 didn't jump to line 480 because the condition on line 479 was never true

480 resolved_model: Final = llm_router.resolve_model_name_from_model_id(model_id_from_decoded) 

481 if resolved_model: 

482 data["model"] = resolved_model 

483 

484 # Process request using ProxyBaseLLMRequestProcessing 

485 processor: Final = ProxyBaseLLMRequestProcessing(data=data) 

486 try: 

487 remixed: Final[object] = await processor.base_process_llm_request( 

488 request=request, 

489 fastapi_response=fastapi_response, 

490 user_api_key_dict=user_api_key_dict, 

491 route_type="avideo_remix", 

492 proxy_logging_obj=proxy_logging_obj, 

493 llm_router=llm_router, 

494 general_settings=general_settings, 

495 proxy_config=proxy_config, 

496 select_data_generator=select_data_generator, 

497 model=None, 

498 user_model=user_model, 

499 user_temperature=user_temperature, 

500 user_request_timeout=user_request_timeout, 

501 user_max_tokens=user_max_tokens, 

502 user_api_base=user_api_base, 

503 version=version, 

504 ) 

505 except Exception as e: 

506 raise await processor._handle_llm_api_exception( 

507 e=e, 

508 user_api_key_dict=user_api_key_dict, 

509 proxy_logging_obj=proxy_logging_obj, 

510 version=version, 

511 ) 

512 else: 

513 return remixed 

514 

515 

516@router.post( 

517 "/v1/videos/characters", 

518 dependencies=[Depends(user_api_key_auth)], 

519 response_class=ORJSONResponse, 

520 tags=["videos"], 

521) 

522@router.post( 

523 "/videos/characters", 

524 dependencies=[Depends(user_api_key_auth)], 

525 response_class=ORJSONResponse, 

526 tags=["videos"], 

527) 

528async def video_create_character( 

529 request: Request, 

530 fastapi_response: Response, 

531 video: UploadFile = File(...), 

532 name: str = Form(...), 

533 user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), 

534): 

535 """ 

536 Create a character from an uploaded video file. 

537 

538 Follows the OpenAI Videos API spec: 

539 https://platform.openai.com/docs/api-reference/videos/create-character 

540 

541 Example: 

542 ```bash 

543 curl -X POST "http://localhost:4000/v1/videos/characters" \ 

544 -H "Authorization: Bearer sk-1234" \ 

545 -F "video=@character_video.mp4" \ 

546 -F "name=my_character" 

547 ``` 

548 """ 

549 from litellm.proxy.proxy_server import ( 

550 general_settings, 

551 llm_router, 

552 proxy_config, 

553 proxy_logging_obj, 

554 select_data_generator, 

555 user_api_base, 

556 user_max_tokens, 

557 user_model, 

558 user_request_timeout, 

559 user_temperature, 

560 version, 

561 ) 

562 

563 data: Final = await _read_request_body(request=request) 

564 video_file: Final = await batch_to_bytesio([video]) 

565 if video_file: 565 ↛ 568line 565 didn't jump to line 568 because the condition on line 565 was always true

566 data["video"] = video_file[0] 

567 

568 target_model_name: Final = extract_model_from_target_model_names(data.get("target_model_names")) 

569 if target_model_name and not data.get("model"): 569 ↛ 570line 569 didn't jump to line 570 because the condition on line 569 was never true

570 data["model"] = target_model_name 

571 

572 custom_llm_provider: Final = ( 

573 get_custom_llm_provider_from_request_headers(request=request) 

574 or get_custom_llm_provider_from_request_query(request=request) 

575 or get_custom_provider_from_data(data=data) 

576 or "openai" 

577 ) 

578 data["custom_llm_provider"] = custom_llm_provider 

579 

580 processor: Final = ProxyBaseLLMRequestProcessing(data=data) 

581 try: 

582 response: object = await processor.base_process_llm_request( 

583 request=request, 

584 fastapi_response=fastapi_response, 

585 user_api_key_dict=user_api_key_dict, 

586 route_type="avideo_create_character", 

587 proxy_logging_obj=proxy_logging_obj, 

588 llm_router=llm_router, 

589 general_settings=general_settings, 

590 proxy_config=proxy_config, 

591 select_data_generator=select_data_generator, 

592 model=None, 

593 user_model=user_model, 

594 user_temperature=user_temperature, 

595 user_request_timeout=user_request_timeout, 

596 user_max_tokens=user_max_tokens, 

597 user_api_base=user_api_base, 

598 version=version, 

599 ) 

600 if target_model_name: 

601 hidden_params: Final = getattr(response, "_hidden_params", {}) or {} 

602 provider_for_encoding: Final = hidden_params.get("custom_llm_provider") or custom_llm_provider or "openai" 

603 model_id_for_encoding: Final = hidden_params.get("model_id") or data.get("model") 

604 response = encode_character_id_in_response( 

605 response=response, 

606 custom_llm_provider=provider_for_encoding, 

607 model_id=model_id_for_encoding, 

608 ) 

609 return response 

610 except Exception as e: 

611 raise await processor._handle_llm_api_exception( 

612 e=e, 

613 user_api_key_dict=user_api_key_dict, 

614 proxy_logging_obj=proxy_logging_obj, 

615 version=version, 

616 ) 

617 

618 

619@router.get( 

620 "/v1/videos/characters/{character_id}", 

621 dependencies=[Depends(user_api_key_auth)], 

622 response_class=ORJSONResponse, 

623 tags=["videos"], 

624) 

625@router.get( 

626 "/videos/characters/{character_id}", 

627 dependencies=[Depends(user_api_key_auth)], 

628 response_class=ORJSONResponse, 

629 tags=["videos"], 

630) 

631async def video_get_character( 

632 character_id: str, 

633 request: Request, 

634 fastapi_response: Response, 

635 user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), 

636): 

637 """ 

638 Retrieve a character by ID. 

639 

640 Follows the OpenAI Videos API spec: 

641 https://platform.openai.com/docs/api-reference/videos/get-character 

642 

643 Example: 

644 ```bash 

645 curl -X GET "http://localhost:4000/v1/videos/characters/char_123" \ 

646 -H "Authorization: Bearer sk-1234" 

647 ``` 

648 """ 

649 from litellm.proxy.proxy_server import ( 

650 general_settings, 

651 llm_router, 

652 proxy_config, 

653 proxy_logging_obj, 

654 select_data_generator, 

655 user_api_base, 

656 user_max_tokens, 

657 user_model, 

658 user_request_timeout, 

659 user_temperature, 

660 version, 

661 ) 

662 

663 original_requested_character_id: Final = character_id 

664 data: Final[dict[str, object]] = {"character_id": character_id} 

665 

666 decoded: Final = decode_character_id_with_provider(character_id) 

667 provider_from_id: Final = decoded.get("custom_llm_provider") 

668 model_id_from_decoded: Final = decoded.get("model_id") 

669 decoded_character_id: Final = decoded.get("character_id") 

670 if decoded_character_id: 670 ↛ 673line 670 didn't jump to line 673 because the condition on line 670 was always true

671 data["character_id"] = decoded_character_id 

672 

673 custom_llm_provider: Final = ( 

674 get_custom_llm_provider_from_request_headers(request=request) 

675 or get_custom_llm_provider_from_request_query(request=request) 

676 or await get_custom_llm_provider_from_request_body(request=request) 

677 or provider_from_id 

678 or "openai" 

679 ) 

680 data["custom_llm_provider"] = custom_llm_provider 

681 

682 if model_id_from_decoded and llm_router: 682 ↛ 683line 682 didn't jump to line 683 because the condition on line 682 was never true

683 resolved_model: Final = llm_router.resolve_model_name_from_model_id(model_id_from_decoded) 

684 if resolved_model: 

685 data["model"] = resolved_model 

686 

687 processor: Final = ProxyBaseLLMRequestProcessing(data=data) 

688 try: 

689 response: object = await processor.base_process_llm_request( 

690 request=request, 

691 fastapi_response=fastapi_response, 

692 user_api_key_dict=user_api_key_dict, 

693 route_type="avideo_get_character", 

694 proxy_logging_obj=proxy_logging_obj, 

695 llm_router=llm_router, 

696 general_settings=general_settings, 

697 proxy_config=proxy_config, 

698 select_data_generator=select_data_generator, 

699 model=None, 

700 user_model=user_model, 

701 user_temperature=user_temperature, 

702 user_request_timeout=user_request_timeout, 

703 user_max_tokens=user_max_tokens, 

704 user_api_base=user_api_base, 

705 version=version, 

706 ) 

707 if original_requested_character_id.startswith("character_"): 

708 provider_for_encoding: Final = provider_from_id or custom_llm_provider or "openai" 

709 model_id_for_encoding: Final = model_id_from_decoded 

710 response = encode_character_id_in_response( 

711 response=response, 

712 custom_llm_provider=provider_for_encoding, 

713 model_id=model_id_for_encoding, 

714 ) 

715 return response 

716 except Exception as e: 

717 raise await processor._handle_llm_api_exception( 

718 e=e, 

719 user_api_key_dict=user_api_key_dict, 

720 proxy_logging_obj=proxy_logging_obj, 

721 version=version, 

722 ) 

723 

724 

725@router.post( 

726 "/v1/videos/edits", 

727 dependencies=[Depends(user_api_key_auth)], 

728 response_class=ORJSONResponse, 

729 tags=["videos"], 

730) 

731@router.post( 

732 "/videos/edits", 

733 dependencies=[Depends(user_api_key_auth)], 

734 response_class=ORJSONResponse, 

735 tags=["videos"], 

736) 

737async def video_edit( 

738 request: Request, 

739 fastapi_response: Response, 

740 user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), 

741): 

742 """ 

743 Create a video edit job. 

744 

745 Follows the OpenAI Videos API spec: 

746 https://platform.openai.com/docs/api-reference/videos/create-edit 

747 

748 Example: 

749 ```bash 

750 curl -X POST "http://localhost:4000/v1/videos/edits" \ 

751 -H "Authorization: Bearer sk-1234" \ 

752 -H "Content-Type: application/json" \ 

753 -d '{"prompt": "Make it brighter", "video": {"id": "video_123"}}' 

754 ``` 

755 """ 

756 from litellm.proxy.proxy_server import ( 

757 general_settings, 

758 llm_router, 

759 proxy_config, 

760 proxy_logging_obj, 

761 select_data_generator, 

762 user_api_base, 

763 user_max_tokens, 

764 user_model, 

765 user_request_timeout, 

766 user_temperature, 

767 version, 

768 ) 

769 

770 data: Final = await _read_request_body(request=request) 

771 uploaded_video: Final = data.pop("video", None) 

772 if isinstance(uploaded_video, StarletteUploadFile): 772 ↛ 773line 772 didn't jump to line 773 because the condition on line 772 was never true

773 video_files: Final = await batch_to_bytesio((uploaded_video,)) 

774 if video_files: 

775 data["video"] = video_files[0] 

776 data["video_id"] = "" 

777 else: 

778 data["video_id"] = video_reference_to_id(uploaded_video) 

779 

780 decoded: Final = decode_video_id_with_provider(data["video_id"]) 

781 provider_from_id: Final = decoded.get("custom_llm_provider") 

782 model_id_from_decoded: Final = decoded.get("model_id") 

783 

784 custom_llm_provider: Final = ( 

785 get_custom_llm_provider_from_request_headers(request=request) 

786 or get_custom_llm_provider_from_request_query(request=request) 

787 or get_custom_provider_from_data(data=data) 

788 or provider_from_id 

789 or "openai" 

790 ) 

791 data["custom_llm_provider"] = custom_llm_provider 

792 

793 if model_id_from_decoded and llm_router: 793 ↛ 794line 793 didn't jump to line 794 because the condition on line 793 was never true

794 resolved_model: Final = llm_router.resolve_model_name_from_model_id(model_id_from_decoded) 

795 if resolved_model: 

796 data["model"] = resolved_model 

797 

798 processor: Final = ProxyBaseLLMRequestProcessing(data=data) 

799 try: 

800 edited: Final[object] = await processor.base_process_llm_request( 

801 request=request, 

802 fastapi_response=fastapi_response, 

803 user_api_key_dict=user_api_key_dict, 

804 route_type="avideo_edit", 

805 proxy_logging_obj=proxy_logging_obj, 

806 llm_router=llm_router, 

807 general_settings=general_settings, 

808 proxy_config=proxy_config, 

809 select_data_generator=select_data_generator, 

810 model=None, 

811 user_model=user_model, 

812 user_temperature=user_temperature, 

813 user_request_timeout=user_request_timeout, 

814 user_max_tokens=user_max_tokens, 

815 user_api_base=user_api_base, 

816 version=version, 

817 ) 

818 except Exception as e: 

819 raise await processor._handle_llm_api_exception( 

820 e=e, 

821 user_api_key_dict=user_api_key_dict, 

822 proxy_logging_obj=proxy_logging_obj, 

823 version=version, 

824 ) 

825 else: 

826 return edited 

827 

828 

829@router.post( 

830 "/v1/videos/extensions", 

831 dependencies=[Depends(user_api_key_auth)], 

832 response_class=ORJSONResponse, 

833 tags=["videos"], 

834) 

835@router.post( 

836 "/videos/extensions", 

837 dependencies=[Depends(user_api_key_auth)], 

838 response_class=ORJSONResponse, 

839 tags=["videos"], 

840) 

841async def video_extension( 

842 request: Request, 

843 fastapi_response: Response, 

844 user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), 

845): 

846 """ 

847 Create a video extension. 

848 

849 Follows the OpenAI Videos API spec: 

850 https://platform.openai.com/docs/api-reference/videos/create-extension 

851 

852 Example: 

853 ```bash 

854 curl -X POST "http://localhost:4000/v1/videos/extensions" \ 

855 -H "Authorization: Bearer sk-1234" \ 

856 -H "Content-Type: application/json" \ 

857 -d '{"prompt": "Continue the scene", "seconds": "5", "video": {"id": "video_123"}}' 

858 ``` 

859 """ 

860 from litellm.proxy.proxy_server import ( 

861 general_settings, 

862 llm_router, 

863 proxy_config, 

864 proxy_logging_obj, 

865 select_data_generator, 

866 user_api_base, 

867 user_max_tokens, 

868 user_model, 

869 user_request_timeout, 

870 user_temperature, 

871 version, 

872 ) 

873 

874 data: Final = await _read_request_body(request=request) 

875 data["video_id"] = video_reference_to_id(data.pop("video", None)) 

876 

877 decoded: Final = decode_video_id_with_provider(data["video_id"]) 

878 provider_from_id: Final = decoded.get("custom_llm_provider") 

879 model_id_from_decoded: Final = decoded.get("model_id") 

880 

881 custom_llm_provider: Final = ( 

882 get_custom_llm_provider_from_request_headers(request=request) 

883 or get_custom_llm_provider_from_request_query(request=request) 

884 or get_custom_provider_from_data(data=data) 

885 or provider_from_id 

886 or "openai" 

887 ) 

888 data["custom_llm_provider"] = custom_llm_provider 

889 

890 if model_id_from_decoded and llm_router: 890 ↛ 891line 890 didn't jump to line 891 because the condition on line 890 was never true

891 resolved_model: Final = llm_router.resolve_model_name_from_model_id(model_id_from_decoded) 

892 if resolved_model: 

893 data["model"] = resolved_model 

894 

895 processor: Final = ProxyBaseLLMRequestProcessing(data=data) 

896 try: 

897 extended: Final[object] = await processor.base_process_llm_request( 

898 request=request, 

899 fastapi_response=fastapi_response, 

900 user_api_key_dict=user_api_key_dict, 

901 route_type="avideo_extension", 

902 proxy_logging_obj=proxy_logging_obj, 

903 llm_router=llm_router, 

904 general_settings=general_settings, 

905 proxy_config=proxy_config, 

906 select_data_generator=select_data_generator, 

907 model=None, 

908 user_model=user_model, 

909 user_temperature=user_temperature, 

910 user_request_timeout=user_request_timeout, 

911 user_max_tokens=user_max_tokens, 

912 user_api_base=user_api_base, 

913 version=version, 

914 ) 

915 except Exception as e: 

916 raise await processor._handle_llm_api_exception( 

917 e=e, 

918 user_api_key_dict=user_api_key_dict, 

919 proxy_logging_obj=proxy_logging_obj, 

920 version=version, 

921 ) 

922 else: 

923 return extended