Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mask API key for Tongyi ChatModel and LLM #14170

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
875be81
added Union import and SecretStr import to tongyi.py
fadilparves Dec 2, 2023
3538e68
added function that will convert the raw string to SecretStr
fadilparves Dec 2, 2023
c9b1233
added property method for getting the api key from env and converting…
fadilparves Dec 2, 2023
b9addc0
fix type from dashcope to dashscope_api_key
fadilparves Dec 2, 2023
fc4cc16
added get_secret_value() when calling the api_key for tongyi client
fadilparves Dec 2, 2023
c4bb303
added the test file for tyongi chat model
fadilparves Dec 2, 2023
d43867b
added dashscope to the extended_testing in pyproject.toml to check if…
fadilparves Dec 2, 2023
492d008
adjust formatting of code
fadilparves Dec 2, 2023
31460cd
adjusting the var name for property function
fadilparves Dec 2, 2023
ade1f4f
fix the firt test case by adding _to_secret in root validator
fadilparves Dec 2, 2023
6eab833
all 3 test is passed
fadilparves Dec 2, 2023
d09ba4c
added dashscope as optional deps in pyproject.toml
fadilparves Dec 2, 2023
283064a
updated the poetry to add dashscope and also the toml file to make da…
fadilparves Dec 2, 2023
fb2b490
adding file poetry.lock and pyproject.toml missed it in the last commit
fadilparves Dec 2, 2023
93b1c32
added test for tongyi llm module
fadilparves Dec 3, 2023
efffaf8
added the 3 test cases for tongyi chat models
fadilparves Dec 3, 2023
ae35d6e
fix the issue where the api_key could be none hence calling get_secre…
fadilparves Dec 3, 2023
5fbfeaa
added the to secret function
fadilparves Dec 3, 2023
c4d31b2
all 3 test is passing for tongyi llm after adding the SecretStr
fadilparves Dec 3, 2023
9bcc1ed
fixed the passing of api key in kwargs to the dashscope generation ca…
fadilparves Dec 3, 2023
d3ff1e8
cr
baskaryan Dec 3, 2023
dd561c2
fmt
baskaryan Dec 3, 2023
b354fe6
cr
baskaryan Dec 3, 2023
d7a3e00
poetry
baskaryan Dec 3, 2023
1cc7f7b
poetry
baskaryan Dec 3, 2023
dfc5b2a
Merge branch 'master' into fadilp/fix-tongyi-api-key
fadilparves Dec 4, 2023
8e1199a
Merge branch 'master' into fadilp/fix-tongyi-api-key
eyurtsev Dec 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions libs/langchain/langchain/chat_models/tongyi.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
Optional,
Tuple,
Type,
cast,
)

from langchain_core.messages import (
Expand All @@ -33,7 +34,8 @@
ChatResult,
GenerationChunk,
)
from langchain_core.pydantic_v1 import Field, root_validator
from langchain_core.pydantic_v1 import Field, SecretStr, root_validator
from langchain_core.utils import convert_to_secret_str
from requests.exceptions import HTTPError
from tenacity import (
RetryCallState,
Expand Down Expand Up @@ -214,7 +216,7 @@ def lc_serializable(self) -> bool:
top_p: float = 0.8
"""Total probability mass of tokens to consider at each step."""

dashscope_api_key: Optional[str] = None
dashscope_api_key: Optional[SecretStr] = None
"""Dashscope api key provide by alicloud."""

n: int = 1
Expand All @@ -240,7 +242,9 @@ def _llm_type(self) -> str:
@root_validator()
def validate_environment(cls, values: Dict) -> Dict:
"""Validate that api key and python package exists in environment."""
get_from_dict_or_env(values, "dashscope_api_key", "DASHSCOPE_API_KEY")
values["dashscope_api_key"] = convert_to_secret_str(
get_from_dict_or_env(values, "dashscope_api_key", "DASHSCOPE_API_KEY")
)
try:
import dashscope
except ImportError:
Expand Down Expand Up @@ -387,7 +391,7 @@ def _create_message_dicts(
def _client_params(self) -> Dict[str, Any]:
"""Get the parameters used for the openai client."""
creds: Dict[str, Any] = {
"api_key": self.dashscope_api_key,
"api_key": cast(SecretStr, self.dashscope_api_key).get_secret_value()
}
return {**self._default_params, **creds}

Expand Down
14 changes: 9 additions & 5 deletions libs/langchain/langchain/llms/tongyi.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from __future__ import annotations

import logging
from typing import Any, Callable, Dict, List, Optional
from typing import Any, Callable, Dict, List, Optional, cast

from langchain_core.outputs import Generation, LLMResult
from langchain_core.pydantic_v1 import Field, root_validator
from langchain_core.pydantic_v1 import Field, SecretStr, root_validator
from langchain_core.utils import convert_to_secret_str
from requests.exceptions import HTTPError
from tenacity import (
before_sleep_log,
Expand Down Expand Up @@ -109,15 +110,15 @@ def is_lc_serializable(cls) -> bool:
return True

client: Any #: :meta private:
model_name: str = "qwen-plus-v1"
model_name: str = "qwen-plus"

"""Model name to use."""
model_kwargs: Dict[str, Any] = Field(default_factory=dict)

top_p: float = 0.8
"""Total probability mass of tokens to consider at each step."""

dashscope_api_key: Optional[str] = None
dashscope_api_key: Optional[SecretStr] = None
"""Dashscope api key provide by alicloud."""

n: int = 1
Expand All @@ -140,7 +141,9 @@ def _llm_type(self) -> str:
@root_validator()
def validate_environment(cls, values: Dict) -> Dict:
"""Validate that api key and python package exists in environment."""
get_from_dict_or_env(values, "dashscope_api_key", "DASHSCOPE_API_KEY")
values["dashscope_api_key"] = convert_to_secret_str(
get_from_dict_or_env(values, "dashscope_api_key", "DASHSCOPE_API_KEY")
)
try:
import dashscope
except ImportError:
Expand All @@ -164,6 +167,7 @@ def _default_params(self) -> Dict[str, Any]:
"""Get the default parameters for calling OpenAI API."""
normal_params = {
"top_p": self.top_p,
"api_key": cast(SecretStr, self.dashscope_api_key).get_secret_value(),
}

return {**normal_params, **self.model_kwargs}
Expand Down
27 changes: 19 additions & 8 deletions libs/langchain/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions libs/langchain/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ msal = {version = "^1.25.0", optional = true}
databricks-vectorsearch = {version = "^0.21", optional = true}
couchbase = {version = "^4.1.9", optional = true}
dgml-utils = {version = "^0.3.0", optional = true}
dashscope = {version = "^1.13.3", optional = true}
datasets = {version = "^2.15.0", optional = true}

[tool.poetry.group.test.dependencies]
Expand Down Expand Up @@ -336,6 +337,7 @@ extended_testing = [
"bibtexparser",
"cassio",
"chardet",
"dashscope",
"datasets",
"google-cloud-documentai",
"esprima",
Expand Down
38 changes: 38 additions & 0 deletions libs/langchain/tests/unit_tests/chat_models/test_tongyi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""
This file is to perform unit tests for Tongyi chat model.
"""

import pytest
from langchain_core.pydantic_v1 import SecretStr
from pytest import CaptureFixture, MonkeyPatch

from langchain.chat_models.tongyi import ChatTongyi


@pytest.mark.requires("dashscope")
def test_api_key_is_secret_value() -> None:
llm = ChatTongyi(dashscope_api_key="secret-api-key")
assert isinstance(llm.dashscope_api_key, SecretStr)


@pytest.mark.requires("dashscope")
def test_api_key_is_secret_pass_by_constructor(
capsys: CaptureFixture,
) -> None:
llm = ChatTongyi(dashscope_api_key="secret-api-key")
print(llm.dashscope_api_key, end="")
captured = capsys.readouterr()

assert captured.out == "**********"


@pytest.mark.requires("dashscope")
def test_api_key_is_secret_pass_by_end(
monkeypatch: MonkeyPatch, capsys: CaptureFixture
) -> None:
monkeypatch.setenv("DASHSCOPE_API_KEY", "secret-api-key")
llm = ChatTongyi()
print(llm.dashscope_api_key, end="")
captured = capsys.readouterr()

assert captured.out == "**********"
39 changes: 39 additions & 0 deletions libs/langchain/tests/unit_tests/llms/test_tongyi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""
This file is to perform unit tests for Tongyi llm.
"""

import pytest
from langchain_core.pydantic_v1 import SecretStr
from pytest import CaptureFixture, MonkeyPatch

from langchain.llms.tongyi import Tongyi

pytest.mark.requires("dashscope")


def test_api_key_is_secret_value() -> None:
llm = Tongyi(dashscope_api_key="secret-key-api")
assert isinstance(llm.dashscope_api_key, SecretStr)


@pytest.mark.requires("dashscope")
def test_api_key_is_secret_value_pass_by_constructor(
capsys: CaptureFixture,
) -> None:
llm = Tongyi(dashscope_api_key="secret-key-api")
print(llm.dashscope_api_key, end="")
captured = capsys.readouterr()

assert captured.out == "**********"


@pytest.mark.requires("dashscope")
def test_api_key_is_secret_value_pass_by_end(
capsys: CaptureFixture, monkeypatch: MonkeyPatch
) -> None:
monkeypatch.setenv("DASHSCOPE_API_KEY", "secret-api-key")
llm = Tongyi()
print(llm.dashscope_api_key, end="")
captured = capsys.readouterr()

assert captured.out == "**********"
Loading