Skip to content

Commit 44fc7ed

Browse files
authored
Simplify passing host configuration direct to Index client (#280)
## Problem In production situations, it's important people be able to configure the client in a way that does not hit the control plane to find out the host url. This was possible, but now that I'm writing docs I realized this is cumbersome because the positional index name arg was still being required even though it wasn't being used in that scenario. We want it to be easy. ## Solution ### Before ```python from pinecone.grpc import PineconeGRPC pc = PineconeGRPC(api_key="key") # Targeting by name is easy index = pc.Index('blah') # Targeting by host url is awkward index = pc.Index('required-but-unused-index-name', host='blah-24vnhz6.svc.apw5-4e34-81fa.pinecone.io') ``` ### After ```python from pinecone.grpc import PineconeGRPC pc = PineconeGRPC(api_key="key") # This still works index = pc.Index('blah') # This now works index = pc.Index(host='blah-24vnhz6.svc.apw5-4e34-81fa.pinecone.io') # Or pass both if you really want, but not needed. index = pc.Index(name='blah', host='blah-24vnhz6.svc.apw5-4e34-81fa.pinecone.io') ``` ## Type of Change - [x] New feature (non-breaking change which adds functionality) ## Test Plan Update integration tests to check it can still issue data calls without errors no matter how it is configured.
1 parent 557afd5 commit 44fc7ed

File tree

3 files changed

+65
-11
lines changed

3 files changed

+65
-11
lines changed

pinecone/control/pinecone.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from pinecone.core.client.api.manage_indexes_api import ManageIndexesApi as IndexOperationsApi
99
from pinecone.core.client.api_client import ApiClient
10-
from pinecone.utils import get_user_agent
10+
from pinecone.utils import get_user_agent, normalize_host
1111
from pinecone.core.client.models import (
1212
CreateCollectionRequest,
1313
CreateIndexRequest,
@@ -213,7 +213,15 @@ def _get_status(self, name: str):
213213
response = api_instance.describe_index(name)
214214
return response["status"]
215215

216-
def Index(self, name: str, host: Optional[str] = None):
217-
if host is None:
218-
host = self.index_host_store.get_host(self.index_api, self.config, name)
219-
return Index(api_key=self.config.api_key, host=host, pool_threads=self.pool_threads)
216+
def Index(self, name: str = '', host: str = ''):
217+
if name == '' and host == '':
218+
raise ValueError("Either name or host must be specified")
219+
220+
if host != '':
221+
# Use host url if it is provided
222+
return Index(api_key=self.config.api_key, host=normalize_host(host), pool_threads=self.pool_threads)
223+
224+
if name != '':
225+
# Otherwise, get host url from describe_index using the index name
226+
index_host = self.index_host_store.get_host(self.index_api, self.config, name)
227+
return Index(api_key=self.config.api_key, host=index_host, pool_threads=self.pool_threads)

pinecone/grpc/pinecone.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
from ..control.pinecone import Pinecone
22
from ..config.config import ConfigBuilder
33
from .index_grpc import GRPCIndex
4-
from typing import Optional
54

65
class PineconeGRPC(Pinecone):
7-
def Index(self, name: str, host: Optional[str] = None):
8-
if host is None:
9-
host = self.index_host_store.get_host(self.index_api, self.config, name)
10-
config = ConfigBuilder.build(api_key=self.config.api_key, host=host)
11-
return GRPCIndex(index_name=name, config=config)
6+
def Index(self, name: str = '', host: str = ''):
7+
if name == '' and host == '':
8+
raise ValueError("Either name or host must be specified")
9+
10+
if host != '':
11+
# Use host if it is provided
12+
config = ConfigBuilder.build(api_key=self.config.api_key, host=host)
13+
return GRPCIndex(index_name=name, config=config)
14+
15+
if name != '':
16+
# Otherwise, get host url from describe_index using the index name
17+
index_host = self.index_host_store.get_host(self.index_api, self.config, name)
18+
config = ConfigBuilder.build(api_key=self.config.api_key, host=index_host)
19+
return GRPCIndex(index_name=name, config=config)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import pytest
2+
3+
class TestIndexClientInitialization:
4+
def test_index_direct_host_kwarg(self, client, index_host):
5+
index = client.Index(host=index_host)
6+
index.fetch(ids=['1', '2', '3'])
7+
8+
def test_index_direct_host_with_https(self, client, index_host):
9+
if not index_host.startswith('https://'):
10+
index_host = 'https://' + index_host
11+
index = client.Index(host=index_host)
12+
index.fetch(ids=['1', '2', '3'])
13+
14+
def test_index_direct_host_without_https(self, client, index_host):
15+
if index_host.startswith('https://'):
16+
index_host = index_host[8:]
17+
index = client.Index(host=index_host)
18+
index.fetch(ids=['1', '2', '3'])
19+
20+
def test_index_by_name_positional_only(self, client, index_name, index_host):
21+
index = client.Index(index_name)
22+
index.fetch(ids=['1', '2', '3'])
23+
24+
def test_index_by_name_positional_with_host(self, client, index_name, index_host):
25+
index = client.Index(index_name, index_host)
26+
index.fetch(ids=['1', '2', '3'])
27+
28+
def test_index_by_name_kwargs(self, client, index_name):
29+
index = client.Index(name=index_name)
30+
index.fetch(ids=['1', '2', '3'])
31+
32+
def test_index_by_name_kwargs_with_host(self, client, index_name, index_host):
33+
index = client.Index(name=index_name, host=index_host)
34+
index.fetch(ids=['1', '2', '3'])
35+
36+
def test_raises_when_no_name_or_host(self, client, index_host):
37+
with pytest.raises(ValueError):
38+
client.Index()

0 commit comments

Comments
 (0)