"""Test for Serializable base class""" from typing import Any, Dict import pytest from langchain.callbacks.tracers.langchain import LangChainTracer from langchain.chains.llm import LLMChain from langchain.chat_models.openai import ChatOpenAI from langchain.llms.openai import OpenAI from langchain.load.dump import dumps from langchain.load.serializable import Serializable from langchain.prompts.chat import ChatPromptTemplate, HumanMessagePromptTemplate from langchain.prompts.prompt import PromptTemplate class Person(Serializable): secret: str you_can_see_me: str = "hello" @property def lc_serializable(self) -> bool: return True @property def lc_secrets(self) -> Dict[str, str]: return {"secret": "SECRET"} @property def lc_attributes(self) -> Dict[str, str]: return {"you_can_see_me": self.you_can_see_me} class SpecialPerson(Person): another_secret: str another_visible: str = "bye" # Gets merged with parent class's secrets @property def lc_secrets(self) -> Dict[str, str]: return {"another_secret": "ANOTHER_SECRET"} # Gets merged with parent class's attributes @property def lc_attributes(self) -> Dict[str, str]: return {"another_visible": self.another_visible} class NotSerializable: pass def test_person(snapshot: Any) -> None: p = Person(secret="hello") assert dumps(p, pretty=True) == snapshot sp = SpecialPerson(another_secret="Wooo", secret="Hmm") assert dumps(sp, pretty=True) == snapshot @pytest.mark.requires("openai") def test_serialize_openai_llm(snapshot: Any) -> None: llm = OpenAI( model="davinci", temperature=0.5, openai_api_key="hello", # This is excluded from serialization callbacks=[LangChainTracer()], ) llm.temperature = 0.7 # this is reflected in serialization assert dumps(llm, pretty=True) == snapshot @pytest.mark.requires("openai") def test_serialize_llmchain(snapshot: Any) -> None: llm = OpenAI(model="davinci", temperature=0.5, openai_api_key="hello") prompt = PromptTemplate.from_template("hello {name}!") chain = LLMChain(llm=llm, prompt=prompt) assert dumps(chain, pretty=True) == snapshot @pytest.mark.requires("openai") def test_serialize_llmchain_env() -> None: llm = OpenAI(model="davinci", temperature=0.5, openai_api_key="hello") prompt = PromptTemplate.from_template("hello {name}!") chain = LLMChain(llm=llm, prompt=prompt) import os has_env = "OPENAI_API_KEY" in os.environ if not has_env: os.environ["OPENAI_API_KEY"] = "env_variable" llm_2 = OpenAI(model="davinci", temperature=0.5) prompt_2 = PromptTemplate.from_template("hello {name}!") chain_2 = LLMChain(llm=llm_2, prompt=prompt_2) assert dumps(chain_2, pretty=True) == dumps(chain, pretty=True) if not has_env: del os.environ["OPENAI_API_KEY"] @pytest.mark.requires("openai") def test_serialize_llmchain_chat(snapshot: Any) -> None: llm = ChatOpenAI(model="davinci", temperature=0.5, openai_api_key="hello") prompt = ChatPromptTemplate.from_messages( [HumanMessagePromptTemplate.from_template("hello {name}!")] ) chain = LLMChain(llm=llm, prompt=prompt) assert dumps(chain, pretty=True) == snapshot import os has_env = "OPENAI_API_KEY" in os.environ if not has_env: os.environ["OPENAI_API_KEY"] = "env_variable" llm_2 = ChatOpenAI(model="davinci", temperature=0.5) prompt_2 = ChatPromptTemplate.from_messages( [HumanMessagePromptTemplate.from_template("hello {name}!")] ) chain_2 = LLMChain(llm=llm_2, prompt=prompt_2) assert dumps(chain_2, pretty=True) == dumps(chain, pretty=True) if not has_env: del os.environ["OPENAI_API_KEY"] @pytest.mark.requires("openai") def test_serialize_llmchain_with_non_serializable_arg(snapshot: Any) -> None: llm = OpenAI( model="davinci", temperature=0.5, openai_api_key="hello", client=NotSerializable, ) prompt = PromptTemplate.from_template("hello {name}!") chain = LLMChain(llm=llm, prompt=prompt) assert dumps(chain, pretty=True) == snapshot