Skip to content

Commit fe5f69d

Browse files
authored
[Fix] Fetch sparse-only vector over grpc (#467)
## Problem An error is raised when fetching sparse vector data over grpc. ## Solution - Add test case for fetch - Modify response parsing so that error does not occur ## Type of Change - [x] Bug fix (non-breaking change which fixes an issue)
2 parents 938a5c8 + d0b54bc commit fe5f69d

File tree

12 files changed

+52
-18
lines changed

12 files changed

+52
-18
lines changed

.github/actions/test-data-asyncio/action.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ runs:
3838
- name: Run data plane tests
3939
id: data-plane-asyncio-tests
4040
shell: bash
41-
run: poetry run pytest tests/integration/data_asyncio -s -vv
41+
run: poetry run pytest tests/integration/data_asyncio --retries 5 --retry-delay 35 -s -vv --log-cli-level=DEBUG
4242
env:
4343
PINECONE_API_KEY: ${{ inputs.PINECONE_API_KEY }}
4444
USE_GRPC: ${{ inputs.use_grpc }}

.github/actions/test-data-plane/action.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ runs:
5252
- name: Run data plane tests
5353
id: data-plane-tests
5454
shell: bash
55-
run: poetry run pytest tests/integration/data
55+
run: poetry run pytest tests/integration/data --retries 5 --retry-delay 35 -s -vv --log-cli-level=DEBUG
5656
env:
5757
PINECONE_API_KEY: ${{ inputs.PINECONE_API_KEY }}
5858
USE_GRPC: ${{ inputs.use_grpc }}

.github/workflows/testing-integration-asyncio.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
- name: Run data plane tests
2727
id: data-plane-asyncio-tests
2828
shell: bash
29-
run: poetry run pytest tests/integration/data_asyncio -s -vv
29+
run: poetry run pytest tests/integration/data_asyncio --retries 5 --retry-delay 35 -s -vv --log-cli-level=DEBUG
3030
env:
3131
PINECONE_API_KEY: ${{ secrets.PINECONE_API_KEY }}
3232

@@ -51,6 +51,6 @@ jobs:
5151
include_asyncio: true
5252
include_dev: true
5353
- name: 'db_control asyncio'
54-
run: poetry run pytest tests/integration/control_asyncio -s -vv
54+
run: poetry run pytest tests/integration/control_asyncio --retries 5 --retry-delay 35 -s -vv --log-cli-level=DEBUG
5555
env:
5656
PINECONE_API_KEY: '${{ secrets.PINECONE_API_KEY }}'

.github/workflows/testing-integration.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
with:
2222
include_asyncio: true
2323
- name: 'Run integration tests'
24-
run: poetry run pytest tests/integration/inference -s -vv
24+
run: poetry run pytest tests/integration/inference --retries 5 --retry-delay 35 -s -vv --log-cli-level=DEBUG
2525
env:
2626
PINECONE_DEBUG_CURL: 'true'
2727
PINECONE_API_KEY: '${{ secrets.PINECONE_API_KEY }}'
@@ -113,7 +113,7 @@ jobs:
113113
- name: Setup Poetry
114114
uses: ./.github/actions/setup-poetry
115115
- name: 'Run integration tests (REST)'
116-
run: poetry run pytest tests/integration/control/serverless -s -vv
116+
run: poetry run pytest tests/integration/control/serverless --retries 5 --retry-delay 35 -s -vv --log-cli-level=DEBUG
117117
env:
118118
PINECONE_DEBUG_CURL: 'true'
119119
PINECONE_API_KEY: '${{ secrets.PINECONE_API_KEY }}'

.github/workflows/testing-unit.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ jobs:
5858
include_asyncio: true
5959

6060
- name: Run unit tests (REST)
61-
run: poetry run pytest --cov=pinecone --timeout=120 tests/unit
61+
run: poetry run pytest --cov=pinecone --timeout=120 tests/unit --retries 5 --retry-delay 35 -s -vv --log-cli-level=DEBUG
6262
- name: Run unit tests (GRPC)
6363
if: ${{ matrix.use_grpc == true }}
64-
run: poetry run pytest --cov=pinecone/grpc --timeout=120 tests/unit_grpc
64+
run: poetry run pytest --cov=pinecone/grpc --timeout=120 tests/unit_grpc --retries 5 --retry-delay 35 -s -vv --log-cli-level=DEBUG

pinecone/grpc/utils.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ def parse_fetch_response(response: Message):
4848
for id, vec in vectors.items():
4949
vd[id] = _Vector(
5050
id=vec["id"],
51-
values=vec["values"],
52-
sparse_values=parse_sparse_values(vec.get("sparseValues")),
51+
values=vec.get("values", None),
52+
sparse_values=parse_sparse_values(vec.get("sparseValues", None)),
5353
metadata=vec.get("metadata", None),
5454
_check_type=False,
5555
)

pinecone/utils/tqdm.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
import warnings
2+
3+
__all__ = ["tqdm"]
4+
15
try:
2-
# Use the notebook-friendly auto selection if tqdm is installed.
3-
from tqdm.auto import tqdm
6+
# Suppress the specific tqdm warning about IProgress
7+
with warnings.catch_warnings():
8+
warnings.filterwarnings("ignore", category=UserWarning, module="tqdm")
9+
from tqdm.auto import tqdm
410
except ImportError:
511
# Fallback: define a dummy tqdm that supports the same interface.
612
class tqdm: # type: ignore

poetry.lock

+18-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ pytest = "8.2.0"
8585
pytest-asyncio = "^0.25.2"
8686
pytest-cov = "2.10.1"
8787
pytest-mock = "3.6.1"
88+
pytest-retry = "^1.7.0"
8889
pytest-timeout = "2.2.0"
8990
pytest-benchmark = [
9091
{ version = '5.0.0', python = ">=3.9,<4.0" }

tests/integration/data/test_fetch.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@ def test_fetch_unspecified_namespace(self, idx):
143143
assert results.vectors["1"].values is not None
144144
assert results.vectors["4"].metadata is not None
145145

146-
@pytest.mark.skip(reason="Backend implementation not ready")
147146
def test_fetch_sparse_index(self, sparse_idx):
148147
sparse_idx.upsert(
149148
vectors=[
@@ -165,9 +164,11 @@ def test_fetch_sparse_index(self, sparse_idx):
165164
assert fetch_results.namespace == ""
166165
assert len(fetch_results.vectors) == 10
167166
for i in range(10):
167+
logger.debug(fetch_results.vectors[str(i)])
168168
assert fetch_results.vectors[str(i)].id == str(i)
169-
assert fetch_results.vectors[str(i)].values is not None
170-
assert len(fetch_results.vectors[str(i)].values) == 2
169+
assert fetch_results.vectors[str(i)].sparse_values is not None
170+
assert len(fetch_results.vectors[str(i)].sparse_values.indices) == 2
171+
assert len(fetch_results.vectors[str(i)].sparse_values.values) == 2
171172
assert fetch_results.vectors[str(i)].metadata is not None
172173
assert fetch_results.vectors[str(i)].metadata["genre"] == "action"
173174
assert fetch_results.vectors[str(i)].metadata["runtime"] == 120

tests/integration/data/test_list_errors.py

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ def seed_for_list2(idx, list_errors_namespace, wait=True):
2828

2929
@pytest.mark.usefixtures("seed_for_list2")
3030
class TestListErrors:
31+
@pytest.mark.skip(reason="Bug filed https://github.com/pinecone-io/pinecone-db/issues/9578")
3132
def test_list_change_prefix_while_fetching_next_page(self, idx, list_errors_namespace):
3233
results = idx.list_paginated(prefix="99", limit=5, namespace=list_errors_namespace)
3334
with pytest.raises(PineconeException) as e:

tests/integration/data/test_query.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,11 @@ def test_query_by_vector_include_metadata(self, idx, query_namespace, use_nondef
115115
assert isinstance(results, QueryResponse) == True
116116
assert results.namespace == target_namespace
117117

118-
matches_with_metadata = [match for match in results.matches if match.metadata is not None]
118+
matches_with_metadata = [
119+
match
120+
for match in results.matches
121+
if match.metadata is not None and match.metadata != {}
122+
]
119123
assert len(matches_with_metadata) == 3
120124
assert find_by_id(results.matches, "4").metadata["genre"] == "action"
121125

@@ -134,7 +138,11 @@ def test_query_by_vector_include_values_and_metadata(
134138
assert isinstance(results, QueryResponse) == True
135139
assert results.namespace == target_namespace
136140

137-
matches_with_metadata = [match for match in results.matches if match.metadata is not None]
141+
matches_with_metadata = [
142+
match
143+
for match in results.matches
144+
if match.metadata is not None and match.metadata != {}
145+
]
138146
assert len(matches_with_metadata) == 3
139147
assert find_by_id(results.matches, "4").metadata["genre"] == "action"
140148
assert len(results.matches[0].values) == self.expected_dimension

0 commit comments

Comments
 (0)