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

Update pydantic compatibility message, and add one to openapi docs as well #243

Merged
merged 2 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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