Skip to content
Merged
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

Note: version releases in the 0.x.y range may include both bug fixes and new features, not strictly limited to patches.

## 0.2.14
- feat: add API to fetch query info and Graph method to check query installation

## 0.2.13
- feat: rename parameter `secret` to `secret_alias` in `create_token` method for clarity
- feat: add strict type checks for column_name formatting and raise errors on invalid inputs
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "tigergraphx"
version = "0.2.13"
version = "0.2.14"
description = "TigerGraphX is a high-level Python library offering a unified, Python-native interface for graph databases, advanced analytics, and GraphRAG workflows. Combining the simplicity of NetworkX with the advanced capabilities of TigerGraph, including tgCloud, it empowers Python developers to harness the power of graphs without the need to learn query languages like Cypher or GSQL."
authors = ["Xuanlei Lin <xuanlei.lin@tigergraph.com>"]
license = "MIT"
Expand Down
6 changes: 4 additions & 2 deletions tests/integration/core/graph_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,9 @@ def test_create_install_run_and_drop_query(self):
Test creating, running, and dropping a GSQL query using the integration setup.
"""
# Define a GSQL query to install
query_name = "getUserPurchases"
gsql_query = f"""
CREATE QUERY getUserPurchases(VERTEX<User> user) FOR GRAPH {self.G.name} {{
CREATE QUERY {query_name}(VERTEX<User> user) FOR GRAPH {self.G.name} {{
Start = {{user}};
Purchases = SELECT tgt FROM Start:s - (purchased:e) -> :tgt;
PRINT Purchases;
Expand All @@ -369,8 +370,9 @@ def test_create_install_run_and_drop_query(self):
assert success is True, "Expected query to be successfully created"

# Install the query
query_name = "getUserPurchases"
assert not self.G.is_query_installed(query_name)
success = self.G.install_query(query_name)
assert self.G.is_query_installed(query_name)
assert success is True, "Expected query to be successfully created"

# Run the query
Expand Down
3 changes: 3 additions & 0 deletions tigergraphx/config/endpoint_definitions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ endpoints:
path: "/restpp/query/{graph_name}/{query_name}"
method: "POST"

get_query_info:
path: "/gsql/v1/queries/info?graph={graph_name}"

# ------------------------------ Upsert ------------------------------
upsert_graph_data:
path: "/restpp/graph/{graph_name}"
Expand Down
16 changes: 15 additions & 1 deletion tigergraphx/core/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@ def drop_graph(self) -> None:
return self._schema_manager.drop_graph()

# ------------------------------ Data Loading Operations ------------------------------
def load_data(self, loading_job_config: LoadingJobConfig | Dict | str | Path) -> str:
def load_data(
self, loading_job_config: LoadingJobConfig | Dict | str | Path
) -> str:
"""
Load data into the graph using the provided loading job configuration.

Expand Down Expand Up @@ -531,6 +533,18 @@ def run_query(self, query_name: str, params: Dict = {}) -> Optional[List]:
"""
return self._query_manager.run_query(query_name, params)

def is_query_installed(self, query_name: str) -> bool:
"""
Check if a query is installed on the graph.

Args:
query_name: Name of the query.

Returns:
True if the query is installed, False otherwise.
"""
return self._query_manager.is_query_installed(query_name)

def get_nodes(
self,
node_type: Optional[str] = None,
Expand Down
14 changes: 14 additions & 0 deletions tigergraphx/core/managers/query_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,20 @@ def run_query(self, query_name: str, params: Dict = {}) -> Optional[List]:
logger.error(f"Error running query {query_name}: {e}")
return None

def is_query_installed(self, query_name: str) -> bool:
try:
query_info = self._tigergraph_api.get_query_info(self._graph_name)
for query in query_info:
if (
query.get("name") == query_name
and query.get("installed")
):
return True
return False
except Exception as e:
logger.error(f"Error checking if query {query_name} is installed: {e}")
return False

def get_nodes(
self,
node_type: Optional[str] = None,
Expand Down
9 changes: 9 additions & 0 deletions tigergraphx/core/tigergraph_api/api/query_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ def run_installed_query_post(
raise TypeError(f"Expected list, but got {type(result).__name__}: {result}")
return result

def get_query_info(self, graph_name: str) -> List:
result = self._request(
endpoint_name="get_query_info",
graph_name=graph_name,
)
if not isinstance(result, list):
raise TypeError(f"Expected list, but got {type(result).__name__}: {result}")
return result

def _parse_query_parameters(self, params: Dict[str, Any]) -> Dict[str, Any]:
"""
Parses query parameters into a dictionary suitable for HTTP requests.
Expand Down
14 changes: 14 additions & 0 deletions tigergraphx/core/tigergraph_api/tigergraph_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,20 @@ def run_installed_query_post(
"""
return self._query_api.run_installed_query_post(graph_name, query_name, params)

def get_query_info(self, graph_name: str) -> List:
"""
Retrieve information about all queries for a given graph.

This includes query code, endpoints, parameters, and status.

Args:
graph_name: The name of the graph.

Returns:
API response as a list.
"""
return self._query_api.get_query_info(graph_name)

# ------------------------------ Upsert ------------------------------
def upsert_graph_data(self, graph_name: str, payload: Dict[str, Any]) -> List:
"""
Expand Down