Skip to content

Commit 0c50e18

Browse files
authored
Add better error messages for mistaken from_texts and from_documents (#342)
## Problem Sometimes people using Pinecone with Langchain accidentally try to invoke `from_texts` and `from_documents` methods on our `Pinecone` class even though these are not methods by us. This is mostly name-related confusion because Langchain used to have an export called `Pinecone` that later got renamed to the less ambiguous `PineconeVectorStore`. ## Solution Add some stub methods to the `Pinecone` class to guide users in the right direction. <img width="920" alt="Screenshot 2024-05-13 at 2 36 51 PM" src="https://github.com/pinecone-io/pinecone-python-client/assets/1326365/09bfa6bf-b307-43e9-8756-bcf807b0e3b0"> ## Type of Change - [x] New feature (non-breaking change which adds functionality) ## Test Plan Added unit tests. And also an integration test to verify the docs link resolves to a valid page.
1 parent b174eea commit 0c50e18

File tree

6 files changed

+52
-1
lines changed

6 files changed

+52
-1
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from pinecone.utils import docslinks
2+
3+
KB_ARTICLE = docslinks['LANGCHAIN_IMPORT_KB_ARTICLE']
4+
GITHUB_REPO = docslinks['GITHUB_REPO']
5+
6+
def _build_langchain_attribute_error_message(method_name: str):
7+
return f"""{method_name} is not a top-level attribute of the Pinecone class provided by pinecone's official python package developed at {GITHUB_REPO}. You may have a name collision with an export from another dependency in your project that wraps Pinecone functionality and exports a similarly named class. Please refer to the following knowledge base article for more information: {KB_ARTICLE}
8+
"""
9+

pinecone/control/pinecone.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
ConfigureIndexRequestSpecPod
1717
)
1818
from pinecone.models import ServerlessSpec, PodSpec, IndexList, CollectionList
19+
from .langchain_import_warnings import _build_langchain_attribute_error_message
1920

2021
from pinecone.data import Index
2122

@@ -545,6 +546,13 @@ def _get_status(self, name: str):
545546
response = api_instance.describe_index(name)
546547
return response["status"]
547548

549+
@staticmethod
550+
def from_texts(*args, **kwargs):
551+
raise AttributeError(_build_langchain_attribute_error_message("from_texts"))
552+
553+
@staticmethod
554+
def from_documents(*args, **kwargs):
555+
raise AttributeError(_build_langchain_attribute_error_message("from_documents"))
548556

549557
def Index(self, name: str = '', host: str = '', **kwargs):
550558
"""

pinecone/utils/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55
from .fix_tuple_length import fix_tuple_length
66
from .convert_to_list import convert_to_list
77
from .normalize_host import normalize_host
8-
from .setup_openapi_client import setup_openapi_client
8+
from .setup_openapi_client import setup_openapi_client
9+
from .docslinks import docslinks

pinecone/utils/docslinks.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
docslinks = {
2+
'GITHUB_REPO': 'https://github.com/pinecone-io/pinecone-python-client',
3+
'LANGCHAIN_IMPORT_KB_ARTICLE': 'https://docs.pinecone.io/troubleshooting/pinecone-attribute-errors-with-langchain'
4+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import pytest
2+
from pinecone import Pinecone
3+
4+
class TestLangchainErrorMessages():
5+
def test_error_from_texts_positional_args(self):
6+
with pytest.raises(AttributeError) as e:
7+
Pinecone.from_texts("texts", "id")
8+
assert "from_texts is not a top-level attribute of the Pinecone class" in str(e.value)
9+
10+
def test_error_from_texts_kwargs(self):
11+
with pytest.raises(AttributeError) as e:
12+
Pinecone.from_texts(foo="texts", bar="id", num_threads=1)
13+
assert "from_texts is not a top-level attribute of the Pinecone class" in str(e.value)
14+
15+
def test_error_from_documents(self):
16+
with pytest.raises(AttributeError) as e:
17+
Pinecone.from_documents("documents", "id")
18+
assert "from_documents is not a top-level attribute of the Pinecone class" in str(e.value)
19+

tests/unit/utils/test_docs_links.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import pytest
2+
import requests
3+
from pinecone.utils import docslinks
4+
5+
urls = list(docslinks.values())
6+
7+
@pytest.mark.parametrize("url", urls)
8+
def test_valid_links(url):
9+
response = requests.get(url)
10+
assert response.status_code == 200, f"Docs link is invalid: {url}"

0 commit comments

Comments
 (0)