mirror of
https://github.com/tiennm99/litellm.git
synced 2026-08-10 16:22:17 +00:00
fix(videos): pass api_key from litellm_params to video remix handlers (#21965)
video_remix_handler and async_video_remix_handler were not falling back to litellm_params.api_key when the api_key parameter was None, causing Authorization: Bearer None to be sent to the provider. This matches the pattern already used by async_video_generation_handler.
This commit is contained in:
@@ -5602,7 +5602,7 @@ class BaseLLMHTTPHandler:
|
||||
sync_httpx_client = client
|
||||
|
||||
headers = video_remix_provider_config.validate_environment(
|
||||
api_key=api_key,
|
||||
api_key=api_key or litellm_params.get("api_key", None),
|
||||
headers=extra_headers or {},
|
||||
model="",
|
||||
)
|
||||
@@ -5684,7 +5684,7 @@ class BaseLLMHTTPHandler:
|
||||
async_httpx_client = client
|
||||
|
||||
headers = video_remix_provider_config.validate_environment(
|
||||
api_key=api_key,
|
||||
api_key=api_key or litellm_params.get("api_key", None),
|
||||
headers=extra_headers or {},
|
||||
model="",
|
||||
)
|
||||
|
||||
@@ -14,6 +14,7 @@ import litellm
|
||||
from litellm.cost_calculator import default_video_cost_calculator
|
||||
from litellm.integrations.custom_logger import CustomLogger
|
||||
from litellm.litellm_core_utils.litellm_logging import Logging as LitellmLogging
|
||||
from litellm.llms.custom_httpx.http_handler import AsyncHTTPHandler
|
||||
from litellm.llms.custom_httpx.llm_http_handler import BaseLLMHTTPHandler
|
||||
from litellm.llms.gemini.videos.transformation import GeminiVideoConfig
|
||||
from litellm.llms.openai.videos.transformation import OpenAIVideoConfig
|
||||
@@ -1437,5 +1438,117 @@ class TestVideoEndpointsProxyLitellmParams:
|
||||
)
|
||||
|
||||
|
||||
def test_video_remix_handler_uses_api_key_from_litellm_params():
|
||||
"""Sync remix handler should fall back to litellm_params api_key when api_key param is None."""
|
||||
handler = BaseLLMHTTPHandler()
|
||||
config = OpenAIVideoConfig()
|
||||
|
||||
with patch.object(config, "validate_environment") as mock_validate:
|
||||
mock_validate.return_value = {"Authorization": "Bearer deployment-key"}
|
||||
|
||||
with patch.object(config, "transform_video_remix_request") as mock_transform:
|
||||
mock_transform.return_value = ("https://api.openai.com/v1/videos/video_123/remix", {"prompt": "remix it"})
|
||||
|
||||
with patch.object(config, "transform_video_remix_response") as mock_resp:
|
||||
mock_resp.return_value = MagicMock()
|
||||
|
||||
mock_client = MagicMock()
|
||||
mock_client.post.return_value = MagicMock(status_code=200)
|
||||
|
||||
with patch(
|
||||
"litellm.llms.custom_httpx.llm_http_handler._get_httpx_client",
|
||||
return_value=mock_client,
|
||||
):
|
||||
handler.video_remix_handler(
|
||||
video_id="video_123",
|
||||
prompt="remix it",
|
||||
video_remix_provider_config=config,
|
||||
custom_llm_provider="openai",
|
||||
litellm_params={"api_key": "deployment-key", "api_base": "https://api.openai.com/v1"},
|
||||
logging_obj=MagicMock(),
|
||||
timeout=5.0,
|
||||
api_key=None,
|
||||
_is_async=False,
|
||||
)
|
||||
|
||||
mock_validate.assert_called_once()
|
||||
assert mock_validate.call_args.kwargs["api_key"] == "deployment-key"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_async_video_remix_handler_uses_api_key_from_litellm_params():
|
||||
"""Async remix handler should fall back to litellm_params api_key when api_key param is None."""
|
||||
handler = BaseLLMHTTPHandler()
|
||||
config = OpenAIVideoConfig()
|
||||
|
||||
with patch.object(config, "validate_environment") as mock_validate:
|
||||
mock_validate.return_value = {"Authorization": "Bearer deployment-key"}
|
||||
|
||||
with patch.object(config, "transform_video_remix_request") as mock_transform:
|
||||
mock_transform.return_value = ("https://api.openai.com/v1/videos/video_123/remix", {"prompt": "remix it"})
|
||||
|
||||
with patch.object(config, "transform_video_remix_response") as mock_resp:
|
||||
mock_resp.return_value = MagicMock()
|
||||
|
||||
mock_client = MagicMock(spec=AsyncHTTPHandler)
|
||||
mock_response = MagicMock(status_code=200)
|
||||
mock_client.post = AsyncMock(return_value=mock_response)
|
||||
|
||||
with patch(
|
||||
"litellm.llms.custom_httpx.llm_http_handler.get_async_httpx_client",
|
||||
return_value=mock_client,
|
||||
):
|
||||
await handler.async_video_remix_handler(
|
||||
video_id="video_123",
|
||||
prompt="remix it",
|
||||
video_remix_provider_config=config,
|
||||
custom_llm_provider="openai",
|
||||
litellm_params={"api_key": "deployment-key", "api_base": "https://api.openai.com/v1"},
|
||||
logging_obj=MagicMock(),
|
||||
timeout=5.0,
|
||||
api_key=None,
|
||||
)
|
||||
|
||||
mock_validate.assert_called_once()
|
||||
assert mock_validate.call_args.kwargs["api_key"] == "deployment-key"
|
||||
|
||||
|
||||
def test_video_remix_handler_prefers_explicit_api_key():
|
||||
"""Sync remix handler should prefer explicit api_key over litellm_params."""
|
||||
handler = BaseLLMHTTPHandler()
|
||||
config = OpenAIVideoConfig()
|
||||
|
||||
with patch.object(config, "validate_environment") as mock_validate:
|
||||
mock_validate.return_value = {"Authorization": "Bearer explicit-key"}
|
||||
|
||||
with patch.object(config, "transform_video_remix_request") as mock_transform:
|
||||
mock_transform.return_value = ("https://api.openai.com/v1/videos/video_123/remix", {"prompt": "remix it"})
|
||||
|
||||
with patch.object(config, "transform_video_remix_response") as mock_resp:
|
||||
mock_resp.return_value = MagicMock()
|
||||
|
||||
mock_client = MagicMock()
|
||||
mock_client.post.return_value = MagicMock(status_code=200)
|
||||
|
||||
with patch(
|
||||
"litellm.llms.custom_httpx.llm_http_handler._get_httpx_client",
|
||||
return_value=mock_client,
|
||||
):
|
||||
handler.video_remix_handler(
|
||||
video_id="video_123",
|
||||
prompt="remix it",
|
||||
video_remix_provider_config=config,
|
||||
custom_llm_provider="openai",
|
||||
litellm_params={"api_key": "deployment-key", "api_base": "https://api.openai.com/v1"},
|
||||
logging_obj=MagicMock(),
|
||||
timeout=5.0,
|
||||
api_key="explicit-key",
|
||||
_is_async=False,
|
||||
)
|
||||
|
||||
mock_validate.assert_called_once()
|
||||
assert mock_validate.call_args.kwargs["api_key"] == "explicit-key"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__])
|
||||
|
||||
Reference in New Issue
Block a user