You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Most LangChain APIs that accept Pydantic objects have been updated to accept both Pydantic v1 and v2 objects.
After langchain-core>=0.2.23, use either Pydantic v1 or v2 objects when passing to LangChain APIs.
If you are still seeing issues with these APIs or other APIs that accept Pydantic objects, please open an issue, and we'll address it.
I think there is an issue with Langserve's API not accepting chains with v2 pydantic objects. See below for reproduction criteria pytest, particularly around the lines with pytest.raises(RuntimeError) as re, which occur when calling add_routes when passing chains with input types declared with pydantic v2 models.
As far as I can tell, due to FastAPI's lack of actual support for v1 and v2 pydantic models coexisting, it seems like the only solution is to use an older version of langchain-core that supports the pydantic v1 langserve requires?
$ poetry show pydantic | grep version
version : 2.8.2
$ poetry show langchain-core | grep version
version : 0.2.28
$ poetry show langchain-core | grep pydantic
- pydantic >=1,<3
- pydantic >=2.7.4,<3.0.0
$ poetry show fastapi | grep version
version : 0.112.0
The docstring to langserve's add_routes states with respect to input_type: Union[Type, Literal["auto"], BaseModel] = "auto",
input_type: type to use for input validation.
Default is "auto" which will use the InputType of the runnable.
User is free to provide a custom type annotation.
Favor using runnable.with_types(input_type=..., output_type=...) instead.
This parameter may get deprecated!
So instead of defining this parameter, I put on my chain,
chain.with_types(input_type=ChatHistoryInput)
before passing it to add_routes, but then it ends up erroring in langserve.api_handler._resolve_model, which calls:
which for me, at least, it falling into the else branch, with
because it's failing the issubclass check:
Error signature:
RuntimeError: no validator found for <class <path.to.class>>, see `arbitrary_types_allowed` in Config
ChatHistoryInput adheres to pydantic 2.8's documentation with respect to arbitrary_types_allowed - ConfigDict - pydantic 2.8, so I don't think this is the actual issue; instead, I think the issue is that both BaseModel and create_model are getting imported from pydantic v1, not pydantic v2, in spite of pydantic v2 being loaded.
I've seen π¦οΈπ LangServe | π¦οΈπ LangChain mentions that LangChain uses the v1 namespace in pydantic v2, links back to the former page, but it seems like the issue is that langchain-core is now requiring pydantic v2, but langserve is requiring pydantic v1.
Perhaps langserve 0.2.2's pyproject.toml should have a dependency of `langchain-core = ">=0.1,<0.2.23" instead of langchain-core = ">=0.1,<0.3"?
Reproduction Criteria - pytest
Here is a pytest that reproduces the observations above:
fromtypingimportAnnotatedimportlangserveimportpydanticimportpytestfromfastapiimportFastAPIfromlangchain_core.messagesimportBaseMessagefromlangchain_core.promptsimportChatPromptTemplate, MessagesPlaceholderfromlangchain_core.runnablesimportRunnableLambdafromlangserveimportadd_routes, pydantic_v1frompydanticimportSkipValidationchat_history_stringifier=ChatPromptTemplate.from_messages(
[MessagesPlaceholder("chat_history")]
) |RunnableLambda(lambdax: x.to_string())
deftest_arbitrary_types_allowed_pydantic_error_model_config() ->None:
""" test that using a pydantic 2 model with arbitrary_types_allowed=False raises an error when being added to a FastAPI app with langserve's add_routes function due to langserve's use of pydantic 1 """assertpydantic_v1.PYDANTIC_VERSION.startswith("2.")
classChatHistoryInput(pydantic.BaseModel):
model_config=pydantic.ConfigDict(arbitrary_types_allowed=True)
# follow the guidance# [How to use LangChain with different Pydantic versions | π¦οΈπ LangChain](https://python.langchain.com/v0.2/docs/how_to/pydantic_compatibility/#3-disable-run-time-validation-for-langchain-objects-used-inside-pydantic-v2-models)# - [](https://api.python.langchain.com/en/latest/tools/langchain_core.tools.BaseTool.html)# - - 3\. Disable run-time validation for LangChain objects used inside Pydantic v2 modelschat_history: Annotated[list[BaseMessage], SkipValidation()] =pydantic.Field(
...,
description="The chat messages representing the current conversation.",
)
input_typed_chat_history_stringifier=chat_history_stringifier.with_types(
input_type=ChatHistoryInput
)
app=FastAPI()
withpytest.raises(RuntimeError) asre:
add_routes(app, input_typed_chat_history_stringifier)
error_text=str(re.value)
asserterror_text.startswith("no validator found for <class ")
asserterror_text.endswith("see `arbitrary_types_allowed` in Config")
deftest_arbitrary_types_allowed_pydantic_error_classic_config() ->None:
""" Using the classic config returns the same error as using the model_config """assertpydantic_v1.PYDANTIC_VERSION.startswith("2.")
classChatHistoryInput(pydantic.BaseModel):
# > raise PydanticUserError('"Config" and "model_config" cannot be used together', code='config-both')# model_config = pydantic.ConfigDict(arbitrary_types_allowed=True)# follow the guidance# [How to use LangChain with different Pydantic versions | π¦οΈπ LangChain](https://python.langchain.com/v0.2/docs/how_to/pydantic_compatibility/#3-disable-run-time-validation-for-langchain-objects-used-inside-pydantic-v2-models)# - [](https://api.python.langchain.com/en/latest/tools/langchain_core.tools.BaseTool.html)# - - 3\. Disable run-time validation for LangChain objects used inside Pydantic v2 modelschat_history: Annotated[list[BaseMessage], SkipValidation()] =pydantic.Field(
...,
description="The chat messages representing the current conversation.",
)
classConfig:
arbitrary_types_allowed=Trueinput_typed_chat_history_stringifier=chat_history_stringifier.with_types(
input_type=ChatHistoryInput
)
app=FastAPI()
withpytest.raises(RuntimeError) asre:
add_routes(app, input_typed_chat_history_stringifier)
error_text=str(re.value)
asserterror_text.startswith("no validator found for <class ")
asserterror_text.endswith("see `arbitrary_types_allowed` in Config")
The text was updated successfully, but these errors were encountered:
codekiln
changed the title
Error - chains with input types of Pydantic v2 models causing an error even though pydantic 2.8 is loaded
RuntimeError calling add_routes with chains that have input types in Pydantic v2
Aug 4, 2024
in order to try to adjust to langchain-core's new requirement for pydantic > 2.7.4,
langchain-core should not have any requirements on pydantic at the moment -- it allows installing either pydantic 1 or 2. Could you tell me where you are seeing this?
tl;dr
How to use LangChain with different Pydantic versions | π¦οΈπ LangChain says
I think there is an issue with Langserve's API not accepting chains with v2 pydantic objects. See below for reproduction criteria pytest, particularly around the lines
with pytest.raises(RuntimeError) as re
, which occur when callingadd_routes
when passing chains with input types declared with pydantic v2 models.As far as I can tell, due to FastAPI's lack of actual support for v1 and v2 pydantic models coexisting, it seems like the only solution is to use an older version of langchain-core that supports the pydantic v1 langserve requires?
Details
I'm attempting to upgrade a set of langserve endpoints to pydantic 2.8, in order to try to adjust to
langchain-core
's new requirement for pydantic > 2.7.4, and trying to cope with V1 models for response and body by chbndrhnns Β· Pull Request #10223 Β· fastapi/fastapi not being merged into FastAPI yet in a way that solves the errors described in its other issue, Working with Pydantic v1 while having v2 installed Β· Issue #10360 Β· fastapi/fastapi.I have a pydantic v2's
pydantic.BaseModel
.The docstring to langserve's
add_routes
states with respect toinput_type: Union[Type, Literal["auto"], BaseModel] = "auto",
So instead of defining this parameter, I put on my chain,
before passing it to
add_routes
, but then it ends up erroring inlangserve.api_handler._resolve_model
, which calls:which for me, at least, it falling into the
else
branch, withbecause it's failing the
issubclass
check:Error signature:
ChatHistoryInput
adheres to pydantic 2.8's documentation with respect to arbitrary_types_allowed - ConfigDict - pydantic 2.8, so I don't think this is the actual issue; instead, I think the issue is that bothBaseModel
andcreate_model
are getting imported from pydantic v1, not pydantic v2, in spite of pydantic v2 being loaded.I've seen how How to use LangChain with different Pydantic versions | π¦οΈπ LangChain mentions that the OpenAPI docs page won't work for pydantic v2 models.
I've seen π¦οΈπ LangServe | π¦οΈπ LangChain mentions that LangChain uses the v1 namespace in pydantic v2, links back to the former page, but it seems like the issue is that
langchain-core
is now requiring pydantic v2, but langserve is requiring pydantic v1.Perhaps langserve 0.2.2's pyproject.toml should have a dependency of `langchain-core = ">=0.1,<0.2.23" instead of langchain-core = ">=0.1,<0.3"?
Reproduction Criteria - pytest
Here is a pytest that reproduces the observations above:
The text was updated successfully, but these errors were encountered: