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
2 changes: 1 addition & 1 deletion pyTigerGraph/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
from pyTigerGraph.pytgasync.pyTigerGraph import AsyncTigerGraphConnection
from pyTigerGraph.common.exception import TigerGraphException

__version__ = "1.8.8"
__version__ = "1.9.0"

__license__ = "Apache 2"
85 changes: 38 additions & 47 deletions pyTigerGraph/ai/ai.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""AI Submodule
The AI submodule is used to interact with the TigerGraph CoPilot service.
It allows users to register custom queries, run natural language queries, and interact with the CoPilot service.
The AI submodule is used to interact with the TigerGraph GraphRAG service.
It allows users to register custom queries, run natural language queries, and interact with the GraphRAG service.

To use the AI submodule, you must first create a TigerGraphConnection object, and verify that you have a TigerGraph CoPilot service running.
To use the AI submodule, you must first create a TigerGraphConnection object, and verify that you have a TigerGraph GraphRAG service running.

For example, to use the AI submodule, you can run the following code:

Expand All @@ -19,12 +19,12 @@

conn.getToken()

conn.ai.configureCoPilotHost(hostname="http://COPILOT_ADDRESS")
conn.ai.configureGraphRAGHost(hostname="http://GRAPHRAG_ADDRESS")

conn.ai.query("How many servers are there?")
----

For a more detailed and varied examples, see the demo notebooks in the (TigerGraph CoPilot GitHub repository)[https://github.com/tigergraph/CoPilot/tree/main/copilot/docs/notebooks].
For a more detailed and varied examples, see the demo notebooks in the (TigerGraph GraphRAG GitHub repository)[https://github.com/tigergraph/graphrag/tree/main/graphrag/docs/notebooks].
"""

import warnings
Expand All @@ -44,42 +44,33 @@ def __init__(self, conn: TigerGraphConnection) -> None:
"""
self.conn = conn
self.nlqs_host = None
self.aiserver = "supportai"
self.server_mode = "graphrag"
if conn.tgCloud:
# split scheme and host
scheme, host = conn.host.split("://")
self.nlqs_host = scheme + "://copilot-" + host
self.nlqs_host = scheme + "://graphrag-" + host

def configureInquiryAIHost(self, hostname: str):
""" DEPRECATED: Configure the hostname of the InquiryAI service.
Not recommended to use. Use configureCoPilotHost() instead.
def configureGraphRAGHost(self, hostname: str):
""" Configure the hostname of the GraphRAG service.
Not necessary if using TigerGraph GraphRAG on TigerGraph Cloud.
Args:
hostname (str):
The hostname (and port number) of the InquiryAI serivce.
The hostname (and port number) of the GraphRAG serivce.
"""
warnings.warn(
"The `configureInquiryAIHost()` function is deprecated; use `configureCoPilotHost()` function instead.",
DeprecationWarning)
self.nlqs_host = hostname
self.server_mode = "graphrag"

def configureCoPilotHost(self, hostname: str):
""" Configure the hostname of the CoPilot service.
Not necessary if using TigerGraph CoPilot on TigerGraph Cloud.
Args:
hostname (str):
The hostname (and port number) of the CoPilot serivce.
"""
self.nlqs_host = hostname

def configureServerHost(self, hostname: str, aiserver: str):
def configureServerHost(self, hostname: str, server: str):
""" Configure the hostname of the AI service.
Not necessary if using TigerGraph AI on TigerGraph Cloud.
Args:
hostname (str):
The hostname (and port number) of the CoPilot serivce.
The hostname (and port number) of the GraphRAG serivce.
server (str):
The service mode of the GraphRAG serivce.
"""
self.nlqs_host = hostname
self.aiserver = aiserver
self.server_mode = server

def registerCustomQuery(self, query_name: str, description: str = None, docstring: str = None, param_types: dict = None):
""" Register a custom query with the InquiryAI service.
Expand Down Expand Up @@ -225,10 +216,10 @@ def query(self, query):
url = self.nlqs_host+"/"+self.conn.graphname+"/query"
return self.conn._req("POST", url, authMode="pwd", data=data, jsonData=True, resKey=None)

def coPilotHealth(self):
""" Check the health of the CoPilot service.
def healthCheck(self):
""" Check the health of the GraphRAG service.
Returns:
JSON response from the CoPilot service.
JSON response from the GraphRAG service.
"""
url = self.nlqs_host+"/health"
return self.conn._req("GET", url, authMode="pwd", resKey=None)
Expand All @@ -238,22 +229,22 @@ def initializeSupportAI(self):
Returns:
JSON response from the SupportAI service.
"""
return self.initializeAIServer("supportai")
return self.initializeServer("supportai")

def initializeGraphAI(self):
def initializeGraphRAG(self):
""" Initialize the GraphAI service.
Returns:
JSON response from the GraphAI service.
"""
return self.initializeAIServer("graphai")
return self.initializeServer("graphrag")

def initializeAIServer(self, server="supportai"):
def initializeServer(self, server="graphrag"):
""" Initialize the given service.
Returns:
JSON response from the given service.
"""
self.aiserver = server
url = f"{self.nlqs_host}/{self.conn.graphname}/{self.aiserver}/initialize"
self.server_mode = server
url = f"{self.nlqs_host}/{self.conn.graphname}/{self.server_mode}/initialize"
return self.conn._req("POST", url, authMode="pwd", resKey=None)

def createDocumentIngest(self, data_source, data_source_config, loader_config, file_format):
Expand All @@ -277,7 +268,7 @@ def createDocumentIngest(self, data_source, data_source_config, loader_config, f
"file_format": file_format
}

url = f"{self.nlqs_host}/{self.conn.graphname}/{self.aiserver}/create_ingest"
url = f"{self.nlqs_host}/{self.conn.graphname}/{self.server_mode}/create_ingest"
return self.conn._req("POST", url, authMode="pwd", data=data, jsonData=True, resKey=None)

def runDocumentIngest(self, load_job_id, data_source_id, data_path, data_source="remote"):
Expand All @@ -300,10 +291,10 @@ def runDocumentIngest(self, load_job_id, data_source_id, data_path, data_source=
"data_source_id": data_source_id,
"file_path": data_path
}
url = f"{self.nlqs_host}/{self.conn.graphname}/{self.aiserver}/ingest"
url = f"{self.nlqs_host}/{self.conn.graphname}/{self.server_mode}/ingest"
return self.conn._req("POST", url, authMode="pwd", data=data, jsonData=True, resKey=None)

def searchDocuments(self, query, method="hnswoverlap", method_parameters: dict = {"indices": ["Document", "DocumentChunk", "Entity", "Relationship"], "top_k": 2, "num_hops": 2, "num_seen_min": 2}):
def searchDocuments(self, query, method="hybrid", method_parameters: dict = {"indices": ["Document", "DocumentChunk", "Entity", "Relationship"], "top_k": 2, "num_hops": 2, "num_seen_min": 2}):
""" Search documents.
Args:
query (str):
Expand All @@ -320,10 +311,10 @@ def searchDocuments(self, query, method="hnswoverlap", method_parameters: dict =
"method": method,
"method_params": method_parameters
}
url = self.nlqs_host+"/"+self.conn.graphname+"/supportai/search"
url = self.nlqs_host+"/"+self.conn.graphname+"/"+self.server_mode+"/search"
return self.conn._req("POST", url, authMode="pwd", data=data, jsonData=True, resKey=None)

def answerQuestion(self, query, method="hnswoverlap", method_parameters: dict = {"indices": ["Document", "DocumentChunk", "Entity", "Relationship"], "top_k": 2, "num_hops": 2, "num_seen_min": 2}):
def answerQuestion(self, query, method="hybrid", method_parameters: dict = {"indices": ["Document", "DocumentChunk", "Entity", "Relationship"], "top_k": 2, "num_hops": 2, "num_seen_min": 2}):
""" Answer a question.
Args:
query (str):
Expand All @@ -340,29 +331,29 @@ def answerQuestion(self, query, method="hnswoverlap", method_parameters: dict =
"method": method,
"method_params": method_parameters
}
url = self.nlqs_host+"/"+self.conn.graphname+"/supportai/answerquestion"
url = self.nlqs_host+"/"+self.conn.graphname+"/"+self.server_mode+"/answerquestion"
return self.conn._req("POST", url, authMode="pwd", data=data, jsonData=True, resKey=None)

def forceConsistencyUpdate(self, method="supportai"):
def forceConsistencyUpdate(self, method=""):
""" Force a consistency update for SupportAI embeddings.
Args:
method (str):
The doc initialization method to run
Currentlty only "supportai" is supported in CoPilot v0.9.
Returns:
JSON response from the consistency update.
"""
url = f"{self.nlqs_host}/{self.conn.graphname}/{method}/forceupdate/"
server = method if method else self.server_mode
url = f"{self.nlqs_host}/{self.conn.graphname}/{server}/forceupdate"
return self.conn._req("GET", url, authMode="pwd", resKey=None)

def checkConsistencyProgress(self, method="supportai"):
def checkConsistencyProgress(self, method=""):
""" Check the progress of the consistency update.
Args:
method (str):
The doc initialization method to check or run.
Currentlty only "supportai" is supported in CoPilot v0.9.
Returns:
JSON response from the consistency update progress.
"""
url = f"{self.nlqs_host}/{self.conn.graphname}/supportai/consistency_status/{method}"
server = method if method else self.server_mode
url = f"{self.nlqs_host}/{self.conn.graphname}/{server}/consistency_status"
return self.conn._req("GET", url, authMode="pwd", resKey=None)
14 changes: 13 additions & 1 deletion pyTigerGraph/pyTigerGraphQuery.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ def installQueries(self, queries: Union[str, list], flag: Union[str, list] = Non
logger.info("entry: installQueries")
if logger.level == logging.DEBUG:
logger.debug("params: " + self._locals(locals()))
self.ver = self.getVer()
major_ver, minor_ver, patch_ver = self.ver.split(".")
if int(major_ver) < 4 or int(major_ver) == 4 and int(minor_ver) == 0:
logger.info("exit: installQueries")
raise TigerGraphException(
"This function is only supported on versions of TigerGraph >= 4.1.0.", 0)

params = {}
params["graph"] = self.graphname
Expand Down Expand Up @@ -163,8 +169,14 @@ def getQueryInstallationStatus(self, requestId: str) -> dict:
logger.info("entry: getQueryInstallationStatus")
if logger.level == logging.DEBUG:
logger.debug("params: " + self._locals(locals()))
self.ver = self.getVer()
major_ver, minor_ver, patch_ver = self.ver.split(".")
if int(major_ver) < 4 or int(major_ver) == 4 and int(minor_ver) == 0:
logger.info("exit: getQueryInstallationStatus")
raise TigerGraphException(
"This function is only supported on versions of TigerGraph >= 4.1.0.", 0)

ret = self._req("GET", self.gsUrl + "/gsql/v1/queries/install&requestid=" + requestId, authMode="pwd", resKey="")
ret = self._req("GET", self.gsUrl + "/gsql/v1/queries/install/" + requestId, authMode="pwd", resKey="")

if logger.level == logging.DEBUG:
logger.debug("return: " + str(ret))
Expand Down
2 changes: 1 addition & 1 deletion pyTigerGraph/pytgasync/pyTigerGraphBase.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
The `AsyncTigerGraphConnection` object is the main object that you will interact with when using pyTigerGraph.
It provides the same core functionality as the synchronous `TigerGraphConnection` object, but with asynchronous methods.

**Note:** `AsyncTigerGraphConnection` does not currently support the GDS or TigerGraph CoPilot APIs found in the synchronous version.
**Note:** `AsyncTigerGraphConnection` does not currently support the GDS or TigerGraph GraphRAG APIs found in the synchronous version.

To test your connection, you can use the `echo()` method. This method sends a simple request to the server and returns the response.

Expand Down
16 changes: 14 additions & 2 deletions pyTigerGraph/pytgasync/pyTigerGraphQuery.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ async def installQueries(self, queries: Union[str, list], flag: Union[str, list]
logger.info("entry: installQueries")
if logger.level == logging.DEBUG:
logger.debug("params: " + self._locals(locals()))
self.ver = await self.getVer()
major_ver, minor_ver, patch_ver = self.ver.split(".")
if int(major_ver) < 4 or int(major_ver) == 4 and int(minor_ver) == 0:
logger.info("exit: installQueries")
raise TigerGraphException(
"This function is only supported on versions of TigerGraph >= 4.1.0.", 0)

params = {}
params["graph"] = self.graphname
Expand All @@ -143,7 +149,7 @@ async def installQueries(self, queries: Union[str, list], flag: Union[str, list]
break
else:
ret = None
time.sleep(1)
await asyncio.sleep(1)

if logger.level == logging.DEBUG:
logger.debug("return: " + str(ret))
Expand All @@ -168,8 +174,14 @@ async def getQueryInstallationStatus(self, requestId: str) -> dict:
logger.info("entry: getQueryInstallationStatus")
if logger.level == logging.DEBUG:
logger.debug("params: " + self._locals(locals()))
self.ver = await self.getVer()
major_ver, minor_ver, patch_ver = self.ver.split(".")
if int(major_ver) < 4 or int(major_ver) == 4 and int(minor_ver) == 0:
logger.info("exit: getQueryInstallationStatus")
raise TigerGraphException(
"This function is only supported on versions of TigerGraph >= 4.1.0.", 0)

ret = await self._req("GET", self.gsUrl + "/gsql/v1/queries/install&requestid=" + requestId, authMode="pwd")
ret = await self._req("GET", self.gsUrl + "/gsql/v1/queries/install/" + requestId, authMode="pwd", resKey="")

if logger.level == logging.DEBUG:
logger.debug("return: " + str(ret))
Expand Down