From d8d1bc9829d1a6f9a6caeb3425b54e3190e122c4 Mon Sep 17 00:00:00 2001 From: Jen Hamon Date: Mon, 5 Jan 2026 13:29:08 -0500 Subject: [PATCH 1/2] ## Summary Resolved the host handling discrepancy between `Pinecone.Index()` and `PineconeGRPC.Index()`. ### Changes Made: 1. **Updated `pinecone/grpc/pinecone.py`**: - Added imports for `normalize_host` from `pinecone.utils` and `check_realistic_host` from `pinecone.pinecone` - Updated the `Index()` method to validate and normalize the host when provided, matching `Pinecone.Index()`: - Validates the host using `check_realistic_host()` to ensure it's a valid host URL (not an index name) - Normalizes the host using `normalize_host()` to ensure it has a protocol prefix (`https://` or `http://`) 2. **Added test coverage** in `tests/unit_grpc/test_grpc_index_initialization.py`: - Added `test_invalid_host()` to verify that invalid hosts raise appropriate errors, matching the test for the regular Pinecone client ### Result: Both `Pinecone.Index()` and `PineconeGRPC.Index()` now: - Validate that provided hosts are valid (contain a "." or "localhost") - Normalize hosts by adding "https://" prefix if no protocol is present - Handle hosts consistently whether provided directly or fetched by index name The implementation is now consistent between both clients, ensuring proper host validation and normalization in all cases. --- pinecone/grpc/pinecone.py | 11 ++++++++-- .../test_grpc_index_initialization.py | 22 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/pinecone/grpc/pinecone.py b/pinecone/grpc/pinecone.py index b03da15d7..7926afc83 100644 --- a/pinecone/grpc/pinecone.py +++ b/pinecone/grpc/pinecone.py @@ -1,5 +1,7 @@ from pinecone import Pinecone from pinecone.config import ConfigBuilder +from pinecone.utils import normalize_host +from pinecone.pinecone import check_realistic_host from .index_grpc import GRPCIndex @@ -122,8 +124,13 @@ def Index(self, name: str = "", host: str = "", **kwargs): if name == "" and host == "": raise ValueError("Either name or host must be specified") - # Use host if it is provided, otherwise get host from describe_index - index_host = host or self.db.index._get_host(name) + if host != "": + check_realistic_host(host) + # Use host url if it is provided + index_host = normalize_host(host) + else: + # Otherwise, get host url from describe_index using the index name + index_host = self.db.index._get_host(name) pt = kwargs.pop("pool_threads", None) or self._pool_threads diff --git a/tests/unit_grpc/test_grpc_index_initialization.py b/tests/unit_grpc/test_grpc_index_initialization.py index b0b642505..392264633 100644 --- a/tests/unit_grpc/test_grpc_index_initialization.py +++ b/tests/unit_grpc/test_grpc_index_initialization.py @@ -1,3 +1,4 @@ +import pytest import re from pinecone.grpc import PineconeGRPC, GRPCClientConfig @@ -91,3 +92,24 @@ def test_config_passes_source_tag_when_set(self): re.search(r"source_tag=my_source_tag", pc.db._index_api.api_client.user_agent) is not None ) + + def test_invalid_host(self): + pc = PineconeGRPC(api_key="key") + + with pytest.raises(ValueError) as e: + pc.Index(host="invalid") + assert "You passed 'invalid' as the host but this does not appear to be valid" in str( + e.value + ) + + with pytest.raises(ValueError) as e: + pc.Index(host="my-index") + assert "You passed 'my-index' as the host but this does not appear to be valid" in str( + e.value + ) + + # Can instantiate with realistic host + pc.Index(host="test-bt8x3su.svc.apw5-4e34-81fa.pinecone.io") + + # Can instantiate with localhost address + pc.Index(host="localhost:8080") From 24f62c86f0fdd0c8c35b996d9cddccb7f8aaa299 Mon Sep 17 00:00:00 2001 From: Jen Hamon Date: Mon, 5 Jan 2026 13:45:57 -0500 Subject: [PATCH 2/2] All tests pass and linting is clean. Summary: ## Summary Fixed a test failure found during CI checks: ### Issue Found: The test `test_config_passed_when_target_by_host_and_port` was failing because it used `host="myhost:4343"`, which doesn't pass the `check_realistic_host` validation (it requires a "." in the hostname or "localhost"). ### Fix Applied: Updated the test to use a valid hostname: `myhost.example.com:4343` instead of `myhost:4343`. This maintains the test's intent (testing hosts with port numbers) while using a valid hostname. ### Test Results: - All 8 tests in `test_grpc_index_initialization.py` pass - Linting passes - Type checking passes ### Current Status: - No PR exists for branch `vk/e239-resolve-descrepa` yet - All local checks pass - Code is ready for PR creation The changes are committed and ready. If you want, I can help create a PR or check for any other issues. --- tests/unit_grpc/test_grpc_index_initialization.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit_grpc/test_grpc_index_initialization.py b/tests/unit_grpc/test_grpc_index_initialization.py index 392264633..987728f99 100644 --- a/tests/unit_grpc/test_grpc_index_initialization.py +++ b/tests/unit_grpc/test_grpc_index_initialization.py @@ -74,7 +74,7 @@ def test_config_passed_when_target_by_host(self): def test_config_passed_when_target_by_host_and_port(self): pc = PineconeGRPC(api_key="YOUR_API_KEY") config = GRPCClientConfig(timeout=5, secure=False) - index = pc.Index(host="myhost:4343", grpc_config=config) + index = pc.Index(host="myhost.example.com:4343", grpc_config=config) assert index.grpc_client_config.timeout == 5 assert index.grpc_client_config.secure == False @@ -84,7 +84,7 @@ def test_config_passed_when_target_by_host_and_port(self): assert index.grpc_client_config.conn_timeout == 1 # Endpoint calculation does not override port - assert index._endpoint() == "myhost:4343" + assert index._endpoint() == "myhost.example.com:4343" def test_config_passes_source_tag_when_set(self): pc = PineconeGRPC(api_key="YOUR_API_KEY", source_tag="my_source_tag")