-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Fix] Configuring SSL proxy via openapi_config object (#321)
## Problem A few different problems being solved here: - `Pinecone` class accepts an optional param, `openapi_config`. When this is passed (usually as a vehicle for SSL configurations), it currently clobbers the `api_key` param so the user sees an error message about not providing an api_key (even though they did pass it) if they attempt to perform a control plane operation ```python from pinecone import Pinecone from pinecone.core.client.configuration import Configuration as OpenApiConfiguration openapi_config = OpenApiConfiguration() openapi_config.ssl_ca_cert = '/path/to/cert' pc = Pinecone(api_key='key, openapi_config=openapi_config) pc.list_indexes() // error: No api-key provided ``` - In a related issue, the `openapi_config` (with SSL configs) was not being correctly passed through to the underlying `DataPlaneApi` for data calls. So users with custom network configurations requiring SSL config would see SSL validation failures when attempting data operations. ```python from pinecone import Pinecone from pinecone.core.client.configuration import Configuration as OpenApiConfiguration openapi_config = OpenApiConfiguration() openapi_config.ssl_ca_cert = '/path/to/cert' pc = Pinecone(api_key='key, openapi_config=openapi_config) pc.list_indexes() // error: No api-key provided ``` ## Solution - Adjust the ConfigBuilder to avoid clobbering API key - Move some logic into a util function so that behavior will be consistent across both data and control planes - Ensure configuration is passed to from the `Pinecone` object to the index client - deepcopy the openapi_config object before modifying it so that index-specific host changes do clobber control plane or calls to other indexes. ## Future work - In the future, we should deprecate `openapi_config` and have some way of passing SSL config without all the baggage that comes with this OpenApiConfiguration object. This config object is an undocumented holdover from earlier versions of the client and breaks the abstraction the client is trying to provide to smooth out the UX of the generated SDK code. ## Type of Change - [x] Bug fix (non-breaking change which fixes an issue) ## Test Plan - Added tests
- Loading branch information
Showing
11 changed files
with
175 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
from pinecone.core.client.api_client import ApiClient | ||
from .user_agent import get_user_agent | ||
|
||
def setup_openapi_client(api_klass, config, pool_threads): | ||
api_client = ApiClient( | ||
configuration=config.openapi_config, | ||
pool_threads=pool_threads | ||
) | ||
api_client.user_agent = get_user_agent() | ||
extra_headers = config.additional_headers or {} | ||
for key, value in extra_headers.items(): | ||
api_client.set_default_header(key, value) | ||
client = api_klass(api_client) | ||
return client |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import pytest | ||
import os | ||
|
||
from pinecone import Pinecone | ||
from pinecone.core.client.configuration import Configuration as OpenApiConfiguration | ||
from urllib3 import make_headers | ||
|
||
@pytest.mark.skipif(os.getenv('USE_GRPC') != 'false', reason='Only test when using REST') | ||
class TestIndexOpenapiConfig: | ||
def test_passing_openapi_config(self, api_key_fixture, index_host): | ||
oai_config = OpenApiConfiguration.get_default_copy() | ||
p = Pinecone(api_key=api_key_fixture, openapi_config=oai_config) | ||
assert p.config.api_key == api_key_fixture | ||
p.list_indexes() # should not throw | ||
|
||
index = p.Index(host=index_host) | ||
assert index._config.api_key == api_key_fixture | ||
index.describe_index_stats() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import pytest | ||
|
||
from pinecone.core.client.configuration import Configuration as OpenApiConfiguration | ||
from pinecone.config import ConfigBuilder | ||
from pinecone import PineconeConfigurationError | ||
|
||
class TestConfigBuilder: | ||
def test_build_simple(self): | ||
config = ConfigBuilder.build(api_key="my-api-key", host="https://my-controller-host") | ||
assert config.api_key == "my-api-key" | ||
assert config.host == "https://my-controller-host" | ||
assert config.additional_headers == {} | ||
assert config.openapi_config.host == "https://my-controller-host" | ||
assert config.openapi_config.api_key == {"ApiKeyAuth": "my-api-key"} | ||
|
||
def test_build_merges_key_and_host_when_openapi_config_provided(self): | ||
config = ConfigBuilder.build( | ||
api_key="my-api-key", | ||
host="https://my-controller-host", | ||
openapi_config=OpenApiConfiguration() | ||
) | ||
assert config.api_key == "my-api-key" | ||
assert config.host == "https://my-controller-host" | ||
assert config.additional_headers == {} | ||
assert config.openapi_config.host == "https://my-controller-host" | ||
assert config.openapi_config.api_key == {"ApiKeyAuth": "my-api-key"} | ||
|
||
def test_build_errors_when_no_api_key_is_present(self): | ||
with pytest.raises(PineconeConfigurationError) as e: | ||
ConfigBuilder.build() | ||
assert str(e.value) == "You haven't specified an Api-Key." | ||
|
||
def test_build_errors_when_no_host_is_present(self): | ||
with pytest.raises(PineconeConfigurationError) as e: | ||
ConfigBuilder.build(api_key='my-api-key') | ||
assert str(e.value) == "You haven't specified a host." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters