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

Pydantic v1 and v2 compatibility #466

Merged
merged 7 commits into from
Nov 15, 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
2 changes: 2 additions & 0 deletions docs/source/contributors/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

This page is intended for people interested in building new or modified functionality for Jupyter AI.

If you would like to build applications that enhance Jupyter AI, please see the {doc}`developer's guide </developers/index>`.

## Design principles

Maintainers of Jupyter AI have adopted principles that contributors should also follow. These principles, which build on top of [the Zen of Python](https://peps.python.org/pep-0020/), are intended to earn users' trust by keeping their data under their control. The following list is non-exhaustive; maintainers have discretion to interpret and revise these principles.
Expand Down
18 changes: 18 additions & 0 deletions docs/source/developers/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Developers

The developer documentation is for authors who want to enhance
the functionality of Jupyter AI.

If you are interested in contributing to Jupyter AI,
please see our {doc}`contributor's guide </contributors/index>`.

## Pydantic compatibility

Jupyter AI is fully compatible with Python environments using Pydantic v1
or Pydantic v2. Jupyter AI imports Pydantic classes from the
`langchain.pydantic_v1` module. Developers should do the same when they extend
Jupyter AI classes.

For more details about using `langchain.pydantic_v1` in an environment with
Pydantic v2 installed, see the
[LangChain documentation on Pydantic compatibility](https://python.langchain.com/docs/guides/pydantic_compatibility).
1 change: 1 addition & 0 deletions docs/source/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ maxdepth: 2

users/index
contributors/index
developers/index
```
10 changes: 10 additions & 0 deletions docs/source/users/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ Welcome to the user documentation for Jupyter AI.
If you are interested in contributing to Jupyter AI,
please see our {doc}`contributor's guide </contributors/index>`.

If you would like to build applications that enhance Jupyter AI,
please see the {doc}`developer's guide </developers/index>`.

## Prerequisites

You can run Jupyter AI on any system that can run a supported Python version
Expand Down Expand Up @@ -45,6 +48,13 @@ does not depend on JupyterLab or `jupyter_ai`. You can install
If you have both `jupyter_ai_magics` and `jupyter_ai` installed, you should
have the same version of each, to avoid errors.

Jupyter AI internally uses Pydantic v1 and should work with either Pydantic
version 1 or version 2. For compatibility, developers using Pydantic V2
should import classes using the `pydantic.v1` package. See the
[LangChain Pydantic migration plan](https://python.langchain.com/docs/guides/pydantic_compatibility)
for advice about how developers should use `v1` to avoid mixing v1 and v2
classes in their code.

JasonWeill marked this conversation as resolved.
Show resolved Hide resolved
## Installation

### Installation via `pip`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
HuggingFaceHubEmbeddings,
OpenAIEmbeddings,
)
from pydantic import BaseModel, Extra
from langchain.pydantic_v1 import BaseModel, Extra


class BaseEmbeddingsProvider(BaseModel):
Expand Down
2 changes: 1 addition & 1 deletion packages/jupyter-ai-magics/jupyter_ai_magics/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import Literal, Optional, get_args

import click
from pydantic import BaseModel
from langchain.pydantic_v1 import BaseModel

FORMAT_CHOICES_TYPE = Literal[
"code", "html", "image", "json", "markdown", "math", "md", "text"
Expand Down
2 changes: 1 addition & 1 deletion packages/jupyter-ai-magics/jupyter_ai_magics/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@
from langchain.llms.sagemaker_endpoint import LLMContentHandler
from langchain.llms.utils import enforce_stop_tokens
from langchain.prompts import PromptTemplate
from langchain.pydantic_v1 import BaseModel, Extra, root_validator
from langchain.schema import LLMResult
from langchain.utils import get_from_dict_or_env
from pydantic import BaseModel, Extra, root_validator


class EnvAuthStrategy(BaseModel):
Expand Down
1 change: 0 additions & 1 deletion packages/jupyter-ai-magics/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ dynamic = ["version", "description", "authors", "urls", "keywords"]

dependencies = [
"ipython",
"pydantic~=1.0",
"importlib_metadata>=5.2.0",
"langchain==0.0.318",
"typing_extensions>=4.5.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/jupyter-ai/jupyter_ai/chat_handlers/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
from langchain.llms import BaseLLM
from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import PromptTemplate
from langchain.pydantic_v1 import BaseModel
from langchain.schema.output_parser import BaseOutputParser
from pydantic import BaseModel


class OutlineSection(BaseModel):
Expand Down
20 changes: 9 additions & 11 deletions packages/jupyter-ai/jupyter_ai/chat_handlers/learn.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ async def process_message(self, message: HumanChatMessage):
em_provider_cls, em_provider_args = self.get_embedding_provider()
if not em_provider_cls:
self.reply(
"Please select an embedding provider in the chat settings, "
"then run your **/learn** command again."
"Sorry, please select an embedding provider before using the `/learn` command."
)
return

Expand Down Expand Up @@ -122,18 +121,17 @@ async def process_message(self, message: HumanChatMessage):
)
self.save()

response = f"""🎉 I have learned from documents at **{load_path}** and
I am ready to answer questions about them. You can ask questions about these
documents by starting your message with **/ask**."""
response = f"""🎉 I have learned documents at **{load_path}** and I am ready to answer questions about them.
You can ask questions about these docs by prefixing your message with **/ask**."""
self.reply(response, message)

def _build_list_response(self):
if not self.metadata.dirs:
return "I haven't learned from any documents yet."
return "There are no docs that have been learned yet."

dirs = [dir.path for dir in self.metadata.dirs]
dir_list = "\n- " + "\n- ".join(dirs) + "\n\n"
message = f"""I can answer questions about documents in these directories:
message = f"""I can answer questions from docs in these directories:
{dir_list}"""
return message

Expand Down Expand Up @@ -200,10 +198,10 @@ async def delete_and_relearn(self):
self.log.info(
f"Switching embedding provider from {prev_em_id} to {curr_em_id}."
)
message = f"""🔔 Hi there! It seems like you have changed the embedding
message = f"""🔔 Hi there, it seems like you have updated the embeddings
model from `{prev_em_id}` to `{curr_em_id}`. I have to re-learn the
documents you had previously submitted for learning. Please wait
until I am done with this task before you use the **/ask** command."""
documents you had previously submitted for learning. Please wait to use
the **/ask** command until I am done with this task."""

self.reply(message)

Expand Down Expand Up @@ -238,7 +236,7 @@ async def relearn(self, metadata: IndexMetadata):
dir_list = (
"\n- " + "\n- ".join([dir.path for dir in self.metadata.dirs]) + "\n\n"
)
message = f"""🎉 I am done learning about documents in these directories:
message = f"""🎉 I am done learning docs in these directories:
{dir_list} I am ready to answer questions about them.
You can ask me about these documents by starting your message with **/ask**."""
self.reply(message)
Expand Down
2 changes: 1 addition & 1 deletion packages/jupyter-ai/jupyter_ai/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from jupyter_ai.config_manager import ConfigManager, KeyEmptyError, WriteConflictError
from jupyter_server.base.handlers import APIHandler as BaseAPIHandler
from jupyter_server.base.handlers import JupyterHandler
from pydantic import ValidationError
from langchain.pydantic_v1 import ValidationError
from tornado import web, websocket
from tornado.web import HTTPError

Expand Down
2 changes: 1 addition & 1 deletion packages/jupyter-ai/jupyter_ai/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Any, Dict, List, Literal, Optional, Union

from jupyter_ai_magics.providers import AuthStrategy, Field
from pydantic import BaseModel, validator
from langchain.pydantic_v1 import BaseModel, validator

DEFAULT_CHUNK_SIZE = 2000
DEFAULT_CHUNK_OVERLAP = 100
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
)
from jupyter_ai.models import DescribeConfigResponse, GlobalConfig, UpdateConfigRequest
from jupyter_ai_magics.utils import get_em_providers, get_lm_providers
from pydantic import ValidationError
from langchain.pydantic_v1 import ValidationError


@pytest.fixture
Expand Down
1 change: 0 additions & 1 deletion packages/jupyter-ai/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ classifiers = [
dependencies = [
"jupyter_server>=1.6,<3",
"jupyterlab~=4.0",
"pydantic~=1.0",
"openai~=0.26",
"aiosqlite>=0.18",
"importlib_metadata>=5.2.0",
Expand Down
Loading