Fix the azure auth format for videos (#17009)

* fix the azure auth in correct format

* Add litellm param in validate_environment method

* fix lint errors
This commit is contained in:
Sameer Kankute 2025-11-25 07:10:55 +05:30 • committed by GitHub
parent 84e8b9a7bf
commit 3b6c170739
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 70 additions and 43 deletions

View file

@ -1,9 +1,8 @@
from typing import TYPE_CHECKING, Any, Dict, Optional
from litellm.types.videos.main import VideoCreateOptionalRequestParams
from litellm.secret_managers.main import get_secret_str
from litellm.types.router import GenericLiteLLMParams
from litellm.llms.azure.common_utils import BaseAzureLLM
import litellm
from litellm.llms.openai.videos.transformation import OpenAIVideoConfig
if TYPE_CHECKING:
from litellm.litellm_core_utils.litellm_logging import Logging as _LiteLLMLoggingObj
@ -56,22 +55,27 @@ class AzureVideoConfig(OpenAIVideoConfig):
headers: dict,
model: str,
api_key: Optional[str] = None,
litellm_params: Optional[GenericLiteLLMParams] = None,
) -> dict:
api_key = (
api_key
or litellm.api_key
or litellm.azure_key
or get_secret_str("AZURE_OPENAI_API_KEY")
or get_secret_str("AZURE_API_KEY")
"""
Validate Azure environment and set up authentication headers.
Uses _base_validate_azure_environment to properly handle credentials from litellm_credential_name.
"""
# If litellm_params is provided, use it; otherwise create a new one
if litellm_params is None:
litellm_params = GenericLiteLLMParams()
if api_key and not litellm_params.api_key:
litellm_params.api_key = api_key
# Use the base Azure validation method which properly handles:
# 1. Credentials from litellm_credential_name via litellm_params
# 2. Sets the correct "api-key" header (not "Authorization: Bearer")
return BaseAzureLLM._base_validate_azure_environment(
headers=headers,
litellm_params=litellm_params
)
headers.update(
{
"Authorization": f"Bearer {api_key}",
}
)
return headers
def get_complete_url(
self,
model: str,

View file

@ -66,6 +66,7 @@ class BaseVideoConfig(ABC):
headers: dict,
model: str,
api_key: Optional[str] = None,
litellm_params: Optional[GenericLiteLLMParams] = None,
) -> dict:
return {}

View file

@ -4126,6 +4126,7 @@ class BaseLLMHTTPHandler:
headers=video_generation_optional_request_params.get("extra_headers", {})
or {},
model=model,
litellm_params=litellm_params,
)
if extra_headers:
@ -4226,6 +4227,7 @@ class BaseLLMHTTPHandler:
headers=video_generation_optional_request_params.get("extra_headers", {})
or {},
model=model,
litellm_params=litellm_params,
)
if extra_headers:

View file

@ -160,11 +160,16 @@ class GeminiVideoConfig(BaseVideoConfig):
headers: dict,
model: str,
api_key: Optional[str] = None,
litellm_params: Optional[GenericLiteLLMParams] = None,
) -> dict:
"""
Validate environment and add Gemini API key to headers.
Gemini uses x-goog-api-key header for authentication.
"""
# Use api_key from litellm_params if available, otherwise fall back to other sources
if litellm_params and litellm_params.api_key:
api_key = api_key or litellm_params.api_key
api_key = (
api_key
or litellm.api_key

View file

@ -61,7 +61,12 @@ class OpenAIVideoConfig(BaseVideoConfig):
headers: dict,
model: str,
api_key: Optional[str] = None,
litellm_params: Optional[GenericLiteLLMParams] = None,
) -> dict:
# Use api_key from litellm_params if available, otherwise fall back to other sources
if litellm_params and litellm_params.api_key:
api_key = api_key or litellm_params.api_key
api_key = (
api_key
or litellm.api_key

View file

@ -114,11 +114,16 @@ class RunwayMLVideoConfig(BaseVideoConfig):
headers: dict,
model: str,
api_key: Optional[str] = None,
litellm_params: Optional[GenericLiteLLMParams] = None,
) -> dict:
"""
Validate environment and set up authentication headers.
RunwayML uses Bearer token authentication via RUNWAYML_API_SECRET.
"""
# Use api_key from litellm_params if available, otherwise fall back to other sources
if litellm_params and litellm_params.api_key:
api_key = api_key or litellm_params.api_key
api_key = (
api_key
or litellm.api_key

View file

@ -160,13 +160,11 @@ class VertexAIVideoConfig(BaseVideoConfig, VertexBase):
def validate_environment(
self,
headers: Dict,
headers: dict,
model: str,
api_key: Optional[str] = None,
api_base: Optional[str] = None,
litellm_params: Optional[dict] = None,
**kwargs,
) -> Dict:
litellm_params: Optional[GenericLiteLLMParams] = None,
) -> dict:
"""
Validate environment and return headers for Vertex AI OCR.

View file

@ -65,8 +65,13 @@ class TestAzureVideoConfig:
assert result["size"] == "1280x720"
assert result["user"] == "test_user"
def test_validate_environment_with_api_key(self):
"""Test environment validation with provided API key."""
@patch('litellm.llms.azure.common_utils.litellm')
def test_validate_environment_with_api_key(self, mock_litellm):
"""Test environment validation with provided API key - should use api-key header for Azure."""
# Since validate_environment passes litellm_params=None, it relies on litellm.api_key or litellm.azure_key
mock_litellm.api_key = self.api_key
mock_litellm.azure_key = None
headers = {"Content-Type": "application/json"}
result_headers = self.config.validate_environment(
@ -75,14 +80,15 @@ class TestAzureVideoConfig:
api_key=self.api_key
)
assert "Authorization" in result_headers
assert result_headers["Authorization"] == f"Bearer {self.api_key}"
# Azure uses "api-key" header, not "Authorization: Bearer"
assert "api-key" in result_headers
assert result_headers["api-key"] == self.api_key
assert result_headers["Content-Type"] == "application/json"
@patch('litellm.llms.azure.videos.transformation.get_secret_str')
@patch('litellm.llms.azure.videos.transformation.litellm')
@patch('litellm.llms.azure.common_utils.get_secret_str')
@patch('litellm.llms.azure.common_utils.litellm')
def test_validate_environment_without_api_key(self, mock_litellm, mock_get_secret):
"""Test environment validation without provided API key."""
"""Test environment validation without provided API key - should fallback to secret manager."""
mock_litellm.api_key = None
mock_litellm.azure_key = None
mock_get_secret.return_value = "secret-api-key"
@ -95,8 +101,8 @@ class TestAzureVideoConfig:
api_key=None
)
assert "Authorization" in result_headers
assert result_headers["Authorization"] == "Bearer secret-api-key"
assert "api-key" in result_headers
assert result_headers["api-key"] == "secret-api-key"
def test_get_complete_url(self):
"""Test URL construction for Azure video API."""
@ -320,23 +326,24 @@ class TestAzureVideoConfig:
logging_obj=logging_obj
)
def test_azure_specific_environment_validation(self):
@patch('litellm.llms.azure.common_utils.litellm')
def test_azure_specific_environment_validation(self, mock_litellm):
"""Test Azure-specific environment validation with different key sources."""
# Test with azure_key
mock_litellm.api_key = None
mock_litellm.azure_key = "azure-test-key"
mock_litellm.openai_key = None
headers = {"Content-Type": "application/json"}
# Test with azure_key
with patch('litellm.llms.azure.videos.transformation.litellm') as mock_litellm:
mock_litellm.api_key = None
mock_litellm.azure_key = "azure-test-key"
mock_litellm.openai_key = None
result_headers = self.config.validate_environment(
headers=headers,
model=self.model,
api_key=None
)
assert result_headers["Authorization"] == "Bearer azure-test-key"
result_headers = self.config.validate_environment(
headers=headers,
model=self.model,
api_key=None
)
assert "api-key" in result_headers
assert result_headers["api-key"] == "azure-test-key"
def test_usage_data_creation_in_video_create(self):
"""Test that usage data is created correctly in video create response."""