Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Pinecone] Use Haystack Secrets #420

Merged
merged 6 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
# SPDX-License-Identifier: Apache-2.0
import io
import logging
import os
from copy import copy
from typing import Any, Dict, List, Optional

import pandas as pd
from haystack import default_to_dict
from haystack import default_from_dict, default_to_dict
from haystack.dataclasses import Document
from haystack.document_stores.types import DuplicatePolicy
from haystack.utils import Secret, deserialize_secrets_inplace
from haystack.utils.filters import convert

import pinecone
Expand All @@ -29,7 +29,7 @@ class PineconeDocumentStore:
def __init__(
self,
*,
api_key: Optional[str] = None,
api_key: Secret = Secret.from_env_var("PINECONE_API_KEY"), # noqa: B008
environment: str = "us-west1-gcp",
index: str = "default",
namespace: str = "default",
Expand Down Expand Up @@ -58,15 +58,16 @@ def __init__(
[API reference](https://docs.pinecone.io/reference/create_index-1).

"""
api_key = api_key or os.environ.get("PINECONE_API_KEY")
if not api_key:
resolved_api_key = api_key.resolve_value()
if resolved_api_key is None:
msg = (
"PineconeDocumentStore expects an API key. "
"Set the PINECONE_API_KEY environment variable (recommended) or pass it explicitly."
)
raise ValueError(msg)
self.api_key = api_key

pinecone.init(api_key=api_key, environment=environment)
pinecone.init(api_key=resolved_api_key, environment=environment)

if index not in pinecone.list_indexes():
logger.info(f"Index {index} does not exist. Creating a new index.")
Expand All @@ -92,9 +93,15 @@ def __init__(
self.batch_size = batch_size
self.index_creation_kwargs = index_creation_kwargs

@classmethod
def from_dict(cls, data: Dict[str, Any]) -> "PineconeDocumentStore":
deserialize_secrets_inplace(data["init_parameters"], keys=["api_key"])
return default_from_dict(cls, data)

def to_dict(self) -> Dict[str, Any]:
return default_to_dict(
self,
api_key=self.api_key.to_dict(),
environment=self.environment,
index=self.index,
dimension=self.dimension,
Expand Down
20 changes: 13 additions & 7 deletions integrations/pinecone/tests/test_document_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pytest
from haystack import Document
from haystack.testing.document_store import CountDocumentsTest, DeleteDocumentsTest, WriteDocumentsTest
from haystack.utils import Secret

from haystack_integrations.document_stores.pinecone import PineconeDocumentStore

Expand All @@ -13,7 +14,7 @@ def test_init(mock_pinecone):
mock_pinecone.Index.return_value.describe_index_stats.return_value = {"dimension": 30}

document_store = PineconeDocumentStore(
api_key="fake-api-key",
api_key=Secret.from_token("fake-api-key"),
environment="gcp-starter",
index="my_index",
namespace="test",
Expand All @@ -34,7 +35,7 @@ def test_init(mock_pinecone):

@patch("haystack_integrations.document_stores.pinecone.document_store.pinecone")
def test_init_api_key_in_environment_variable(mock_pinecone, monkeypatch):
monkeypatch.setenv("PINECONE_API_KEY", "fake-api-key")
monkeypatch.setenv("PINECONE_API_KEY", "env-api-key")

PineconeDocumentStore(
environment="gcp-starter",
Expand All @@ -45,14 +46,14 @@ def test_init_api_key_in_environment_variable(mock_pinecone, monkeypatch):
metric="euclidean",
)

mock_pinecone.init.assert_called_with(api_key="fake-api-key", environment="gcp-starter")
mock_pinecone.init.assert_called_with(api_key="env-api-key", environment="gcp-starter")


@patch("haystack_integrations.document_stores.pinecone.document_store.pinecone")
def test_to_dict(mock_pinecone):
def test_to_dict(mock_pinecone, monkeypatch):
mock_pinecone.Index.return_value.describe_index_stats.return_value = {"dimension": 30}
monkeypatch.setenv("PINECONE_API_KEY", "env-api-key")
document_store = PineconeDocumentStore(
api_key="fake-api-key",
environment="gcp-starter",
index="my_index",
namespace="test",
Expand All @@ -63,6 +64,13 @@ def test_to_dict(mock_pinecone):
assert document_store.to_dict() == {
"type": "haystack_integrations.document_stores.pinecone.document_store.PineconeDocumentStore",
"init_parameters": {
"api_key": {
"env_vars": [
"PINECONE_API_KEY",
],
"strict": True,
"type": "env_var",
},
"environment": "gcp-starter",
"index": "my_index",
"dimension": 30,
Expand All @@ -86,11 +94,9 @@ def test_write_documents_duplicate_fail(self, document_store: PineconeDocumentSt
def test_write_documents_duplicate_skip(self, document_store: PineconeDocumentStore): ...

def test_init_fails_wo_api_key(self, monkeypatch):
api_key = None
monkeypatch.delenv("PINECONE_API_KEY", raising=False)
with pytest.raises(ValueError):
PineconeDocumentStore(
api_key=api_key,
environment="gcp-starter",
index="my_index",
)
Expand Down
11 changes: 9 additions & 2 deletions integrations/pinecone/tests/test_emebedding_retriever.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ def test_init_default():


@patch("haystack_integrations.document_stores.pinecone.document_store.pinecone")
def test_to_dict(mock_pinecone):
def test_to_dict(mock_pinecone, monkeypatch):
monkeypatch.setenv("PINECONE_API_KEY", "env-api-key")
mock_pinecone.Index.return_value.describe_index_stats.return_value = {"dimension": 512}
document_store = PineconeDocumentStore(
api_key="test-key",
environment="gcp-starter",
index="default",
namespace="test-namespace",
Expand All @@ -35,6 +35,13 @@ def test_to_dict(mock_pinecone):
"init_parameters": {
"document_store": {
"init_parameters": {
"api_key": {
"env_vars": [
"PINECONE_API_KEY",
],
"strict": True,
"type": "env_var",
},
"environment": "gcp-starter",
"index": "default",
"namespace": "test-namespace",
Expand Down
Loading