From 8b59bddc03e9f9afc705d6dc00eb7af5007be127 Mon Sep 17 00:00:00 2001 From: aditya thomas Date: Mon, 29 Apr 2024 20:09:14 +0530 Subject: [PATCH] anthropic[patch]: add tests for secret_str for api key (#20986) **Description:** Add tests to check API keys are masked **Issue:** Resolves https://github.com/langchain-ai/langchain/issues/12165 for Anthropic models **Dependencies:** None --- .../tests/unit_tests/test_chat_models.py | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/libs/partners/anthropic/tests/unit_tests/test_chat_models.py b/libs/partners/anthropic/tests/unit_tests/test_chat_models.py index 7b5c1624df..0613d05ad5 100644 --- a/libs/partners/anthropic/tests/unit_tests/test_chat_models.py +++ b/libs/partners/anthropic/tests/unit_tests/test_chat_models.py @@ -9,6 +9,7 @@ from langchain_core.messages import AIMessage, HumanMessage, SystemMessage, Tool from langchain_core.outputs import ChatGeneration, ChatResult from langchain_core.pydantic_v1 import BaseModel, Field, SecretStr from langchain_core.tools import BaseTool +from pytest import CaptureFixture, MonkeyPatch from langchain_anthropic import ChatAnthropic from langchain_anthropic.chat_models import ( @@ -419,3 +420,53 @@ def test__format_messages_with_list_content_and_tool_calls() -> None: ) actual = _format_messages(messages) assert expected == actual + + +def test_anthropic_api_key_is_secret_string() -> None: + """Test that the API key is stored as a SecretStr.""" + chat_model = ChatAnthropic( + model="claude-3-opus-20240229", + anthropic_api_key="secret-api-key", + ) + assert isinstance(chat_model.anthropic_api_key, SecretStr) + + +def test_anthropic_api_key_masked_when_passed_from_env( + monkeypatch: MonkeyPatch, capsys: CaptureFixture +) -> None: + """Test that the API key is masked when passed from an environment variable.""" + monkeypatch.setenv("ANTHROPIC_API_KEY ", "secret-api-key") + chat_model = ChatAnthropic( + model="claude-3-opus-20240229", + anthropic_api_key="secret-api-key", + ) + print(chat_model.anthropic_api_key, end="") # noqa: T201 + captured = capsys.readouterr() + + assert captured.out == "**********" + + +def test_anthropic_api_key_masked_when_passed_via_constructor( + capsys: CaptureFixture, +) -> None: + """Test that the API key is masked when passed via the constructor.""" + chat_model = ChatAnthropic( + model="claude-3-opus-20240229", + anthropic_api_key="secret-api-key", + ) + print(chat_model.anthropic_api_key, end="") # noqa: T201 + captured = capsys.readouterr() + + assert captured.out == "**********" + + +def test_anthropic_uses_actual_secret_value_from_secretstr() -> None: + """Test that the actual secret value is correctly retrieved.""" + chat_model = ChatAnthropic( + model="claude-3-opus-20240229", + anthropic_api_key="secret-api-key", + ) + assert ( + cast(SecretStr, chat_model.anthropic_api_key).get_secret_value() + == "secret-api-key" + )