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

Value not declarable with JSON Schema (Pydantic V2) #690

Open
JP-Ellis opened this issue Jun 20, 2024 · 9 comments
Open

Value not declarable with JSON Schema (Pydantic V2) #690

JP-Ellis opened this issue Jun 20, 2024 · 9 comments

Comments

@JP-Ellis
Copy link

Summary

I am unable to get LangServe to work nicely with a Pydantic V2 model.

Background

I understand that LangChain and LangServe are undergoing an upgrade from Pydantic V1 to V2. I was under the impression that LangServe supports V2 models, with the one caveat that OpenAPI docs aren't presently generated.

Example

Here is a simple reproducible example of the error, along with all installed dependencies and the error logs. The TL;DR is:

  • Dependencies:
    • langchain-core==0.2.9
    • langserve==0.2.2
    • pydantic==2.7.4
  • Error:
    raise ValueError(f'Value not declarable with JSON Schema, field: {field}')
    ValueError: Value not declarable with JSON Schema, field: name='__root__' type=Optional[ExampleInput] required=False default=None
    
Virtual Environment
❯ which python
/Users/JP-Ellis/tmp/.venv/bin/python

❯ python --version
Python 3.12.4

❯ uv pip install fastapi langchain_core langserve pydantic sse_starlette
Resolved 55 packages in 36ms
Installed 55 packages in 44ms
 + annotated-types==0.7.0
 + anyio==4.4.0
 + attrs==23.2.0
 + certifi==2024.6.2
 + charset-normalizer==3.3.2
 + click==8.1.7
 + dnspython==2.6.1
 + email-validator==2.1.2
 + fastapi==0.111.0
 + fastapi-cli==0.0.4
 + h11==0.14.0
 + httpcore==1.0.5
 + httptools==0.6.1
 + httpx==0.27.0
 + idna==3.7
 + jinja2==3.1.4
 + jsonpatch==1.33
 + jsonpointer==3.0.0
 + jsonschema==4.22.0
 + jsonschema-specifications==2023.12.1
 + langchain-core==0.2.9
 + langserve==0.2.2
 + langsmith==0.1.81
 + markdown-it-py==3.0.0
 + markupsafe==2.1.5
 + mdurl==0.1.2
 + orjson==3.10.5
 + packaging==24.1
 + pydantic==2.7.4
 + pydantic-core==2.18.4
 + pygments==2.18.0
 + pyproject-toml==0.0.10
 + python-dotenv==1.0.1
 + python-multipart==0.0.9
 + pyyaml==6.0.1
 + referencing==0.35.1
 + requests==2.32.3
 + rich==13.7.1
 + rpds-py==0.18.1
 + setuptools==70.1.0
 + shellingham==1.5.4
 + sniffio==1.3.1
 + sse-starlette==2.1.2
 + starlette==0.37.2
 + tenacity==8.4.1
 + toml==0.10.2
 + typer==0.12.3
 + typing-extensions==4.12.2
 + ujson==5.10.0
 + urllib3==2.2.2
 + uvicorn==0.30.1
 + uvloop==0.19.0
 + watchfiles==0.22.0
 + websockets==12.0
 + wheel==0.43.0
example.py
from fastapi import APIRouter
from langchain_core.runnables import Runnable, RunnableConfig
from langserve import add_routes
from pydantic import BaseModel

router = APIRouter()


class ExampleInput(BaseModel):
    foo: str


class ExampleOutput(BaseModel):
    bar: str


class ExampleGenerator(Runnable[ExampleInput, ExampleOutput]):
    def invoke(
        self, input: ExampleInput, config: RunnableConfig | None = None
    ) -> ExampleOutput:
        return ExampleOutput(bar=f"Received foo={input.foo}")


add_routes(
    router,
    ExampleGenerator(),
    path="/example",
)
Error logs
❯ python example.py
Traceback (most recent call last):
  File "/Users/JP-Ellis/tmp/example.py", line 26, in <module>
    add_routes(
  File "/Users/JP-Ellis/tmp/.venv/lib/python3.12/site-packages/langserve/server.py", line 443, in add_routes
    api_handler = APIHandler(
                  ^^^^^^^^^^^
  File "/Users/JP-Ellis/tmp/.venv/lib/python3.12/site-packages/langserve/api_handler.py", line 667, in __init__
    input_type_ = _resolve_model(
                  ^^^^^^^^^^^^^^^
  File "/Users/JP-Ellis/tmp/.venv/lib/python3.12/site-packages/langserve/api_handler.py", line 338, in _resolve_model
    hash_ = model.schema_json()
            ^^^^^^^^^^^^^^^^^^^
  File "/Users/JP-Ellis/tmp/.venv/lib/python3.12/site-packages/pydantic/v1/main.py", line 675, in schema_json
    cls.schema(by_alias=by_alias, ref_template=ref_template), default=pydantic_encoder, **dumps_kwargs
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JP-Ellis/tmp/.venv/lib/python3.12/site-packages/pydantic/v1/main.py", line 664, in schema
    s = model_schema(cls, by_alias=by_alias, ref_template=ref_template)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JP-Ellis/tmp/.venv/lib/python3.12/site-packages/pydantic/v1/schema.py", line 188, in model_schema
    m_schema, m_definitions, nested_models = model_process_schema(
                                             ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JP-Ellis/tmp/.venv/lib/python3.12/site-packages/pydantic/v1/schema.py", line 581, in model_process_schema
    m_schema, m_definitions, nested_models = model_type_schema(
                                             ^^^^^^^^^^^^^^^^^^
  File "/Users/JP-Ellis/tmp/.venv/lib/python3.12/site-packages/pydantic/v1/schema.py", line 622, in model_type_schema
    f_schema, f_definitions, f_nested_models = field_schema(
                                               ^^^^^^^^^^^^^
  File "/Users/JP-Ellis/tmp/.venv/lib/python3.12/site-packages/pydantic/v1/schema.py", line 255, in field_schema
    f_schema, f_definitions, f_nested_models = field_type_schema(
                                               ^^^^^^^^^^^^^^^^^^
  File "/Users/JP-Ellis/tmp/.venv/lib/python3.12/site-packages/pydantic/v1/schema.py", line 527, in field_type_schema
    f_schema, f_definitions, f_nested_models = field_singleton_schema(
                                               ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/JP-Ellis/tmp/.venv/lib/python3.12/site-packages/pydantic/v1/schema.py", line 951, in field_singleton_schema
    raise ValueError(f'Value not declarable with JSON Schema, field: {field}')
ValueError: Value not declarable with JSON Schema, field: name='__root__' type=Optional[ExampleInput] required=False default=None
@eyurtsev
Copy link
Collaborator

eyurtsev commented Jun 20, 2024

LangChain does not currently support pydantic 2 models. If you're using pydantic 2, you need to use the pydantic.v1 namespace

Do this in your code;

from pydantic.v1 import BaseModel

@JP-Ellis
Copy link
Author

JP-Ellis commented Jun 26, 2024

Is there a tracking issue for when LangServe will support Pydantic 2? Or is there a way to use the pydantic.v1 namespace in Pydantic V2 installations?

I'm asking because I have found that the most recent release of LangChain no longer support Pydantic V1 at all due to this commit which introduced the following change to the langchain-core dependency:

pydantic = [
  { version = ">=1,<3", python =  "<3.12.4" },
  { version = "^2.7.4", python = ">=3.12.4" },
]

@eyurtsev
Copy link
Collaborator

Use pydantic.v1 right now with pydantic 2. We first need to migrate langchain to support pydantic 2 proper (rather than from the v1 namespace).

@JP-Ellis
Copy link
Author

Unfortunately, using the pydantic.v1 namespace does not work for me at the moment, due to some mix up between V1 and V2 functions deep in dependencies which I would rather avoid monkey-patching. Happy to raise another issue to track that specifically if you want.

@eyurtsev
Copy link
Collaborator

Is it coming from langchain dependencies or another dependency?

@JP-Ellis
Copy link
Author

JP-Ellis commented Jul 4, 2024

In my case, it comes from the underlying FastAPI dependency. I am getting the same error as reported in:

Let me see if I can generate a minimal example within LangChain's context.

EDIT: On investigating the issue, I have confirmed it is identical to the example documented above. This does raise another question though: if FastAPI doesn't support Pydantic V1 models, how is LangServe able to avoid this very issue?

Having said all this, I am happy for you to close this issue (or keep it open for visibility, until Pydantic V2 is fully supported?)

@codekiln
Copy link

codekiln commented Aug 4, 2024

Just now saw this issue, which is very similar to the one I just filed - #725. In my case, the only reason I upgraded was that I need to update langchain-core, which was holding back many of my other lang* libraries. In order to do that, I needed to update pydantic to 2.x. I tried converting all models to from langchain.pydantic_v1 import ..., but then I discovered FastAPI was incompatible with having 2.x installed and using 1.x models; specifically, I was getting fastapi basemodel.validate() takes 2 positional arguments but 3 were given in my middleware on every request when I tried that.

@eyurtsev
Copy link
Collaborator

eyurtsev commented Aug 7, 2024

Hi this is a documented limitation currently. Please hold off until LangChain 0.3.x. If you want to use pydantic proper 2. You can use pydantic.v1 namespace but FastAPI does not support it.

https://github.com/langchain-ai/langserve?tab=readme-ov-file#pydantic
https://github.com/langchain-ai/langserve?tab=readme-ov-file#limitations
https://python.langchain.com/v0.2/docs/how_to/pydantic_compatibility/#4-langserve-cannot-generate-openapi-docs-if-running-pydantic-2

@Abd-elr4hman
Copy link

how can one help with moving langchain to pydantic v2 ? can you point me towards a good starting point to get started ?
@eyurtsev

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants