mirror of
https://github.com/tiennm99/litellm.git
synced 2026-07-08 01:16:52 +00:00
Add tests related messages api
This commit is contained in:
@@ -5,7 +5,8 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple
|
||||
|
||||
import httpx
|
||||
|
||||
from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj, verbose_logger
|
||||
from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj
|
||||
from litellm.litellm_core_utils.litellm_logging import verbose_logger
|
||||
from litellm.llms.anthropic.experimental_pass_through.messages.transformation import (
|
||||
AnthropicMessagesConfig,
|
||||
)
|
||||
|
||||
@@ -32,7 +32,7 @@ class TestAzureAnthropicChatCompletion:
|
||||
mock_config.transform_request.return_value = {"model": "claude-sonnet-4-5", "messages": []}
|
||||
mock_config.transform_response.return_value = ModelResponse()
|
||||
mock_config_instance = MagicMock()
|
||||
mock_config_instance.validate_environment.return_value = {"api-key": "test-api-key", "anthropic-version": "2023-06-01"}
|
||||
mock_config_instance.validate_environment.return_value = {"x-api-key": "test-api-key", "anthropic-version": "2023-06-01"}
|
||||
mock_azure_config.return_value = mock_config_instance
|
||||
mock_provider_manager.get_provider_chat_config.return_value = mock_config
|
||||
|
||||
@@ -90,7 +90,7 @@ class TestAzureAnthropicChatCompletion:
|
||||
"stream": True,
|
||||
}
|
||||
mock_config_instance = MagicMock()
|
||||
mock_config_instance.validate_environment.return_value = {"api-key": "test-api-key", "anthropic-version": "2023-06-01"}
|
||||
mock_config_instance.validate_environment.return_value = {"x-api-key": "test-api-key", "anthropic-version": "2023-06-01"}
|
||||
mock_azure_config.return_value = mock_config_instance
|
||||
mock_provider_manager.get_provider_chat_config.return_value = mock_config
|
||||
|
||||
@@ -151,7 +151,7 @@ class TestAzureAnthropicChatCompletion:
|
||||
mock_response = ModelResponse()
|
||||
mock_config.transform_response.return_value = mock_response
|
||||
mock_config_instance = MagicMock()
|
||||
mock_config_instance.validate_environment.return_value = {"api-key": "test-api-key", "anthropic-version": "2023-06-01"}
|
||||
mock_config_instance.validate_environment.return_value = {"x-api-key": "test-api-key", "anthropic-version": "2023-06-01"}
|
||||
mock_azure_config.return_value = mock_config_instance
|
||||
mock_provider_manager.get_provider_chat_config.return_value = mock_config
|
||||
|
||||
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(
|
||||
0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../../.."))
|
||||
)
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from litellm.llms.azure.anthropic.messages_transformation import (
|
||||
AzureAnthropicMessagesConfig,
|
||||
)
|
||||
from litellm.types.router import GenericLiteLLMParams
|
||||
|
||||
|
||||
class TestAzureAnthropicMessagesConfig:
|
||||
def test_inherits_from_anthropic_messages_config(self):
|
||||
"""Test that AzureAnthropicMessagesConfig inherits from AnthropicMessagesConfig"""
|
||||
config = AzureAnthropicMessagesConfig()
|
||||
assert isinstance(config, AzureAnthropicMessagesConfig)
|
||||
# Check that it has methods from parent class
|
||||
assert hasattr(config, "get_supported_anthropic_messages_params")
|
||||
assert hasattr(config, "get_complete_url")
|
||||
assert hasattr(config, "validate_anthropic_messages_environment")
|
||||
assert hasattr(config, "transform_anthropic_messages_request")
|
||||
assert hasattr(config, "transform_anthropic_messages_response")
|
||||
|
||||
def test_validate_anthropic_messages_environment_with_dict_litellm_params(self):
|
||||
"""Test validate_anthropic_messages_environment with dict litellm_params"""
|
||||
config = AzureAnthropicMessagesConfig()
|
||||
headers = {}
|
||||
model = "claude-sonnet-4-5"
|
||||
messages = [{"role": "user", "content": "Hello"}]
|
||||
optional_params = {}
|
||||
litellm_params = {"api_key": "test-api-key"}
|
||||
api_key = "test-api-key"
|
||||
|
||||
with patch(
|
||||
"litellm.llms.azure.common_utils.BaseAzureLLM._base_validate_azure_environment"
|
||||
) as mock_validate:
|
||||
mock_validate.return_value = {"api-key": "test-api-key"}
|
||||
result, api_base = config.validate_anthropic_messages_environment(
|
||||
headers=headers,
|
||||
model=model,
|
||||
messages=messages,
|
||||
optional_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
api_key=api_key,
|
||||
)
|
||||
|
||||
# Verify that dict was converted to GenericLiteLLMParams
|
||||
call_args = mock_validate.call_args
|
||||
assert isinstance(call_args[1]["litellm_params"], GenericLiteLLMParams)
|
||||
assert call_args[1]["litellm_params"].api_key == "test-api-key"
|
||||
assert "anthropic-version" in result
|
||||
assert "x-api-key" in result
|
||||
assert result["x-api-key"] == "test-api-key"
|
||||
assert "api-key" not in result
|
||||
|
||||
def test_validate_anthropic_messages_environment_converts_api_key_to_x_api_key(self):
|
||||
"""Test that api-key header is converted to x-api-key"""
|
||||
config = AzureAnthropicMessagesConfig()
|
||||
headers = {}
|
||||
model = "claude-sonnet-4-5"
|
||||
messages = [{"role": "user", "content": "Hello"}]
|
||||
optional_params = {}
|
||||
litellm_params = {"api_key": "test-api-key"}
|
||||
|
||||
with patch(
|
||||
"litellm.llms.azure.common_utils.BaseAzureLLM._base_validate_azure_environment"
|
||||
) as mock_validate:
|
||||
mock_validate.return_value = {"api-key": "test-api-key"}
|
||||
result, api_base = config.validate_anthropic_messages_environment(
|
||||
headers=headers,
|
||||
model=model,
|
||||
messages=messages,
|
||||
optional_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
)
|
||||
|
||||
# Verify api-key was converted to x-api-key
|
||||
assert "x-api-key" in result
|
||||
assert result["x-api-key"] == "test-api-key"
|
||||
assert "api-key" not in result
|
||||
|
||||
def test_validate_anthropic_messages_environment_sets_headers(self):
|
||||
"""Test that required headers are set"""
|
||||
config = AzureAnthropicMessagesConfig()
|
||||
headers = {}
|
||||
model = "claude-sonnet-4-5"
|
||||
messages = [{"role": "user", "content": "Hello"}]
|
||||
optional_params = {}
|
||||
litellm_params = {"api_key": "test-api-key"}
|
||||
|
||||
with patch(
|
||||
"litellm.llms.azure.common_utils.BaseAzureLLM._base_validate_azure_environment"
|
||||
) as mock_validate:
|
||||
mock_validate.return_value = {"api-key": "test-api-key"}
|
||||
result, api_base = config.validate_anthropic_messages_environment(
|
||||
headers=headers,
|
||||
model=model,
|
||||
messages=messages,
|
||||
optional_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
)
|
||||
|
||||
assert "anthropic-version" in result
|
||||
assert result["anthropic-version"] == "2023-06-01"
|
||||
assert "content-type" in result
|
||||
assert result["content-type"] == "application/json"
|
||||
assert "x-api-key" in result
|
||||
|
||||
def test_get_complete_url_with_base_url(self):
|
||||
"""Test get_complete_url with base URL"""
|
||||
config = AzureAnthropicMessagesConfig()
|
||||
api_base = "https://test.services.ai.azure.com/anthropic"
|
||||
api_key = "test-api-key"
|
||||
model = "claude-sonnet-4-5"
|
||||
optional_params = {}
|
||||
litellm_params = {}
|
||||
|
||||
url = config.get_complete_url(
|
||||
api_base=api_base,
|
||||
api_key=api_key,
|
||||
model=model,
|
||||
optional_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
)
|
||||
|
||||
assert url == "https://test.services.ai.azure.com/anthropic/v1/messages"
|
||||
|
||||
def test_get_complete_url_with_base_url_ending_with_slash(self):
|
||||
"""Test get_complete_url with base URL ending with slash"""
|
||||
config = AzureAnthropicMessagesConfig()
|
||||
api_base = "https://test.services.ai.azure.com/anthropic/"
|
||||
api_key = "test-api-key"
|
||||
model = "claude-sonnet-4-5"
|
||||
optional_params = {}
|
||||
litellm_params = {}
|
||||
|
||||
url = config.get_complete_url(
|
||||
api_base=api_base,
|
||||
api_key=api_key,
|
||||
model=model,
|
||||
optional_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
)
|
||||
|
||||
assert url == "https://test.services.ai.azure.com/anthropic/v1/messages"
|
||||
|
||||
def test_get_complete_url_with_base_url_already_containing_v1_messages(self):
|
||||
"""Test get_complete_url with base URL already containing /v1/messages"""
|
||||
config = AzureAnthropicMessagesConfig()
|
||||
api_base = "https://test.services.ai.azure.com/anthropic/v1/messages"
|
||||
api_key = "test-api-key"
|
||||
model = "claude-sonnet-4-5"
|
||||
optional_params = {}
|
||||
litellm_params = {}
|
||||
|
||||
url = config.get_complete_url(
|
||||
api_base=api_base,
|
||||
api_key=api_key,
|
||||
model=model,
|
||||
optional_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
)
|
||||
|
||||
assert url == "https://test.services.ai.azure.com/anthropic/v1/messages"
|
||||
|
||||
def test_get_complete_url_with_base_url_containing_anthropic(self):
|
||||
"""Test get_complete_url with base URL already containing /anthropic"""
|
||||
config = AzureAnthropicMessagesConfig()
|
||||
api_base = "https://test.services.ai.azure.com/anthropic"
|
||||
api_key = "test-api-key"
|
||||
model = "claude-sonnet-4-5"
|
||||
optional_params = {}
|
||||
litellm_params = {}
|
||||
|
||||
url = config.get_complete_url(
|
||||
api_base=api_base,
|
||||
api_key=api_key,
|
||||
model=model,
|
||||
optional_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
)
|
||||
|
||||
assert url == "https://test.services.ai.azure.com/anthropic/v1/messages"
|
||||
|
||||
def test_get_complete_url_with_base_url_without_anthropic(self):
|
||||
"""Test get_complete_url with base URL without /anthropic"""
|
||||
config = AzureAnthropicMessagesConfig()
|
||||
api_base = "https://test.services.ai.azure.com"
|
||||
api_key = "test-api-key"
|
||||
model = "claude-sonnet-4-5"
|
||||
optional_params = {}
|
||||
litellm_params = {}
|
||||
|
||||
url = config.get_complete_url(
|
||||
api_base=api_base,
|
||||
api_key=api_key,
|
||||
model=model,
|
||||
optional_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
)
|
||||
|
||||
assert url == "https://test.services.ai.azure.com/anthropic/v1/messages"
|
||||
|
||||
def test_get_complete_url_raises_error_when_api_base_missing(self):
|
||||
"""Test get_complete_url raises error when api_base is None"""
|
||||
config = AzureAnthropicMessagesConfig()
|
||||
api_base = None
|
||||
api_key = "test-api-key"
|
||||
model = "claude-sonnet-4-5"
|
||||
optional_params = {}
|
||||
litellm_params = {}
|
||||
|
||||
with patch("litellm.secret_managers.main.get_secret_str", return_value=None):
|
||||
with pytest.raises(ValueError, match="Missing Azure API Base"):
|
||||
config.get_complete_url(
|
||||
api_base=api_base,
|
||||
api_key=api_key,
|
||||
model=model,
|
||||
optional_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
)
|
||||
|
||||
def test_get_supported_anthropic_messages_params(self):
|
||||
"""Test get_supported_anthropic_messages_params returns correct params"""
|
||||
config = AzureAnthropicMessagesConfig()
|
||||
model = "claude-sonnet-4-5"
|
||||
params = config.get_supported_anthropic_messages_params(model)
|
||||
|
||||
assert "messages" in params
|
||||
assert "model" in params
|
||||
assert "max_tokens" in params
|
||||
assert "temperature" in params
|
||||
assert "tools" in params
|
||||
assert "tool_choice" in params
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(
|
||||
0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../../.."))
|
||||
)
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
import litellm
|
||||
from litellm.types.utils import LlmProviders
|
||||
from litellm.utils import ProviderConfigManager
|
||||
|
||||
|
||||
class TestAzureAnthropicProviderConfig:
|
||||
def test_get_provider_anthropic_messages_config_returns_azure_config(self):
|
||||
"""Test that get_provider_anthropic_messages_config returns AzureAnthropicMessagesConfig for azure_anthropic provider"""
|
||||
from litellm.llms.azure.anthropic.messages_transformation import (
|
||||
AzureAnthropicMessagesConfig,
|
||||
)
|
||||
|
||||
config = ProviderConfigManager.get_provider_anthropic_messages_config(
|
||||
model="claude-sonnet-4-5",
|
||||
provider=LlmProviders.AZURE_ANTHROPIC,
|
||||
)
|
||||
|
||||
assert config is not None
|
||||
assert isinstance(config, AzureAnthropicMessagesConfig)
|
||||
|
||||
def test_get_provider_anthropic_messages_config_returns_anthropic_config_for_anthropic_provider(self):
|
||||
"""Test that get_provider_anthropic_messages_config returns AnthropicMessagesConfig for anthropic provider"""
|
||||
from litellm.llms.azure.anthropic.messages_transformation import (
|
||||
AzureAnthropicMessagesConfig,
|
||||
)
|
||||
|
||||
config = ProviderConfigManager.get_provider_anthropic_messages_config(
|
||||
model="claude-sonnet-4-5",
|
||||
provider=LlmProviders.ANTHROPIC,
|
||||
)
|
||||
|
||||
# Should return AnthropicMessagesConfig, not AzureAnthropicMessagesConfig
|
||||
assert config is not None
|
||||
assert not isinstance(config, AzureAnthropicMessagesConfig)
|
||||
assert isinstance(config, litellm.AnthropicMessagesConfig)
|
||||
|
||||
def test_get_provider_chat_config_returns_azure_anthropic_config(self):
|
||||
"""Test that get_provider_chat_config returns AzureAnthropicConfig for azure_anthropic provider"""
|
||||
from litellm.llms.azure.anthropic.transformation import AzureAnthropicConfig
|
||||
|
||||
config = ProviderConfigManager.get_provider_chat_config(
|
||||
model="claude-sonnet-4-5",
|
||||
provider=LlmProviders.AZURE_ANTHROPIC,
|
||||
)
|
||||
|
||||
assert config is not None
|
||||
assert isinstance(config, AzureAnthropicConfig)
|
||||
|
||||
@@ -5,9 +5,10 @@ sys.path.insert(
|
||||
0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../../.."))
|
||||
)
|
||||
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from litellm.llms.azure.anthropic.transformation import AzureAnthropicConfig
|
||||
from litellm.types.router import GenericLiteLLMParams
|
||||
|
||||
@@ -102,8 +103,8 @@ class TestAzureAnthropicConfig:
|
||||
call_args = mock_validate.call_args
|
||||
assert call_args[1]["litellm_params"].api_key == "provided-api-key"
|
||||
|
||||
def test_validate_environment_removes_x_api_key(self):
|
||||
"""Test that x-api-key header is removed (Azure uses api-key instead)"""
|
||||
def test_validate_environment_converts_api_key_to_x_api_key(self):
|
||||
"""Test that api-key header is converted to x-api-key (Azure Anthropic uses x-api-key)"""
|
||||
config = AzureAnthropicConfig()
|
||||
headers = {}
|
||||
model = "claude-sonnet-4-5"
|
||||
@@ -116,7 +117,7 @@ class TestAzureAnthropicConfig:
|
||||
) as mock_validate:
|
||||
mock_validate.return_value = {"api-key": "test-api-key"}
|
||||
with patch.object(
|
||||
config, "get_anthropic_headers", return_value={"x-api-key": "should-be-removed"}
|
||||
config, "get_anthropic_headers", return_value={}
|
||||
):
|
||||
result = config.validate_environment(
|
||||
headers=headers,
|
||||
@@ -126,9 +127,10 @@ class TestAzureAnthropicConfig:
|
||||
litellm_params=litellm_params,
|
||||
)
|
||||
|
||||
# Verify x-api-key was removed
|
||||
assert "x-api-key" not in result
|
||||
assert "api-key" in result
|
||||
# Verify api-key was converted to x-api-key
|
||||
assert "x-api-key" in result
|
||||
assert result["x-api-key"] == "test-api-key"
|
||||
assert "api-key" not in result
|
||||
|
||||
def test_validate_environment_sets_anthropic_version(self):
|
||||
"""Test that anthropic-version header is set"""
|
||||
|
||||
Reference in New Issue
Block a user