Merge pull request #3553 from lentil32/main

fix: Redundant warning when `AWS_PROFILE` set for Bedrock
This commit is contained in:
paul-gauthier 2025-03-21 11:16:27 -07:00 committed by GitHub
commit 44f87c2c17
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 184 additions and 0 deletions

View file

@ -589,6 +589,21 @@ class Model(ModelSettings):
model = self.name
res = litellm.validate_environment(model)
# If missing AWS credential keys but AWS_PROFILE is set, consider AWS credentials valid
if res["missing_keys"] and any(
key in ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"] for key in res["missing_keys"]
):
if model.startswith("bedrock/") or model.startswith("us.anthropic."):
if os.environ.get("AWS_PROFILE"):
res["missing_keys"] = [
k
for k in res["missing_keys"]
if k not in ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"]
]
if not res["missing_keys"]:
res["keys_in_environment"] = True
if res["keys_in_environment"]:
return res
if res["missing_keys"]:

View file

@ -0,0 +1,169 @@
import os
from unittest.mock import patch
from aider.models import Model
class TestAWSCredentials:
"""Test AWS credential handling, especially AWS_PROFILE."""
def test_bedrock_model_with_aws_profile(self):
"""Test that Bedrock models accept AWS_PROFILE as valid authentication."""
# Save original environment
original_env = os.environ.copy()
try:
# Set up test environment
os.environ.clear()
os.environ["AWS_PROFILE"] = "test-profile"
# Create a model instance
with patch("aider.llm.litellm.validate_environment") as mock_validate:
# Mock the litellm validate_environment to return missing AWS keys
mock_validate.return_value = {
"missing_keys": ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"],
"keys_in_environment": False,
}
# Test with a bedrock model
model = Model("bedrock/anthropic.claude-v2")
# Check that the AWS keys were removed from missing_keys
assert "AWS_ACCESS_KEY_ID" not in model.missing_keys
assert "AWS_SECRET_ACCESS_KEY" not in model.missing_keys
# With no missing keys, validation should pass
assert model.keys_in_environment
finally:
# Restore original environment
os.environ.clear()
os.environ.update(original_env)
def test_us_anthropic_model_with_aws_profile(self):
"""Test that us.anthropic models accept AWS_PROFILE as valid authentication."""
# Save original environment
original_env = os.environ.copy()
try:
# Set up test environment
os.environ.clear()
os.environ["AWS_PROFILE"] = "test-profile"
# Create a model instance
with patch("aider.llm.litellm.validate_environment") as mock_validate:
# Mock the litellm validate_environment to return missing AWS keys
mock_validate.return_value = {
"missing_keys": ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"],
"keys_in_environment": False,
}
# Test with a us.anthropic model
model = Model("us.anthropic.claude-3-7-sonnet-20250219-v1:0")
# Check that the AWS keys were removed from missing_keys
assert "AWS_ACCESS_KEY_ID" not in model.missing_keys
assert "AWS_SECRET_ACCESS_KEY" not in model.missing_keys
# With no missing keys, validation should pass
assert model.keys_in_environment
finally:
# Restore original environment
os.environ.clear()
os.environ.update(original_env)
def test_non_bedrock_model_with_aws_profile(self):
"""Test that non-Bedrock models do not accept AWS_PROFILE for AWS credentials."""
# Save original environment
original_env = os.environ.copy()
try:
# Set up test environment
os.environ.clear()
os.environ["AWS_PROFILE"] = "test-profile"
# Create a model instance
with patch("aider.llm.litellm.validate_environment") as mock_validate:
# Mock the litellm validate_environment to return missing AWS keys
mock_validate.return_value = {
"missing_keys": ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"],
"keys_in_environment": False,
}
# Test with a non-Bedrock model
model = Model("gpt-4")
# For non-Bedrock models, AWS credential keys should remain in missing_keys
assert "AWS_ACCESS_KEY_ID" in model.missing_keys
assert "AWS_SECRET_ACCESS_KEY" in model.missing_keys
# With missing keys, validation should fail
assert not model.keys_in_environment
finally:
# Restore original environment
os.environ.clear()
os.environ.update(original_env)
def test_bedrock_model_without_aws_profile(self):
"""Test that Bedrock models require credentials when AWS_PROFILE is not set."""
# Save original environment
original_env = os.environ.copy()
try:
# Set up test environment
os.environ.clear()
# Create a model instance
with patch("aider.llm.litellm.validate_environment") as mock_validate:
# Mock the litellm validate_environment to return missing AWS keys
mock_validate.return_value = {
"missing_keys": ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"],
"keys_in_environment": False,
}
# Test with a bedrock model without AWS_PROFILE
model = Model("bedrock/anthropic.claude-v2")
# Without AWS_PROFILE, AWS credential keys should remain in missing_keys
assert "AWS_ACCESS_KEY_ID" in model.missing_keys
assert "AWS_SECRET_ACCESS_KEY" in model.missing_keys
# With missing keys, validation should fail
assert not model.keys_in_environment
finally:
# Restore original environment
os.environ.clear()
os.environ.update(original_env)
def test_mixed_missing_keys_with_aws_profile(self):
"""Test that only AWS credential keys are affected by AWS_PROFILE."""
# Save original environment
original_env = os.environ.copy()
try:
# Set up test environment
os.environ.clear()
os.environ["AWS_PROFILE"] = "test-profile"
# Create a model instance
with patch("aider.llm.litellm.validate_environment") as mock_validate:
# Mock the litellm validate_environment to return missing AWS keys and another key
mock_validate.return_value = {
"missing_keys": ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "ANOTHER_KEY"],
"keys_in_environment": False,
}
# Test with a bedrock model
model = Model("bedrock/anthropic.claude-v2")
# AWS credential keys should be removed from missing_keys
assert "AWS_ACCESS_KEY_ID" not in model.missing_keys
assert "AWS_SECRET_ACCESS_KEY" not in model.missing_keys
# But other keys should remain
assert "ANOTHER_KEY" in model.missing_keys
# With other missing keys, validation should still fail
assert not model.keys_in_environment
finally:
# Restore original environment
os.environ.clear()
os.environ.update(original_env)