mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-11 22:51:28 +00:00
fix(anthropic): raise missing-credential error on /v1/messages passthrough
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
92fe35854b
commit
e14f485827
2 changed files with 56 additions and 2 deletions
|
|
@ -8,6 +8,7 @@ from litellm.constants import (
|
|||
DEFAULT_REASONING_EFFORT_MEDIUM_THINKING_BUDGET,
|
||||
DEFAULT_REASONING_EFFORT_XHIGH_THINKING_BUDGET,
|
||||
)
|
||||
from litellm.exceptions import AuthenticationError
|
||||
from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj
|
||||
from litellm.litellm_core_utils.litellm_logging import verbose_logger
|
||||
from litellm.llms.base_llm.anthropic_messages.transformation import (
|
||||
|
|
@ -309,8 +310,17 @@ class AnthropicMessagesConfig(BaseAnthropicMessagesConfig):
|
|||
|
||||
if "x-api-key" not in headers and "authorization" not in headers:
|
||||
auth_header: Final = AnthropicModelInfo.get_auth_header(api_key)
|
||||
if auth_header is not None:
|
||||
headers.update(auth_header)
|
||||
if auth_header is None:
|
||||
raise AuthenticationError(
|
||||
message=(
|
||||
"Missing Anthropic API Key - A call is being made to anthropic but no key is set "
|
||||
"either in the environment variables or via params. Please set `ANTHROPIC_API_KEY` "
|
||||
"or `ANTHROPIC_AUTH_TOKEN` in your environment vars"
|
||||
),
|
||||
llm_provider=self._resolved_provider,
|
||||
model=model,
|
||||
)
|
||||
headers.update(auth_header)
|
||||
if "anthropic-version" not in headers:
|
||||
headers["anthropic-version"] = DEFAULT_ANTHROPIC_API_VERSION
|
||||
if "content-type" not in headers:
|
||||
|
|
|
|||
|
|
@ -1227,6 +1227,50 @@ class TestPassthroughAuthToken:
|
|||
assert updated_headers["x-api-key"] == FAKE_REGULAR_KEY
|
||||
assert "authorization" not in updated_headers
|
||||
|
||||
def test_passthrough_missing_credentials_raises_authentication_error(self):
|
||||
"""Passthrough endpoint should raise locally instead of forwarding an unauthenticated request."""
|
||||
from unittest.mock import patch as mock_patch
|
||||
|
||||
import litellm
|
||||
from litellm.llms.anthropic.experimental_pass_through.messages.transformation import (
|
||||
AnthropicMessagesConfig,
|
||||
)
|
||||
|
||||
config = AnthropicMessagesConfig()
|
||||
with mock_patch.dict("os.environ", {}, clear=True):
|
||||
with pytest.raises(litellm.AuthenticationError, match="Missing Anthropic API Key"):
|
||||
config.validate_anthropic_messages_environment(
|
||||
headers={},
|
||||
model="claude-sonnet-4-5-20250929",
|
||||
messages=[{"role": "user", "content": "Hello"}],
|
||||
optional_params={},
|
||||
litellm_params={},
|
||||
api_key=None,
|
||||
api_base=None,
|
||||
)
|
||||
|
||||
def test_passthrough_client_x_api_key_header_is_kept(self):
|
||||
"""A client-forwarded x-api-key header should satisfy validation without env credentials."""
|
||||
from unittest.mock import patch as mock_patch
|
||||
|
||||
from litellm.llms.anthropic.experimental_pass_through.messages.transformation import (
|
||||
AnthropicMessagesConfig,
|
||||
)
|
||||
|
||||
config = AnthropicMessagesConfig()
|
||||
with mock_patch.dict("os.environ", {}, clear=True):
|
||||
updated_headers, _ = config.validate_anthropic_messages_environment(
|
||||
headers={"x-api-key": FAKE_REGULAR_KEY},
|
||||
model="claude-sonnet-4-5-20250929",
|
||||
messages=[{"role": "user", "content": "Hello"}],
|
||||
optional_params={},
|
||||
litellm_params={},
|
||||
api_key=None,
|
||||
api_base=None,
|
||||
)
|
||||
|
||||
assert updated_headers["x-api-key"] == FAKE_REGULAR_KEY
|
||||
|
||||
def test_passthrough_get_complete_url_honours_base_url_env(self):
|
||||
"""get_complete_url should use ANTHROPIC_BASE_URL when api_base is None."""
|
||||
from unittest.mock import patch as mock_patch
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue