Skip to content

Commit

Permalink
Update pydantic compatibility message, and add one to openapi docs as…
Browse files Browse the repository at this point in the history
… well (#243)

Surfacing the pydantic compatibility message in open api docs as well to
help users!

This PR adds a warning message to the openapi docs when using pydantic
v2:

![image](https://github.com/langchain-ai/langserve/assets/3205522/729eeeea-7fbd-49d7-b21a-62b5903d9714)
  • Loading branch information
eyurtsev authored Nov 17, 2023
1 parent 286d254 commit d8ffff9
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 16 deletions.
14 changes: 11 additions & 3 deletions langserve/pydantic_v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,21 @@

try:
# F401: imported but unused
from pydantic.v1 import BaseModel, Field, ValidationError # noqa: F401
from pydantic.v1 import ( # noqa: F401
BaseModel,
Field,
ValidationError,
create_model,
)
except ImportError:
from pydantic import BaseModel, Field, ValidationError # noqa: F401
from pydantic import BaseModel, Field, ValidationError, create_model # noqa: F401


# This is not a pydantic v1 thing, but it feels too small to create a new module for.

PYDANTIC_VERSION = metadata.version("pydantic")

try:
_PYDANTIC_MAJOR_VERSION: int = int(metadata.version("pydantic").split(".")[0])
_PYDANTIC_MAJOR_VERSION: int = int(PYDANTIC_VERSION.split(".")[0])
except metadata.PackageNotFoundError:
_PYDANTIC_MAJOR_VERSION = -1
59 changes: 46 additions & 13 deletions langserve/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,17 @@
from langsmith.utils import tracing_is_enabled
from typing_extensions import Annotated

try:
from pydantic.v1 import BaseModel, Field, ValidationError, create_model
except ImportError:
from pydantic import BaseModel, Field, ValidationError, create_model

from langserve.callbacks import AsyncEventAggregatorCallback, CallbackEventDict
from langserve.lzstring import LZString
from langserve.playground import serve_playground
from langserve.pydantic_v1 import _PYDANTIC_MAJOR_VERSION
from langserve.pydantic_v1 import (
_PYDANTIC_MAJOR_VERSION,
PYDANTIC_VERSION,
BaseModel,
Field,
ValidationError,
create_model,
)
from langserve.schema import (
BatchResponseMetadata,
CustomUserType,
Expand Down Expand Up @@ -306,11 +308,15 @@ def orange(text: str) -> str:

if _PYDANTIC_MAJOR_VERSION == 2:
print()
print(f'{orange("OpenAPI Docs:")} ', end="")
print(f'{orange("LANGSERVE:")} ', end="")
print(
"Running with pydantic >= 2: OpenAPI docs for "
"invoke/batch/stream/stream_log` endpoints will not be "
"generated; but, API endpoints and playground will work as expected."
f"⚠️ Using pydantic {PYDANTIC_VERSION}. "
f"OpenAPI docs for invoke, batch, stream, stream_log "
f"endpoints will not be generated. API endpoints and playground "
f"should work as expected. "
f"If you need to see the docs, you can downgrade to pydantic 1. "
"For example, `pip install pydantic==1.10.13`. "
f"See https://github.com/tiangolo/fastapi/issues/10360 for details."
)
print()

Expand Down Expand Up @@ -525,11 +531,38 @@ def _route_name_with_config(name: str) -> str:
if hasattr(app, "openapi_tags") and (path or (app not in _APP_SEEN)):
if not path:
_APP_SEEN.add(app)

if _PYDANTIC_MAJOR_VERSION == 1:
# Documentation for the default endpoints
default_endpoint_tags = {
"name": route_tags[0] if route_tags else "default",
}
elif _PYDANTIC_MAJOR_VERSION == 2:
# When using pydantic v2, we cannot generate openapi docs for
# the invoke/batch/stream/stream_log endpoints since the underlying
# models are from the pydantic.v1 namespace and cannot be supported
# by fastapi's.
# https://github.com/tiangolo/fastapi/issues/10360
default_endpoint_tags = {
"name": route_tags[0] if route_tags else "default",
"description": (
f"⚠️ Using pydantic {PYDANTIC_VERSION}. "
f"OpenAPI docs for `invoke`, `batch`, `stream`, `stream_log` "
f"endpoints will not be generated. API endpoints and playground "
f"should work as expected. "
f"If you need to see the docs, you can downgrade to pydantic 1. "
"For example, `pip install pydantic==1.10.13`"
f"See https://github.com/tiangolo/fastapi/issues/10360 for details."
),
}
else:
raise AssertionError(
f"Expected pydantic major version 1 or 2, got {_PYDANTIC_MAJOR_VERSION}"
)

app.openapi_tags = [
*(getattr(app, "openapi_tags", []) or []),
{
"name": route_tags[0] if route_tags else "default",
},
default_endpoint_tags,
{
"name": route_tags_with_config[0],
"description": (
Expand Down

0 comments on commit d8ffff9

Please sign in to comment.