-
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.
Support passing custom host for Index operations (#218)
## Problem We need support for supplying a custom `host` value for index operations. ## Solution `pinecone.init()` and `Config` already support the ability to supply a custom `host`. It didn't seem like it was being passed through to the `ApiClient`: - Update `_get_api_instance()` in `manage.py` to check for a `Config.CONTROLLER_HOST` value, and apply it to the `client_config` if so. This will then be used throughout the index operations. - Add a unit test file for `manage.py`, test setting `controller_host` and timeout functionality in `create_index` / `delete_index`. ## Type of Change - [X] New feature (non-breaking change which adds functionality) ## Test Plan Pull this branch down and test locally. I validated myself by passing a bogus `host` in and looking over the errors, then passing the proper `host` via `init` to validate it works properly. ```python >>> poetry shell >>> python3 >>> import pinecone >>> pinecone.init(api_key="123-456-789", environment="my_environment", host: "https:custom-host-foo.com") # Having passed a custom host that's inaccessible should fail >>> pinecone.list_indexes() # urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='fooblahblah.io', port=443): Max retries exceeded with # url: /databases (Caused by NameResolutionError("<urllib3.connection.HTTPSConnection object at 0x107eb9dd0>: # Failed to resolve 'fooblahblah.io' ([Errno 8] nodename nor servname provided, or not known)")) # Re-Init - should work as expected >>> pinecone.init(api_key="123-456-789", environment="my_environment") pinecone.list_indexes() # ['austin-3', 'austin-py-test', 'resin--test-index-1', 'test-create-1'] ```
- Loading branch information
1 parent
3fccb12
commit 7ff4ed8
Showing
4 changed files
with
62 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import pytest | ||
import pinecone | ||
import time | ||
|
||
class TestManage: | ||
|
||
def test_get_api_instance_without_host(self): | ||
pinecone.init(api_key="123-456-789", environment="my-environment") | ||
api_instance = pinecone.manage._get_api_instance() | ||
assert api_instance.api_client.configuration.host == "https://controller.my-environment.pinecone.io" | ||
|
||
def test_get_api_instance_with_host(self): | ||
pinecone.init(api_key="123-456-789", environment="my-environment", host="my-host") | ||
api_instance = pinecone.manage._get_api_instance() | ||
assert api_instance.api_client.configuration.host == "my-host" | ||
|
||
@pytest.mark.parametrize("timeout_value, get_status_calls, time_sleep_calls, get_status_responses", [ | ||
# No timeout, _get_status called twice, sleep called once | ||
(None, 2, 1, [{"ready": False}, {"ready": True}]), | ||
# Timeout of 10 seconds, _get_status called 3 times, sleep twice | ||
(10, 3, 2, [{"ready": False}, {"ready": False}, {"ready": True}]), | ||
# Timeout of -1 seconds, _get_status not called, no sleep | ||
(-1, 0, 0, [{"ready": False}]), | ||
]) | ||
def test_create_index_with_timeout(self, mocker, timeout_value, get_status_calls, time_sleep_calls, get_status_responses): | ||
mocker.patch('pinecone.manage._get_api_instance', return_value=mocker.Mock()) | ||
mocker.patch('pinecone.manage._get_status', side_effect=get_status_responses) | ||
mocker.patch('time.sleep') | ||
|
||
pinecone.manage.create_index("my-index", 10, timeout=timeout_value) | ||
|
||
pinecone.manage._get_api_instance.assert_called_once() | ||
assert pinecone.manage._get_status.call_count == get_status_calls | ||
assert time.sleep.call_count == time_sleep_calls | ||
|
||
@pytest.mark.parametrize("timeout_value, list_indexes_calls, time_sleep_calls, list_indexes_responses", [ | ||
# No timeout, list_indexes called twice, sleep called once | ||
(None, 2, 1, [["my-index", "index-1"], ["index-1"]]), | ||
# Timeout of 10 seconds, list_indexes called 3 times, sleep twice | ||
(10, 3, 2, [["my-index", "index-1"], ["my-index", "index-1"], ["index-1"]]), | ||
# Timeout of -1 seconds, list_indexes not called, no sleep | ||
(-1, 0, 0, [["my-index", "index-1"]]), | ||
]) | ||
def test_delete_index_with_timeout(self, mocker, timeout_value, list_indexes_calls, time_sleep_calls, list_indexes_responses): | ||
api_instance_mock = mocker.Mock() | ||
api_instance_mock.list_indexes = mocker.Mock(side_effect=list_indexes_responses) | ||
mocker.patch('pinecone.manage._get_api_instance', return_value=api_instance_mock) | ||
mocker.patch('time.sleep') | ||
|
||
pinecone.manage.delete_index("my-index", timeout=timeout_value) | ||
|
||
pinecone.manage._get_api_instance.assert_called_once() | ||
assert api_instance_mock.list_indexes.call_count == list_indexes_calls | ||
assert time.sleep.call_count == time_sleep_calls |