Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ requires-python = ">=3.10"
dependencies = [
"httpx",
"pydantic>1",
"neo4j",
"pinecone-client",
]
dynamic = ["version"]
readme = "README.md"
Expand Down
6 changes: 2 additions & 4 deletions src/whyhow/apis/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,8 @@ def add_documents(self, namespace: str, documents: list[str]) -> str:
)

if len(document_paths) > 3:
raise ValueError(
"""Too many documents
please limit uploads to 3 files during the beta."""
)
raise ValueError("""Too many documents
please limit uploads to 3 files during the beta.""")

files = [
(
Expand Down
13 changes: 9 additions & 4 deletions src/whyhow/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
from httpx import AsyncClient, Auth, Client, Request, Response

from whyhow.apis.graph import GraphAPI
from whyhow.validations import VerifyConnectivity

BASE_URL = "https://43nq5c1b4c.execute-api.us-east-2.amazonaws.com"


class APIKeyAuth(Auth):
Expand Down Expand Up @@ -70,8 +73,7 @@ def __init__(
neo4j_url: str | None = None,
neo4j_user: str | None = None,
neo4j_password: str | None = None,
base_url:
str = "https://43nq5c1b4c.execute-api.us-east-2.amazonaws.com",
base_url: str = BASE_URL,
httpx_kwargs: dict[str, Any] | None = None,
) -> None:
"""Initialize the client."""
Expand Down Expand Up @@ -114,6 +116,10 @@ def __init__(
if neo4j_url is None:
raise ValueError("NEO4J_URL must be set.")

VerifyConnectivity(
neo4j_url, neo4j_user, neo4j_password, pinecone_api_key
)

auth = APIKeyAuth(
api_key,
openai_api_key,
Expand Down Expand Up @@ -166,8 +172,7 @@ def __init__(
neo4j_user: str | None = None,
neo4j_password: str | None = None,
neo4j_url: str | None = None,
base_url:
str = "https://43nq5c1b4c.execute-api.us-east-2.amazonaws.com",
base_url: str = BASE_URL,
httpx_kwargs: dict[str, Any] | None = None,
) -> None:
"""Initialize the client."""
Expand Down
35 changes: 35 additions & 0 deletions src/whyhow/validations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""Custom validators for whyhow sdk."""

from dataclasses import dataclass

import pinecone
from neo4j import GraphDatabase


@dataclass
class VerifyConnectivity:
"""This class will verify the connectivity with databases."""

neo4j_url: str
neo4j_user: str
neo4j_password: str
pinecone_api_key: str

def __post_init__(self):
"""
Verify neo4j and pinecone connectivity.

:return: None
"""
self._verify_neo4j_connectivity()
self._verify_pinecone_connectivity()

def _verify_neo4j_connectivity(self):
auth = (self.neo4j_user, self.neo4j_password)

with GraphDatabase.driver(self.neo4j_url, auth=auth) as driver:
driver.verify_connectivity()

def _verify_pinecone_connectivity(self):
pc_client = pinecone.Pinecone(api_key=self.pinecone_api_key)
pc_client.list_indexes()
18 changes: 16 additions & 2 deletions tests/apis/test_graph.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Tests focused on the graph API."""

import os
from unittest.mock import Mock

import pytest

Expand All @@ -11,6 +12,7 @@
QueryGraphResponse,
QueryGraphReturn,
)
from whyhow.validations import VerifyConnectivity

# Set fake environment variables
os.environ["WHYHOW_API_KEY"] = "fake_api_key"
Expand All @@ -35,8 +37,14 @@
class TestGraphAPIQuery:
"""Tests for the query_graph method."""

def test_query_graph(self, httpx_mock):
def test_query_graph(self, httpx_mock, monkeypatch):
"""Test querying the graph."""
connectivity_client = Mock(spec=VerifyConnectivity)
connectivity_client.return_value = None
monkeypatch.setattr(
"whyhow.client.VerifyConnectivity", connectivity_client
)

client = WhyHow()
query = "What friends does Alice have?"

Expand Down Expand Up @@ -69,8 +77,14 @@ def test_query_graph(self, httpx_mock):
class TestGraphAPIAddDocuments:
"""Tests for the add_documents method."""

def test_errors(self, httpx_mock, tmp_path):
def test_errors(self, monkeypatch, tmp_path):
"""Test error handling."""
connectivity_client = Mock(spec=VerifyConnectivity)
connectivity_client.return_value = None
monkeypatch.setattr(
"whyhow.client.VerifyConnectivity", connectivity_client
)

client = WhyHow()

with pytest.raises(ValueError, match="No documents provided"):
Expand Down
38 changes: 37 additions & 1 deletion tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

import pytest
from httpx import Client
from neo4j.exceptions import ConfigurationError

from whyhow.client import WhyHow
from whyhow.validations import VerifyConnectivity


class TestWhyHow:
Expand All @@ -23,6 +25,13 @@ def test_httpx_kwargs(self, monkeypatch):
fake_httpx_client_class = Mock(return_value=fake_httpx_client_inst)

monkeypatch.setattr("whyhow.client.Client", fake_httpx_client_class)

connectivity_client = Mock(spec=VerifyConnectivity)
connectivity_client.return_value = None
monkeypatch.setattr(
"whyhow.client.VerifyConnectivity", connectivity_client
)

httpx_kwargs = {"verify": False}
client = WhyHow(
api_key="key",
Expand All @@ -41,8 +50,35 @@ def test_httpx_kwargs(self, monkeypatch):

assert client.httpx_client is fake_httpx_client_class.return_value

def test_base_url_twice(self):
def test_credentials_verification(self, monkeypatch):
"""Test connectivity with databases."""
connectivity_client = Mock(spec=VerifyConnectivity)
connectivity_client.side_effect = ConfigurationError(
"Invalid credentials"
)
monkeypatch.setattr(
"whyhow.client.VerifyConnectivity", connectivity_client
)
with pytest.raises(ConfigurationError) as exc_info:
WhyHow(
api_key="mock_api_key",
neo4j_user="mock_neo4j_user",
neo4j_url="mock_neo4j_url",
neo4j_password="mock_neo4j_password",
pinecone_api_key="mock_pinecone_api_key",
)
assert "Invalid credentials" in str(
exc_info.value
), "The exception message is not as expected"

def test_base_url_twice(self, monkeypatch):
"""Test setting base_url in httpx_kwargs."""
connectivity_client = Mock(spec=VerifyConnectivity)
connectivity_client.return_value = None
monkeypatch.setattr(
"whyhow.client.VerifyConnectivity", connectivity_client
)

with pytest.raises(
ValueError, match="base_url cannot be set in httpx_kwargs."
):
Expand Down