From 833b3b75c0d2df346e579f2b702fcc0a4efdb65f Mon Sep 17 00:00:00 2001 From: david qiu Date: Wed, 27 Dec 2023 14:12:17 -0800 Subject: [PATCH] [1.x] Validate Pydantic imports (#548) * lint * add import linter job in GH Actions * fix pydantic import --- .github/workflows/lint.yml | 42 +++++++++++++++++-- nx.json | 3 ++ package.json | 1 + packages/jupyter-ai-magics/package.json | 3 +- .../jupyter_ai/chat_handlers/base.py | 4 +- packages/jupyter-ai/package.json | 3 +- packages/jupyter-ai/pyproject.toml | 16 +++---- pyproject.toml | 11 +++++ 8 files changed, 64 insertions(+), 19 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1ac8b4aa4..49e1a2bd5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,10 +1,10 @@ -name: JS Lint +name: Lint on: - pull_request jobs: - js_lint: - name: JS Lint + lint_ts: + name: Lint TypeScript source runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -15,5 +15,39 @@ jobs: run: pip install jupyterlab~=3.6 - name: Install JS dependencies run: jlpm - - name: Run JS Lint + - name: Lint TypeScript source run: jlpm lerna run lint:check + + lint_py_imports: + name: Lint Python imports + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Echo environment details + run: | + which python + which pip + python --version + pip --version + + # see #546 for context on why this is necessary + - name: Create venv + run: | + python -m venv lint_py_imports + + - name: Install job dependencies + run: | + source ./lint_py_imports/bin/activate + pip install jupyterlab~=3.6 + pip install import-linter~=1.12.1 + + - name: Install Jupyter AI packages from source + run: | + source ./lint_py_imports/bin/activate + jlpm install + jlpm install-from-src + + - name: Lint Python imports + run: | + source ./lint_py_imports/bin/activate + lint-imports diff --git a/nx.json b/nx.json index 5c42122e0..4e9b0baa2 100644 --- a/nx.json +++ b/nx.json @@ -11,6 +11,9 @@ }, "dev-uninstall": { "dependsOn": ["clean:labextension"] + }, + "install-from-src": { + "dependsOn": ["^install-from-src"] } }, "tasksRunnerOptions": { diff --git a/package.json b/package.json index ff0d386d7..a06dca067 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "dev": "jupyter lab --config playground/config.py", "dev-install": "lerna run dev-install --stream", "dev-uninstall": "lerna run dev-uninstall --stream", + "install-from-src": "lerna run install-from-src --stream", "lint": "jlpm && lerna run prettier && lerna run eslint", "lint:check": "lerna run prettier:check && lerna run eslint:check", "watch": "lerna run watch --parallel --stream" diff --git a/packages/jupyter-ai-magics/package.json b/packages/jupyter-ai-magics/package.json index 726b52a4b..3e7b1c10b 100644 --- a/packages/jupyter-ai-magics/package.json +++ b/packages/jupyter-ai-magics/package.json @@ -19,6 +19,7 @@ }, "scripts": { "dev-install": "pip install -e \".[dev,all]\"", - "dev-uninstall": "pip uninstall jupyter_ai_magics -y" + "dev-uninstall": "pip uninstall jupyter_ai_magics -y", + "install-from-src": "pip install ." } } diff --git a/packages/jupyter-ai/jupyter_ai/chat_handlers/base.py b/packages/jupyter-ai/jupyter_ai/chat_handlers/base.py index 9f179de51..bcbba00ba 100644 --- a/packages/jupyter-ai/jupyter_ai/chat_handlers/base.py +++ b/packages/jupyter-ai/jupyter_ai/chat_handlers/base.py @@ -18,9 +18,7 @@ from jupyter_ai.config_manager import ConfigManager, Logger from jupyter_ai.models import AgentChatMessage, ChatMessage, HumanChatMessage from jupyter_ai_magics.providers import BaseProvider - -# necessary to prevent circular import -from pydantic import BaseModel +from langchain.pydantic_v1 import BaseModel if TYPE_CHECKING: from jupyter_ai.handlers import RootChatHandler diff --git a/packages/jupyter-ai/package.json b/packages/jupyter-ai/package.json index 3ed39c7f6..b26ce4cf5 100644 --- a/packages/jupyter-ai/package.json +++ b/packages/jupyter-ai/package.json @@ -55,7 +55,8 @@ "watch:src": "tsc -w", "watch:labextension": "jupyter labextension watch .", "dev-install": "pip install -e \".[dev,all,test]\" && jupyter labextension develop . --overwrite && jupyter server extension enable jupyter_ai", - "dev-uninstall": "pip uninstall jupyter_ai -y" + "dev-uninstall": "pip uninstall jupyter_ai -y", + "install-from-src": "pip install ." }, "dependencies": { "@emotion/react": "^11.10.5", diff --git a/packages/jupyter-ai/pyproject.toml b/packages/jupyter-ai/pyproject.toml index 94fb093ef..9bea0f15f 100644 --- a/packages/jupyter-ai/pyproject.toml +++ b/packages/jupyter-ai/pyproject.toml @@ -28,13 +28,13 @@ dependencies = [ "aiosqlite>=0.18", "importlib_metadata>=5.2.0", "langchain==0.0.350", - "tiktoken", # required for OpenAIEmbeddings + "tiktoken", # required for OpenAIEmbeddings "jupyter_ai_magics", "dask[distributed]", - "faiss-cpu", # Not distributed by official repo + "faiss-cpu", # Not distributed by official repo "typing_extensions>=4.5.0", "traitlets>=5.0", - "deepmerge>=1.0" + "deepmerge>=1.0", ] dynamic = ["version", "description", "authors", "urls", "keywords"] @@ -51,16 +51,12 @@ test = [ "pytest-cov", "pytest-tornasync", "pytest-jupyter", - "syrupy~=4.0.8" + "syrupy~=4.0.8", ] -dev = [ - "jupyter_ai_magics[dev]" -] +dev = ["jupyter_ai_magics[dev]"] -all = [ - "jupyter_ai_magics[all]" -] +all = ["jupyter_ai_magics[all]"] [tool.hatch.version] source = "nodejs" diff --git a/pyproject.toml b/pyproject.toml index e0da9eccf..0eea5610a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,3 +27,14 @@ ignore = [".*"] [tool.check-wheel-contents] ignore = ["W002"] + +[tool.importlinter] +root_packages = ["jupyter_ai", "jupyter_ai_magics"] +include_external_packages = true + +[[tool.importlinter.contracts]] +key = "pydantic" +name = "Forbidden import of `pydantic` package. Please import from `langchain.pydantic_v1` instead for compatibility with both Pydantic v1 and v2." +type = "forbidden" +source_modules = ["jupyter_ai", "jupyter_ai_magics"] +forbidden_modules = ["pydantic"]