Skip to content

Commit

Permalink
ibm[major]: release 0.2 (#20)
Browse files Browse the repository at this point in the history
* delete check_pydantic script

* extra_migrate

* to_pydantic_2

* model_after_rewrite

* Self

* update deps and increment version

* format

* clean up

* update model validation to pre

* update more model_validators to pre

* get item --> .get()

* set protected namespaces on embeddings

* fix
  • Loading branch information
ccurme authored Sep 16, 2024
1 parent 4688770 commit 73ebbe5
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 137 deletions.
68 changes: 41 additions & 27 deletions libs/ibm/langchain_ibm/chat_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,20 @@
)
from langchain_core.outputs import ChatGeneration, ChatGenerationChunk, ChatResult
from langchain_core.prompt_values import ChatPromptValue
from langchain_core.pydantic_v1 import BaseModel, Field, SecretStr, root_validator
from langchain_core.runnables import Runnable, RunnableMap, RunnablePassthrough
from langchain_core.tools import BaseTool
from langchain_core.utils import convert_to_secret_str, get_from_dict_or_env
from langchain_core.utils.function_calling import (
convert_to_openai_function,
convert_to_openai_tool,
)
from pydantic import (
BaseModel,
ConfigDict,
Field,
SecretStr,
model_validator,
)

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -374,10 +380,9 @@ class ChatWatsonx(BaseChatModel):

watsonx_model: ModelInference = Field(default=None, exclude=True) #: :meta private:

class Config:
"""Configuration for this pydantic object."""

allow_population_by_field_name = True
model_config = ConfigDict(
populate_by_name=True,
)

@classmethod
def is_lc_serializable(cls) -> bool:
Expand Down Expand Up @@ -420,8 +425,9 @@ def lc_secrets(self) -> Dict[str, str]:
"instance_id": "WATSONX_INSTANCE_ID",
}

@root_validator(pre=False, skip_on_failure=True)
def validate_environment(cls, values: Dict) -> Dict:
@model_validator(mode="before")
@classmethod
def validate_environment(cls, values: Dict) -> Any:
"""Validate that credentials and python package exists in environment."""
values["url"] = convert_to_secret_str(
get_from_dict_or_env(values, "url", "WATSONX_URL")
Expand All @@ -432,11 +438,11 @@ def validate_environment(cls, values: Dict) -> Dict:
)
else:
if (
not values["token"]
not values.get("token")
and "WATSONX_TOKEN" not in os.environ
and not values["password"]
and not values.get("password")
and "WATSONX_PASSWORD" not in os.environ
and not values["apikey"]
and not values.get("apikey")
and "WATSONX_APIKEY" not in os.environ
):
raise ValueError(
Expand All @@ -447,54 +453,62 @@ def validate_environment(cls, values: Dict) -> Dict:
" or pass 'token', 'password' or 'apikey'"
" as a named parameter."
)
elif values["token"] or "WATSONX_TOKEN" in os.environ:
elif values.get("token") or "WATSONX_TOKEN" in os.environ:
values["token"] = convert_to_secret_str(
get_from_dict_or_env(values, "token", "WATSONX_TOKEN")
)
elif values["password"] or "WATSONX_PASSWORD" in os.environ:
elif values.get("password") or "WATSONX_PASSWORD" in os.environ:
values["password"] = convert_to_secret_str(
get_from_dict_or_env(values, "password", "WATSONX_PASSWORD")
)
values["username"] = convert_to_secret_str(
get_from_dict_or_env(values, "username", "WATSONX_USERNAME")
)
elif values["apikey"] or "WATSONX_APIKEY" in os.environ:
elif values.get("apikey") or "WATSONX_APIKEY" in os.environ:
values["apikey"] = convert_to_secret_str(
get_from_dict_or_env(values, "apikey", "WATSONX_APIKEY")
)
values["username"] = convert_to_secret_str(
get_from_dict_or_env(values, "username", "WATSONX_USERNAME")
)
if not values["instance_id"] or "WATSONX_INSTANCE_ID" not in os.environ:
if not values.get("instance_id") or "WATSONX_INSTANCE_ID" not in os.environ:
values["instance_id"] = convert_to_secret_str(
get_from_dict_or_env(values, "instance_id", "WATSONX_INSTANCE_ID")
)
credentials = Credentials(
url=values["url"].get_secret_value() if values["url"] else None,
api_key=values["apikey"].get_secret_value() if values["apikey"] else None,
token=values["token"].get_secret_value() if values["token"] else None,
url=values["url"].get_secret_value() if values.get("url") else None,
api_key=values["apikey"].get_secret_value()
if values.get("apikey")
else None,
token=values["token"].get_secret_value() if values.get("token") else None,
password=(
values["password"].get_secret_value() if values["password"] else None
values["password"].get_secret_value()
if values.get("password")
else None
),
username=(
values["username"].get_secret_value() if values["username"] else None
values["username"].get_secret_value()
if values.get("username")
else None
),
instance_id=(
values["instance_id"].get_secret_value()
if values["instance_id"]
if values.get("instance_id")
else None
),
version=values["version"].get_secret_value() if values["version"] else None,
verify=values["verify"],
version=values["version"].get_secret_value()
if values.get("version")
else None,
verify=values.get("verify"),
)

watsonx_chat = ModelInference(
model_id=values["model_id"],
deployment_id=values["deployment_id"],
model_id=values.get("model_id", ""),
deployment_id=values.get("deployment_id", ""),
credentials=credentials,
params=values["params"],
project_id=values["project_id"],
space_id=values["space_id"],
params=values.get("params"),
project_id=values.get("project_id", ""),
space_id=values.get("space_id", ""),
)
values["watsonx_model"] = watsonx_chat

Expand Down
80 changes: 43 additions & 37 deletions libs/ibm/langchain_ibm/embeddings.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import os
from typing import Dict, List, Optional, Union
from typing import Any, Dict, List, Optional, Union

from ibm_watsonx_ai import APIClient, Credentials # type: ignore
from ibm_watsonx_ai.foundation_models.embeddings import Embeddings # type: ignore
from langchain_core.embeddings import Embeddings as LangChainEmbeddings
from langchain_core.pydantic_v1 import (
from langchain_core.utils import convert_to_secret_str, get_from_dict_or_env
from pydantic import (
BaseModel,
Extra,
ConfigDict,
Field,
SecretStr,
root_validator,
model_validator,
)
from langchain_core.utils import convert_to_secret_str, get_from_dict_or_env


class WatsonxEmbeddings(BaseModel, LangChainEmbeddings):
Expand Down Expand Up @@ -61,23 +61,24 @@ class WatsonxEmbeddings(BaseModel, LangChainEmbeddings):

watsonx_client: APIClient = Field(default=None) #: :meta private:

class Config:
"""Configuration for this pydantic object."""

extra = Extra.forbid
arbitrary_types_allowed = True
model_config = ConfigDict(
extra="forbid",
arbitrary_types_allowed=True,
protected_namespaces=(),
)

@root_validator(pre=False, skip_on_failure=True)
def validate_environment(cls, values: Dict) -> Dict:
@model_validator(mode="before")
@classmethod
def validate_environment(cls, values: Dict) -> Any:
"""Validate that credentials and python package exists in environment."""
if isinstance(values.get("watsonx_client"), APIClient):
watsonx_embed = Embeddings(
model_id=values["model_id"],
params=values["params"],
api_client=values["watsonx_client"],
project_id=values["project_id"],
space_id=values["space_id"],
verify=values["verify"],
model_id=values.get("model_id", ""),
params=values.get("params"),
api_client=values.get("watsonx_client"),
project_id=values.get("project_id", ""),
space_id=values.get("space_id", ""),
verify=values.get("verify"),
)
values["watsonx_embed"] = watsonx_embed

Expand All @@ -91,11 +92,11 @@ def validate_environment(cls, values: Dict) -> Dict:
)
else:
if (
not values["token"]
not values.get("token")
and "WATSONX_TOKEN" not in os.environ
and not values["password"]
and not values.get("password")
and "WATSONX_PASSWORD" not in os.environ
and not values["apikey"]
and not values.get("apikey")
and "WATSONX_APIKEY" not in os.environ
):
raise ValueError(
Expand All @@ -106,58 +107,63 @@ def validate_environment(cls, values: Dict) -> Dict:
" or pass 'token', 'password' or 'apikey'"
" as a named parameter."
)
elif values["token"] or "WATSONX_TOKEN" in os.environ:
elif values.get("token") or "WATSONX_TOKEN" in os.environ:
values["token"] = convert_to_secret_str(
get_from_dict_or_env(values, "token", "WATSONX_TOKEN")
)
elif values["password"] or "WATSONX_PASSWORD" in os.environ:
elif values.get("password") or "WATSONX_PASSWORD" in os.environ:
values["password"] = convert_to_secret_str(
get_from_dict_or_env(values, "password", "WATSONX_PASSWORD")
)
values["username"] = convert_to_secret_str(
get_from_dict_or_env(values, "username", "WATSONX_USERNAME")
)
elif values["apikey"] or "WATSONX_APIKEY" in os.environ:
elif values.get("apikey") or "WATSONX_APIKEY" in os.environ:
values["apikey"] = convert_to_secret_str(
get_from_dict_or_env(values, "apikey", "WATSONX_APIKEY")
)
values["username"] = convert_to_secret_str(
get_from_dict_or_env(values, "username", "WATSONX_USERNAME")
)
if not values["instance_id"] or "WATSONX_INSTANCE_ID" not in os.environ:
if (
not values.get("instance_id")
or "WATSONX_INSTANCE_ID" not in os.environ
):
values["instance_id"] = convert_to_secret_str(
get_from_dict_or_env(
values, "instance_id", "WATSONX_INSTANCE_ID"
)
)

credentials = Credentials(
url=values["url"].get_secret_value() if values["url"] else None,
url=values["url"].get_secret_value() if values.get("url") else None,
api_key=values["apikey"].get_secret_value()
if values["apikey"]
if values.get("apikey")
else None,
token=values["token"].get_secret_value()
if values.get("token")
else None,
token=values["token"].get_secret_value() if values["token"] else None,
password=values["password"].get_secret_value()
if values["password"]
if values.get("password")
else None,
username=values["username"].get_secret_value()
if values["username"]
if values.get("username")
else None,
instance_id=values["instance_id"].get_secret_value()
if values["instance_id"]
if values.get("instance_id")
else None,
version=values["version"].get_secret_value()
if values["version"]
if values.get("version")
else None,
verify=values["verify"],
verify=values.get("verify"),
)

watsonx_embed = Embeddings(
model_id=values["model_id"],
params=values["params"],
model_id=values.get("model_id", ""),
params=values.get("params"),
credentials=credentials,
project_id=values["project_id"],
space_id=values["space_id"],
project_id=values.get("project_id", ""),
space_id=values.get("space_id", ""),
)

values["watsonx_embed"] = watsonx_embed
Expand Down
Loading

0 comments on commit 73ebbe5

Please sign in to comment.