diff --git a/docs/my-website/docs/providers/azure/videos.md b/docs/my-website/docs/providers/azure/videos.md index d088c63f710..188713d6335 100644 --- a/docs/my-website/docs/providers/azure/videos.md +++ b/docs/my-website/docs/providers/azure/videos.md @@ -54,7 +54,7 @@ print(f"Initial Status: {response.status}") while True: status_response = video_status( video_id=response.id, - model="azure/sora-2" + custom_llm_provider="azure" ) print(f"Current Status: {status_response.status}") @@ -70,7 +70,7 @@ while True: # Download video content when ready video_bytes = video_content( video_id=response.id, - model="azure/sora-2" + custom_llm_provider="azure" ) # Save to file @@ -244,7 +244,7 @@ def generate_and_download_video(prompt): # Step 3: Download video video_bytes = litellm.video_content( video_id=video_id, - model="azure/sora-2" + custom_llm_provider="azure" ) # Step 4: Save to file @@ -266,7 +266,7 @@ video_file = generate_and_download_video( response = litellm.video_remix( prompt="Make the cat jump higher", input_reference=open("path/to/image.jpg", "rb"), # Reference image as file object - model="azure/sora-2", + custom_llm_provider="azure" seconds="8" ) diff --git a/docs/my-website/docs/providers/openai/videos.md b/docs/my-website/docs/providers/openai/videos.md index 473279e60ef..06d0934b180 100644 --- a/docs/my-website/docs/providers/openai/videos.md +++ b/docs/my-website/docs/providers/openai/videos.md @@ -65,7 +65,7 @@ with open("generated_video.mp4", "wb") as f: # Download video content video_bytes = video_content( video_id="video_1234567890", - model="sora-2" + custom_llm_provider="openai" # Or use model="sora-2" ) # Save to file @@ -97,7 +97,7 @@ def generate_and_download_video(prompt): # Step 3: Download video video_bytes = litellm.video_content( video_id=video_id, - model="sora-2" + custom_llm_provider="openai" ) # Step 4: Save to file diff --git a/docs/my-website/docs/videos.md b/docs/my-website/docs/videos.md index 344a0f852df..96ff4c8190a 100644 --- a/docs/my-website/docs/videos.md +++ b/docs/my-website/docs/videos.md @@ -42,7 +42,7 @@ print(f"Initial Status: {response.status}") while True: status_response = video_status( video_id=response.id, - model="openai/sora-2" + custom_llm_provider="openai" ) print(f"Current Status: {status_response.status}") @@ -58,7 +58,7 @@ while True: # Download video content when ready video_bytes = video_content( video_id=response.id, - model="openai/sora-2" + custom_llm_provider="openai" ) # Save to file @@ -89,7 +89,7 @@ async def test_async_video(): while True: status_response = await avideo_status( video_id=response.id, - model="openai/sora-2" + custom_llm_provider="openai" ) print(f"Current Status: {status_response.status}") @@ -105,7 +105,7 @@ async def test_async_video(): # Download video content when ready video_bytes = await avideo_content( video_id=response.id, - model="openai/sora-2" + custom_llm_provider="openai" ) # Save to file @@ -123,7 +123,7 @@ from litellm import video_status # Check the status of a video generation status_response = video_status( video_id="video_1234567890", - model="openai/sora-2" + custom_llm_provider="openai" ) print(f"Video Status: {status_response.status}") @@ -253,27 +253,57 @@ curl --location 'http://localhost:4000/v1/videos' \ Test video status request ```bash +# Using custom-llm-provider header curl --location 'http://localhost:4000/v1/videos/video_id' \ --header 'Accept: application/json' \ ---header 'x-litellm-api-key: sk-1234' +--header 'x-litellm-api-key: sk-1234' \ +--header 'custom-llm-provider: azure' +# Or using query parameter +curl --location 'http://localhost:4000/v1/videos/video_id?custom_llm_provider=azure' \ +--header 'Accept: application/json' \ +--header 'x-litellm-api-key: sk-1234' ``` Test video retrieval request ```bash +# Using custom-llm-provider header curl --location 'http://localhost:4000/v1/videos/video_id/content' \ --header 'Accept: application/json' \ ---header 'x-litellm-api-key: sk-1234' +--header 'x-litellm-api-key: sk-1234' \ +--header 'custom-llm-provider: openai' \ +--output video.mp4 +# Or using query parameter +curl --location 'http://localhost:4000/v1/videos/video_id/content?custom_llm_provider=openai' \ +--header 'Accept: application/json' \ +--header 'x-litellm-api-key: sk-1234' \ +--output video.mp4 ``` Test video remix request ```bash -curl --location --request POST 'http://localhost:4000/v1/videos/string/remix' \ +# Using custom_llm_provider in request body +curl --location --request POST 'http://localhost:4000/v1/videos/video_id/remix' \ --header 'Accept: application/json' \ ---header 'x-litellm-api-key: sk-1234' +--header 'Content-Type: application/json' \ +--header 'x-litellm-api-key: sk-1234' \ +--data '{ + "prompt": "New remix instructions", + "custom_llm_provider": "azure" +}' + +# Or using custom-llm-provider header +curl --location --request POST 'http://localhost:4000/v1/videos/video_id/remix' \ +--header 'Accept: application/json' \ +--header 'Content-Type: application/json' \ +--header 'x-litellm-api-key: sk-1234' \ +--header 'custom-llm-provider: azure' \ +--data '{ + "prompt": "New remix instructions" +}' ``` Test Azure video generation request diff --git a/litellm/llms/base_llm/videos/transformation.py b/litellm/llms/base_llm/videos/transformation.py index 223b308dc08..7234093778c 100644 --- a/litellm/llms/base_llm/videos/transformation.py +++ b/litellm/llms/base_llm/videos/transformation.py @@ -111,7 +111,6 @@ class BaseVideoConfig(ABC): def transform_video_content_request( self, video_id: str, - model: str, api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, @@ -127,7 +126,6 @@ class BaseVideoConfig(ABC): @abstractmethod def transform_video_content_response( self, - model: str, raw_response: httpx.Response, logging_obj: LiteLLMLoggingObj, ) -> bytes: @@ -138,7 +136,6 @@ class BaseVideoConfig(ABC): self, video_id: str, prompt: str, - model: str, api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, @@ -155,7 +152,6 @@ class BaseVideoConfig(ABC): @abstractmethod def transform_video_remix_response( self, - model: str, raw_response: httpx.Response, logging_obj: LiteLLMLoggingObj, ) -> VideoObject: @@ -164,7 +160,6 @@ class BaseVideoConfig(ABC): @abstractmethod def transform_video_list_request( self, - model: str, api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, @@ -184,7 +179,6 @@ class BaseVideoConfig(ABC): @abstractmethod def transform_video_list_response( self, - model: str, raw_response: httpx.Response, logging_obj: LiteLLMLoggingObj, ) -> Dict[str,str]: @@ -194,7 +188,6 @@ class BaseVideoConfig(ABC): def transform_video_delete_request( self, video_id: str, - model: str, api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, @@ -210,7 +203,6 @@ class BaseVideoConfig(ABC): @abstractmethod def transform_video_delete_response( self, - model: str, raw_response: httpx.Response, logging_obj: LiteLLMLoggingObj, ) -> VideoObject: @@ -220,7 +212,6 @@ class BaseVideoConfig(ABC): def transform_video_status_retrieve_request( self, video_id: str, - model: str, api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, @@ -236,7 +227,6 @@ class BaseVideoConfig(ABC): @abstractmethod def transform_video_status_retrieve_response( self, - model: str, raw_response: httpx.Response, logging_obj: LiteLLMLoggingObj, ) -> VideoObject: diff --git a/litellm/llms/custom_httpx/llm_http_handler.py b/litellm/llms/custom_httpx/llm_http_handler.py index d3039dbefdb..b74747a55ae 100644 --- a/litellm/llms/custom_httpx/llm_http_handler.py +++ b/litellm/llms/custom_httpx/llm_http_handler.py @@ -4206,7 +4206,6 @@ class BaseLLMHTTPHandler: def video_content_handler( self, video_id: str, - model: str, video_content_provider_config: BaseVideoConfig, custom_llm_provider: str, litellm_params: GenericLiteLLMParams, @@ -4223,7 +4222,6 @@ class BaseLLMHTTPHandler: if _is_async: return self.async_video_content_handler( video_id=video_id, - model=model, video_content_provider_config=video_content_provider_config, custom_llm_provider=custom_llm_provider, litellm_params=litellm_params, @@ -4243,7 +4241,7 @@ class BaseLLMHTTPHandler: headers = video_content_provider_config.validate_environment( headers=extra_headers or {}, - model=model, + model="", api_key=api_key, ) @@ -4251,7 +4249,7 @@ class BaseLLMHTTPHandler: headers.update(extra_headers) api_base = video_content_provider_config.get_complete_url( - model=model, + model="", api_base=litellm_params.get("api_base", None), litellm_params=dict(litellm_params), ) @@ -4259,7 +4257,6 @@ class BaseLLMHTTPHandler: # Transform the request using the provider config url, params = video_content_provider_config.transform_video_content_request( video_id=video_id, - model=model, api_base=api_base, litellm_params=litellm_params, headers=headers, @@ -4275,7 +4272,6 @@ class BaseLLMHTTPHandler: # Transform the response using the provider config return video_content_provider_config.transform_video_content_response( - model=model, raw_response=response, logging_obj=logging_obj, ) @@ -4289,7 +4285,6 @@ class BaseLLMHTTPHandler: async def async_video_content_handler( self, video_id: str, - model: str, video_content_provider_config: BaseVideoConfig, custom_llm_provider: str, litellm_params: GenericLiteLLMParams, @@ -4312,7 +4307,7 @@ class BaseLLMHTTPHandler: headers = video_content_provider_config.validate_environment( headers=extra_headers or {}, - model=model, + model="", api_key=api_key, ) @@ -4320,7 +4315,7 @@ class BaseLLMHTTPHandler: headers.update(extra_headers) api_base = video_content_provider_config.get_complete_url( - model=model, + model="", api_base=litellm_params.get("api_base", None), litellm_params=dict(litellm_params), ) @@ -4328,7 +4323,6 @@ class BaseLLMHTTPHandler: # Transform the request using the provider config url, params = video_content_provider_config.transform_video_content_request( video_id=video_id, - model=model, api_base=api_base, litellm_params=litellm_params, headers=headers, @@ -4344,7 +4338,6 @@ class BaseLLMHTTPHandler: # Transform the response using the provider config return video_content_provider_config.transform_video_content_response( - model=model, raw_response=response, logging_obj=logging_obj, ) @@ -4359,7 +4352,6 @@ class BaseLLMHTTPHandler: self, video_id: str, prompt: str, - model: str, video_remix_provider_config: BaseVideoConfig, custom_llm_provider: str, litellm_params, @@ -4380,7 +4372,6 @@ class BaseLLMHTTPHandler: return self.async_video_remix_handler( video_id=video_id, prompt=prompt, - model=model, video_remix_provider_config=video_remix_provider_config, custom_llm_provider=custom_llm_provider, litellm_params=litellm_params, @@ -4403,14 +4394,14 @@ class BaseLLMHTTPHandler: headers = video_remix_provider_config.validate_environment( api_key=api_key, headers=extra_headers or {}, - model=model, + model="", ) if extra_headers: headers.update(extra_headers) api_base = video_remix_provider_config.get_complete_url( - model=model, + model="", api_base=litellm_params.get("api_base", None), litellm_params=dict(litellm_params), ) @@ -4419,7 +4410,6 @@ class BaseLLMHTTPHandler: url, data = video_remix_provider_config.transform_video_remix_request( video_id=video_id, prompt=prompt, - model=model, api_base=api_base, litellm_params=litellm_params, headers=headers, @@ -4447,7 +4437,6 @@ class BaseLLMHTTPHandler: ) return video_remix_provider_config.transform_video_remix_response( - model=model, raw_response=response, logging_obj=logging_obj, ) @@ -4462,7 +4451,6 @@ class BaseLLMHTTPHandler: self, video_id: str, prompt: str, - model: str, video_remix_provider_config: BaseVideoConfig, custom_llm_provider: str, litellm_params, @@ -4487,14 +4475,14 @@ class BaseLLMHTTPHandler: headers = video_remix_provider_config.validate_environment( api_key=api_key, headers=extra_headers or {}, - model=model, + model="", ) if extra_headers: headers.update(extra_headers) api_base = video_remix_provider_config.get_complete_url( - model=model, + model="", api_base=litellm_params.get("api_base", None), litellm_params=dict(litellm_params), ) @@ -4503,7 +4491,6 @@ class BaseLLMHTTPHandler: url, data = video_remix_provider_config.transform_video_remix_request( video_id=video_id, prompt=prompt, - model=model, api_base=api_base, litellm_params=litellm_params, headers=headers, @@ -4531,7 +4518,6 @@ class BaseLLMHTTPHandler: ) return video_remix_provider_config.transform_video_remix_response( - model=model, raw_response=response, logging_obj=logging_obj, ) @@ -4547,7 +4533,6 @@ class BaseLLMHTTPHandler: after: Optional[str], limit: Optional[int], order: Optional[str], - model: str, video_list_provider_config, custom_llm_provider: str, litellm_params, @@ -4567,7 +4552,6 @@ class BaseLLMHTTPHandler: after=after, limit=limit, order=order, - model=model, video_list_provider_config=video_list_provider_config, custom_llm_provider=custom_llm_provider, litellm_params=litellm_params, @@ -4587,7 +4571,6 @@ class BaseLLMHTTPHandler: after=after, limit=limit, order=order, - model=model, video_list_provider_config=video_list_provider_config, custom_llm_provider=custom_llm_provider, litellm_params=litellm_params, @@ -4604,7 +4587,6 @@ class BaseLLMHTTPHandler: after: Optional[str], limit: Optional[int], order: Optional[str], - model: str, video_list_provider_config: BaseVideoConfig, custom_llm_provider: str, litellm_params, @@ -4629,21 +4611,20 @@ class BaseLLMHTTPHandler: headers = video_list_provider_config.validate_environment( api_key=api_key, headers=extra_headers or {}, - model=model, + model="", ) if extra_headers: headers.update(extra_headers) api_base = video_list_provider_config.get_complete_url( - model=model, + model="", api_base=litellm_params.get("api_base", None), litellm_params=dict(litellm_params), ) # Transform the request using the provider config url, params = video_list_provider_config.transform_video_list_request( - model=model, api_base=api_base, litellm_params=litellm_params, headers=headers, @@ -4672,7 +4653,6 @@ class BaseLLMHTTPHandler: ) return video_list_provider_config.transform_video_list_response( - model=model, raw_response=response, logging_obj=logging_obj, ) @@ -4686,7 +4666,6 @@ class BaseLLMHTTPHandler: async def async_video_delete_handler( self, video_id: str, - model: str, video_delete_provider_config: BaseVideoConfig, custom_llm_provider: str, litellm_params, @@ -4710,14 +4689,14 @@ class BaseLLMHTTPHandler: headers = video_delete_provider_config.validate_environment( api_key=api_key, headers=extra_headers or {}, - model=model, + model="", ) if extra_headers: headers.update(extra_headers) api_base = video_delete_provider_config.get_complete_url( - model=model, + model="", api_base=litellm_params.get("api_base", None), litellm_params=dict(litellm_params), ) @@ -4725,7 +4704,6 @@ class BaseLLMHTTPHandler: # Transform the request using the provider config url, data = video_delete_provider_config.transform_video_delete_request( video_id=video_id, - model=model, api_base=api_base, litellm_params=litellm_params, headers=headers, @@ -4750,7 +4728,6 @@ class BaseLLMHTTPHandler: ) return video_delete_provider_config.transform_video_delete_response( - model=model, raw_response=response, logging_obj=logging_obj, ) @@ -4764,7 +4741,6 @@ class BaseLLMHTTPHandler: def video_status_handler( self, video_id: str, - model: str, video_status_provider_config: BaseVideoConfig, custom_llm_provider: str, litellm_params, @@ -4784,7 +4760,6 @@ class BaseLLMHTTPHandler: # Return the async coroutine if called with _is_async=True return self.async_video_status_handler( video_id=video_id, - model=model, video_status_provider_config=video_status_provider_config, custom_llm_provider=custom_llm_provider, litellm_params=litellm_params, @@ -4807,27 +4782,24 @@ class BaseLLMHTTPHandler: headers = video_status_provider_config.validate_environment( api_key=api_key, headers=extra_headers or {}, - model=model, + model="", ) if extra_headers: headers.update(extra_headers) api_base = video_status_provider_config.get_complete_url( - model=model, + model="", api_base=litellm_params.get("api_base", None), litellm_params=dict(litellm_params), ) # Transform the request using the provider config - url, data = ( - video_status_provider_config.transform_video_status_retrieve_request( - video_id=video_id, - model=model, - api_base=api_base, - litellm_params=litellm_params, - headers=headers, - ) + url, data = video_status_provider_config.transform_video_status_retrieve_request( + video_id=video_id, + api_base=api_base, + litellm_params=litellm_params, + headers=headers, ) ## LOGGING @@ -4846,13 +4818,9 @@ class BaseLLMHTTPHandler: url=url, headers=headers, ) - - return ( - video_status_provider_config.transform_video_status_retrieve_response( - model=model, - raw_response=response, - logging_obj=logging_obj, - ) + return video_status_provider_config.transform_video_status_retrieve_response( + raw_response=response, + logging_obj=logging_obj, ) except Exception as e: @@ -4864,7 +4832,6 @@ class BaseLLMHTTPHandler: async def async_video_status_handler( self, video_id: str, - model: str, video_status_provider_config: BaseVideoConfig, custom_llm_provider: str, litellm_params, @@ -4889,27 +4856,24 @@ class BaseLLMHTTPHandler: headers = video_status_provider_config.validate_environment( api_key=api_key, headers=extra_headers or {}, - model=model, + model="", ) if extra_headers: headers.update(extra_headers) api_base = video_status_provider_config.get_complete_url( - model=model, + model="", api_base=litellm_params.get("api_base", None), litellm_params=dict(litellm_params), ) # Transform the request using the provider config - url, data = ( - video_status_provider_config.transform_video_status_retrieve_request( - video_id=video_id, - model=model, - api_base=api_base, - litellm_params=litellm_params, - headers=headers, - ) + url, data = video_status_provider_config.transform_video_status_retrieve_request( + video_id=video_id, + api_base=api_base, + litellm_params=litellm_params, + headers=headers, ) ## LOGGING @@ -4928,13 +4892,9 @@ class BaseLLMHTTPHandler: url=url, headers=headers, ) - - return ( - video_status_provider_config.transform_video_status_retrieve_response( - model=model, - raw_response=response, - logging_obj=logging_obj, - ) + return video_status_provider_config.transform_video_status_retrieve_response( + raw_response=response, + logging_obj=logging_obj, ) except Exception as e: diff --git a/litellm/llms/openai/videos/transformation.py b/litellm/llms/openai/videos/transformation.py index 09c7787a28b..c573f3b59b0 100644 --- a/litellm/llms/openai/videos/transformation.py +++ b/litellm/llms/openai/videos/transformation.py @@ -165,7 +165,6 @@ class OpenAIVideoConfig(BaseVideoConfig): def transform_video_content_request( self, video_id: str, - model: str, api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, @@ -188,7 +187,6 @@ class OpenAIVideoConfig(BaseVideoConfig): self, video_id: str, prompt: str, - model: str, api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, @@ -214,7 +212,6 @@ class OpenAIVideoConfig(BaseVideoConfig): def transform_video_content_response( self, - model: str, raw_response: httpx.Response, logging_obj: LiteLLMLoggingObj, ) -> bytes: @@ -227,7 +224,6 @@ class OpenAIVideoConfig(BaseVideoConfig): def transform_video_remix_response( self, - model: str, raw_response: httpx.Response, logging_obj: LiteLLMLoggingObj, ) -> VideoObject: @@ -255,7 +251,6 @@ class OpenAIVideoConfig(BaseVideoConfig): def transform_video_list_request( self, - model: str, api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, @@ -290,7 +285,6 @@ class OpenAIVideoConfig(BaseVideoConfig): def transform_video_list_response( self, - model: str, raw_response: httpx.Response, logging_obj: LiteLLMLoggingObj, ) -> Dict[str,str]: @@ -299,7 +293,6 @@ class OpenAIVideoConfig(BaseVideoConfig): def transform_video_delete_request( self, video_id: str, - model: str, api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, @@ -320,7 +313,6 @@ class OpenAIVideoConfig(BaseVideoConfig): def transform_video_delete_response( self, - model: str, raw_response: httpx.Response, logging_obj: LiteLLMLoggingObj, ) -> VideoObject: @@ -337,7 +329,6 @@ class OpenAIVideoConfig(BaseVideoConfig): def transform_video_status_retrieve_request( self, video_id: str, - model: str, api_base: str, litellm_params: GenericLiteLLMParams, headers: dict, @@ -355,7 +346,6 @@ class OpenAIVideoConfig(BaseVideoConfig): def transform_video_status_retrieve_response( self, - model: str, raw_response: httpx.Response, logging_obj: LiteLLMLoggingObj, ) -> VideoObject: diff --git a/litellm/proxy/route_llm_request.py b/litellm/proxy/route_llm_request.py index 735cc955ef9..965fe5d14b2 100644 --- a/litellm/proxy/route_llm_request.py +++ b/litellm/proxy/route_llm_request.py @@ -152,6 +152,15 @@ async def route_request( models = [model.strip() for model in data.pop("model").split(",")] return llm_router.abatch_completion(models=models, **data) elif llm_router is not None: + if route_type in [ + "avideo_list", + "avideo_status", + "avideo_content", + "avideo_remix", + ] and (data.get("model") is None or data.get("model") == ""): + # These video endpoints don't need a model, use custom_llm_provider + return getattr(litellm, f"{route_type}")(**data) + team_model_name = ( llm_router.map_team_model(data["model"], team_id) if team_id is not None diff --git a/litellm/proxy/video_endpoints/endpoints.py b/litellm/proxy/video_endpoints/endpoints.py index cd1c8c40d79..9cd4a698035 100644 --- a/litellm/proxy/video_endpoints/endpoints.py +++ b/litellm/proxy/video_endpoints/endpoints.py @@ -3,13 +3,18 @@ import orjson from fastapi import APIRouter, Depends, Request, Response, UploadFile, File from fastapi.responses import ORJSONResponse -from typing import Optional +from typing import Optional, Dict, Any from litellm.proxy._types import * from litellm.proxy.auth.user_api_key_auth import UserAPIKeyAuth, user_api_key_auth from litellm.proxy.common_request_processing import ProxyBaseLLMRequestProcessing from litellm.proxy.image_endpoints.endpoints import batch_to_bytesio from litellm.proxy.common_utils.http_parsing_utils import _read_request_body +from litellm.proxy.common_utils.openai_endpoint_utils import ( + get_custom_llm_provider_from_request_body, + get_custom_llm_provider_from_request_headers, + get_custom_llm_provider_from_request_query, +) router = APIRouter() @@ -145,8 +150,16 @@ async def video_list( # Read query parameters query_params = dict(request.query_params) - data = {"query_params": query_params} + data: Dict[str, Any] = {"query_params": query_params} + # Extract custom_llm_provider from headers, query params, or body + custom_llm_provider = ( + get_custom_llm_provider_from_request_headers(request=request) + or get_custom_llm_provider_from_request_query(request=request) + or await get_custom_llm_provider_from_request_body(request=request) + ) + if custom_llm_provider: + data["custom_llm_provider"] = custom_llm_provider # Process request using ProxyBaseLLMRequestProcessing processor = ProxyBaseLLMRequestProcessing(data=data) try: @@ -222,7 +235,18 @@ async def video_status( ) # Create data with video_id - data = {"video_id": video_id} + data: Dict[str, Any] = {"video_id": video_id} + + # Extract custom_llm_provider from headers, query params, or body + custom_llm_provider = ( + get_custom_llm_provider_from_request_headers(request=request) + or get_custom_llm_provider_from_request_query(request=request) + or await get_custom_llm_provider_from_request_body(request=request) + or "openai" + + ) + if custom_llm_provider: + data["custom_llm_provider"] = custom_llm_provider # Process request using ProxyBaseLLMRequestProcessing processor = ProxyBaseLLMRequestProcessing(data=data) @@ -300,7 +324,16 @@ async def video_content( ) # Create data with video_id - data = {"video_id": video_id} + data: Dict[str, Any] = {"video_id": video_id} + + # Extract custom_llm_provider from headers, query params, or body + custom_llm_provider = ( + get_custom_llm_provider_from_request_headers(request=request) + or get_custom_llm_provider_from_request_query(request=request) + or await get_custom_llm_provider_from_request_body(request=request) + ) + if custom_llm_provider: + data["custom_llm_provider"] = custom_llm_provider # Process request using ProxyBaseLLMRequestProcessing processor = ProxyBaseLLMRequestProcessing(data=data) @@ -395,6 +428,15 @@ async def video_remix( data = orjson.loads(body) data["video_id"] = video_id + # Extract custom_llm_provider from headers, query params, or body + custom_llm_provider = ( + get_custom_llm_provider_from_request_headers(request=request) + or get_custom_llm_provider_from_request_query(request=request) + or data.get("custom_llm_provider") + ) + if custom_llm_provider: + data["custom_llm_provider"] = custom_llm_provider + # Process request using ProxyBaseLLMRequestProcessing processor = ProxyBaseLLMRequestProcessing(data=data) try: diff --git a/litellm/utils.py b/litellm/utils.py index 8c0b2b4bb3b..3a22b8ec12b 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -7663,7 +7663,7 @@ class ProviderConfigManager: @staticmethod def get_provider_video_config( - model: str, + model: Optional[str], provider: LlmProviders, ) -> Optional[BaseVideoConfig]: if LlmProviders.OPENAI == provider: diff --git a/litellm/videos/main.py b/litellm/videos/main.py index 9f99c47ca4e..cbc59169a7a 100644 --- a/litellm/videos/main.py +++ b/litellm/videos/main.py @@ -208,7 +208,7 @@ def video_generation( # noqa: PLR0915 ) if video_generation_provider_config is None: - raise ValueError(f"image edit is not supported for {custom_llm_provider}") + raise ValueError(f"video generation is not supported for {custom_llm_provider}") local_vars.update(kwargs) # Get VideoGenerationOptionalRequestParams with only valid parameters @@ -216,7 +216,7 @@ def video_generation( # noqa: PLR0915 VideoGenerationRequestUtils.get_requested_video_generation_optional_param(local_vars) ) - # Get optional parameters for the responses API + # Get optional parameters for the video generation API video_generation_request_params: Dict = ( VideoGenerationRequestUtils.get_optional_params_video_generation( model=model, @@ -258,7 +258,7 @@ def video_generation( # noqa: PLR0915 except Exception as e: raise litellm.exception_type( - model=model, + model=model or DEFAULT_VIDEO_ENDPOINT_MODEL, custom_llm_provider=custom_llm_provider, original_exception=e, completion_kwargs=local_vars, @@ -269,7 +269,6 @@ def video_generation( # noqa: PLR0915 @client def video_content( video_id: str, - model: Optional[str] = None, api_base: Optional[str] = None, timeout: Optional[float] = None, custom_llm_provider: Optional[str] = None, @@ -288,7 +287,6 @@ def video_content( Args: video_id (str): The identifier of the video whose content to download. - model (Optional[str]): The model to use. If not provided, will be auto-detected. api_key (Optional[str]): The API key to use for authentication. api_base (Optional[str]): The base URL for the API. timeout (Optional[float]): The timeout for the request in seconds. @@ -322,17 +320,17 @@ def video_content( litellm_call_id: Optional[str] = kwargs.get("litellm_call_id", None) _is_async = kwargs.pop("async_call", False) is True + # Ensure custom_llm_provider is not None - default to openai if not provided + if custom_llm_provider is None: + custom_llm_provider = "openai" + # get llm provider logic litellm_params = GenericLiteLLMParams(**kwargs) - model, custom_llm_provider, _, _ = get_llm_provider( - model=model or "sora-2", # Default model for video content - custom_llm_provider=custom_llm_provider, - ) # get provider config video_provider_config: Optional[BaseVideoConfig] = ( ProviderConfigManager.get_provider_video_config( - model=model, + model=None, provider=litellm.LlmProviders(custom_llm_provider), ) ) @@ -349,7 +347,7 @@ def video_content( # Pre Call logging litellm_logging_obj.update_environment_variables( - model=model, + model="", user=kwargs.get("user"), optional_params=dict(video_content_request_params), litellm_params={ @@ -362,7 +360,6 @@ def video_content( # Call the handler with _is_async flag instead of directly calling the async handler return base_llm_http_handler.video_content_handler( video_id=video_id, - model=model, video_content_provider_config=video_provider_config, custom_llm_provider=custom_llm_provider, litellm_params=litellm_params, @@ -375,7 +372,7 @@ def video_content( except Exception as e: raise litellm.exception_type( - model=model, + model="", custom_llm_provider=custom_llm_provider, original_exception=e, completion_kwargs=local_vars, @@ -387,7 +384,6 @@ def video_content( @client async def avideo_content( video_id: str, - model: Optional[str] = None, api_key: Optional[str] = None, api_base: Optional[str] = None, timeout: Optional[float] = None, @@ -404,7 +400,6 @@ async def avideo_content( Parameters: - `video_id` (str): The identifier of the video whose content to download - - `model` (Optional[str]): The model to use. If not provided, will be auto-detected - `api_key` (Optional[str]): The API key to use for authentication - `api_base` (Optional[str]): The base URL for the API - `timeout` (Optional[float]): The timeout for the request in seconds @@ -422,16 +417,14 @@ async def avideo_content( loop = asyncio.get_event_loop() kwargs["async_call"] = True - # get custom llm provider so we can use this for mapping exceptions + # Ensure custom_llm_provider is not None - default to openai if not provided + # Video content endpoints don't require a model parameter if custom_llm_provider is None: - _, custom_llm_provider, _, _ = litellm.get_llm_provider( - model=model or DEFAULT_VIDEO_ENDPOINT_MODEL, api_base=api_base - ) + custom_llm_provider = "openai" func = partial( video_content, video_id=video_id, - model=model, api_key=api_key, api_base=api_base, timeout=timeout, @@ -454,7 +447,7 @@ async def avideo_content( return response except Exception as e: raise litellm.exception_type( - model=model, + model="", custom_llm_provider=custom_llm_provider, original_exception=e, completion_kwargs=local_vars, @@ -466,7 +459,6 @@ async def avideo_content( async def avideo_remix( video_id: str, prompt: str, - model: Optional[str] = None, timeout=600, # default to 10 minutes custom_llm_provider=None, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -482,7 +474,6 @@ async def avideo_remix( Parameters: - `video_id` (str): The identifier of the completed video to remix - `prompt` (str): Updated text prompt that directs the remix generation - - `model` (Optional[str]): The video generation model to use - `timeout` (int): Request timeout in seconds - `custom_llm_provider` (Optional[str]): The LLM provider to use - `extra_headers` (Optional[Dict[str, Any]]): Additional headers @@ -498,17 +489,10 @@ async def avideo_remix( loop = asyncio.get_event_loop() kwargs["async_call"] = True - # get custom llm provider so we can use this for mapping exceptions - if custom_llm_provider is None: - _, custom_llm_provider, _, _ = litellm.get_llm_provider( - model=model or DEFAULT_VIDEO_ENDPOINT_MODEL, api_base=local_vars.get("api_base", None) - ) - func = partial( video_remix, video_id=video_id, prompt=prompt, - model=model, timeout=timeout, custom_llm_provider=custom_llm_provider, extra_headers=extra_headers, @@ -529,7 +513,7 @@ async def avideo_remix( return response except Exception as e: raise litellm.exception_type( - model=model, + model="", custom_llm_provider=custom_llm_provider, original_exception=e, completion_kwargs=local_vars, @@ -544,7 +528,6 @@ async def avideo_remix( def video_remix( video_id: str, prompt: str, - model: Optional[str] = None, timeout=600, # default to 10 minutes api_key: Optional[str] = None, api_base: Optional[str] = None, @@ -561,7 +544,6 @@ def video_remix( def video_remix( video_id: str, prompt: str, - model: Optional[str] = None, timeout=600, # default to 10 minutes api_key: Optional[str] = None, api_base: Optional[str] = None, @@ -580,7 +562,6 @@ def video_remix( def video_remix( # noqa: PLR0915 video_id: str, prompt: str, - model: Optional[str] = None, timeout=600, # default to 10 minutes custom_llm_provider=None, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -613,17 +594,17 @@ def video_remix( # noqa: PLR0915 response = VideoObject(**mock_response) return response + # Ensure custom_llm_provider is not None - default to openai if not provided + if custom_llm_provider is None: + custom_llm_provider = "openai" + # get llm provider logic litellm_params = GenericLiteLLMParams(**kwargs) - model, custom_llm_provider, _, _ = get_llm_provider( - model=model or DEFAULT_VIDEO_ENDPOINT_MODEL, - custom_llm_provider=custom_llm_provider, - ) # get provider config video_remix_provider_config: Optional[BaseVideoConfig] = ( ProviderConfigManager.get_provider_video_config( - model=model, + model=None, provider=litellm.LlmProviders(custom_llm_provider), ) ) @@ -640,7 +621,7 @@ def video_remix( # noqa: PLR0915 # Pre Call logging litellm_logging_obj.update_environment_variables( - model=model, + model="", user=kwargs.get("user"), optional_params=dict(video_remix_request_params), litellm_params={ @@ -657,7 +638,6 @@ def video_remix( # noqa: PLR0915 return base_llm_http_handler.video_remix_handler( video_id=video_id, prompt=prompt, - model=model, video_remix_provider_config=video_remix_provider_config, custom_llm_provider=custom_llm_provider, litellm_params=litellm_params, @@ -671,7 +651,7 @@ def video_remix( # noqa: PLR0915 except Exception as e: raise litellm.exception_type( - model=model, + model="", custom_llm_provider=custom_llm_provider, original_exception=e, completion_kwargs=local_vars, @@ -685,7 +665,7 @@ async def avideo_list( after: Optional[str] = None, limit: Optional[int] = None, order: Optional[str] = None, - model: Optional[str] = None, + api_key: Optional[str] = None, timeout=600, # default to 10 minutes custom_llm_provider=None, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -702,7 +682,7 @@ async def avideo_list( - `after` (Optional[str]): Identifier for the last item from the previous pagination request - `limit` (Optional[int]): Number of items to retrieve - `order` (Optional[str]): Sort order of results by timestamp. Use asc for ascending order or desc for descending order - - `model` (Optional[str]): The video generation model to use + - `api_key` (Optional[str]): The API key to use for authentication - `timeout` (int): Request timeout in seconds - `custom_llm_provider` (Optional[str]): The LLM provider to use - `extra_headers` (Optional[Dict[str, Any]]): Additional headers @@ -721,7 +701,7 @@ async def avideo_list( # get custom llm provider so we can use this for mapping exceptions if custom_llm_provider is None: _, custom_llm_provider, _, _ = litellm.get_llm_provider( - model=model or DEFAULT_VIDEO_ENDPOINT_MODEL, api_base=local_vars.get("api_base", None) + model="", api_base=local_vars.get("api_base", None) ) func = partial( @@ -729,7 +709,7 @@ async def avideo_list( after=after, limit=limit, order=order, - model=model, + api_key=api_key, timeout=timeout, custom_llm_provider=custom_llm_provider, extra_headers=extra_headers, @@ -750,7 +730,7 @@ async def avideo_list( return response except Exception as e: raise litellm.exception_type( - model=model, + model="", custom_llm_provider=custom_llm_provider, original_exception=e, completion_kwargs=local_vars, @@ -766,7 +746,6 @@ def video_list( after: Optional[str] = None, limit: Optional[int] = None, order: Optional[str] = None, - model: Optional[str] = None, timeout=600, # default to 10 minutes api_key: Optional[str] = None, api_base: Optional[str] = None, @@ -784,7 +763,6 @@ def video_list( after: Optional[str] = None, limit: Optional[int] = None, order: Optional[str] = None, - model: Optional[str] = None, timeout=600, # default to 10 minutes api_key: Optional[str] = None, api_base: Optional[str] = None, @@ -804,7 +782,6 @@ def video_list( # noqa: PLR0915 after: Optional[str] = None, limit: Optional[int] = None, order: Optional[str] = None, - model: Optional[str] = None, timeout=600, # default to 10 minutes custom_llm_provider=None, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -835,17 +812,17 @@ def video_list( # noqa: PLR0915 mock_response = json.loads(mock_response) return [VideoObject(**item) for item in mock_response] + # Ensure custom_llm_provider is not None - default to openai if not provided + if custom_llm_provider is None: + custom_llm_provider = "openai" + # get llm provider logic litellm_params = GenericLiteLLMParams(**kwargs) - model, custom_llm_provider, _, _ = get_llm_provider( - model=model or DEFAULT_VIDEO_ENDPOINT_MODEL, - custom_llm_provider=custom_llm_provider, - ) # get provider config video_list_provider_config: Optional[BaseVideoConfig] = ( ProviderConfigManager.get_provider_video_config( - model=model, + model=None, provider=litellm.LlmProviders(custom_llm_provider), ) ) @@ -863,7 +840,7 @@ def video_list( # noqa: PLR0915 # Pre Call logging litellm_logging_obj.update_environment_variables( - model=model, + model="", user=kwargs.get("user"), optional_params=dict(video_list_request_params), litellm_params={ @@ -881,7 +858,6 @@ def video_list( # noqa: PLR0915 after=after, limit=limit, order=order, - model=model, video_list_provider_config=video_list_provider_config, custom_llm_provider=custom_llm_provider, litellm_params=litellm_params, @@ -895,7 +871,7 @@ def video_list( # noqa: PLR0915 except Exception as e: raise litellm.exception_type( - model=model, + model="", custom_llm_provider=custom_llm_provider, original_exception=e, completion_kwargs=local_vars, @@ -907,7 +883,6 @@ def video_list( # noqa: PLR0915 @client async def avideo_status( video_id: str, - model: Optional[str] = None, timeout=600, # default to 10 minutes custom_llm_provider=None, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -938,16 +913,10 @@ async def avideo_status( loop = asyncio.get_event_loop() kwargs["async_call"] = True - # get custom llm provider so we can use this for mapping exceptions - if custom_llm_provider is None: - _, custom_llm_provider, _, _ = litellm.get_llm_provider( - model=model or DEFAULT_VIDEO_ENDPOINT_MODEL, api_base=local_vars.get("api_base", None) - ) func = partial( video_status, video_id=video_id, - model=model, timeout=timeout, custom_llm_provider=custom_llm_provider, extra_headers=extra_headers, @@ -968,7 +937,7 @@ async def avideo_status( return response except Exception as e: raise litellm.exception_type( - model=model, + model="", custom_llm_provider=custom_llm_provider, original_exception=e, completion_kwargs=local_vars, @@ -982,7 +951,6 @@ async def avideo_status( @overload def video_status( video_id: str, - model: Optional[str] = None, timeout=600, # default to 10 minutes api_key: Optional[str] = None, api_base: Optional[str] = None, @@ -998,7 +966,6 @@ def video_status( @overload def video_status( video_id: str, - model: Optional[str] = None, timeout=600, # default to 10 minutes api_key: Optional[str] = None, api_base: Optional[str] = None, @@ -1016,7 +983,6 @@ def video_status( @client def video_status( # noqa: PLR0915 video_id: str, - model: Optional[str] = None, timeout=600, # default to 10 minutes custom_llm_provider=None, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -1034,7 +1000,6 @@ def video_status( # noqa: PLR0915 Args: video_id (str): The identifier of the video whose status to retrieve. - model (Optional[str]): The model to use. If not provided, will be auto-detected. timeout (int): The timeout for the request in seconds. custom_llm_provider (Optional[str]): The LLM provider to use. If not provided, will be auto-detected. extra_headers (Optional[Dict[str, Any]]): Additional headers to include in the request. @@ -1073,17 +1038,17 @@ def video_status( # noqa: PLR0915 response = VideoObject(**mock_response) return response + # Ensure custom_llm_provider is not None - default to openai if not provided + if custom_llm_provider is None: + custom_llm_provider = "openai" + # get llm provider logic litellm_params = GenericLiteLLMParams(**kwargs) - model, custom_llm_provider, _, _ = get_llm_provider( - model=model or DEFAULT_VIDEO_ENDPOINT_MODEL, - custom_llm_provider=custom_llm_provider, - ) # get provider config video_status_provider_config: Optional[BaseVideoConfig] = ( ProviderConfigManager.get_provider_video_config( - model=model, + model=None, provider=litellm.LlmProviders(custom_llm_provider), ) ) @@ -1099,7 +1064,7 @@ def video_status( # noqa: PLR0915 # Pre Call logging litellm_logging_obj.update_environment_variables( - model=model, + model="", user=kwargs.get("user"), optional_params=dict(video_status_request_params), litellm_params={ @@ -1115,7 +1080,6 @@ def video_status( # noqa: PLR0915 # Call the handler with _is_async flag instead of directly calling the async handler return base_llm_http_handler.video_status_handler( video_id=video_id, - model=model, video_status_provider_config=video_status_provider_config, custom_llm_provider=custom_llm_provider, litellm_params=litellm_params, @@ -1129,7 +1093,7 @@ def video_status( # noqa: PLR0915 except Exception as e: raise litellm.exception_type( - model=model, + model="", custom_llm_provider=custom_llm_provider, original_exception=e, completion_kwargs=local_vars, diff --git a/tests/test_litellm/llms/azure/videos/test_azure_video_transformation.py b/tests/test_litellm/llms/azure/videos/test_azure_video_transformation.py index dd59461fdc5..14bf0064e61 100644 --- a/tests/test_litellm/llms/azure/videos/test_azure_video_transformation.py +++ b/tests/test_litellm/llms/azure/videos/test_azure_video_transformation.py @@ -183,7 +183,6 @@ class TestAzureVideoConfig: logging_obj = MagicMock() result = self.config.transform_video_remix_response( - model=self.model, raw_response=mock_response, logging_obj=logging_obj ) @@ -208,7 +207,6 @@ class TestAzureVideoConfig: logging_obj = MagicMock() result = self.config.transform_video_delete_response( - model=self.model, raw_response=mock_response, logging_obj=logging_obj ) @@ -226,7 +224,6 @@ class TestAzureVideoConfig: logging_obj = MagicMock() result = self.config.transform_video_content_response( - model=self.model, raw_response=mock_response, logging_obj=logging_obj ) @@ -374,7 +371,6 @@ class TestAzureVideoConfig: logging_obj = MagicMock() result = self.config.transform_video_remix_response( - model=self.model, raw_response=mock_response, logging_obj=logging_obj ) diff --git a/tests/test_litellm/test_video_generation.py b/tests/test_litellm/test_video_generation.py index 56f4f680c27..6007201a676 100644 --- a/tests/test_litellm/test_video_generation.py +++ b/tests/test_litellm/test_video_generation.py @@ -494,7 +494,6 @@ class TestVideoGeneration: # Test request transformation url, data = config.transform_video_status_retrieve_request( video_id="video_123", - model="sora-2", api_base="https://api.openai.com/v1/videos", litellm_params=MagicMock(), headers={} @@ -522,7 +521,6 @@ class TestVideoGeneration: } response = config.transform_video_status_retrieve_response( - model="sora-2", raw_response=mock_http_response, logging_obj=MagicMock() ) @@ -655,7 +653,6 @@ class TestVideoGeneration: for api_base, video_id, expected_url in test_cases: url, data = config.transform_video_status_retrieve_request( video_id=video_id, - model="sora-2", api_base=api_base, litellm_params=MagicMock(), headers={}