From f1a1bf63e7769886dda082874956412ff48e7fcc Mon Sep 17 00:00:00 2001 From: Parker Erickson Date: Tue, 16 Apr 2024 21:16:57 -0500 Subject: [PATCH] feat(gsql query descriptions): add description support --- pyTigerGraph/pyTigerGraphBase.py | 30 +++++++++- pyTigerGraph/pyTigerGraphQuery.py | 95 ++++++++++++++++++++++++++++++- 2 files changed, 121 insertions(+), 4 deletions(-) diff --git a/pyTigerGraph/pyTigerGraphBase.py b/pyTigerGraph/pyTigerGraphBase.py index 75386b67..ae4874e1 100644 --- a/pyTigerGraph/pyTigerGraphBase.py +++ b/pyTigerGraph/pyTigerGraphBase.py @@ -278,7 +278,7 @@ def _req(self, method: str, url: str, authMode: str = "token", headers: dict = N _headers.update(self.awsIamHeaders) if self.responseConfigHeader: _headers.update(self.responseConfigHeader) - if method == "POST" or method == "PUT": + if method == "POST" or method == "PUT" or method == "DELETE": _data = data else: _data = None @@ -387,8 +387,32 @@ def _post(self, url: str, authMode: str = "token", headers: dict = None, logger.info("exit: _post") return res + + def _put(self, url: str, authMode: str = "token", data = None, resKey=None, jsonData=False) -> Union[dict, list]: + """Generic PUT method. + + Args: + url: + Complete REST++ API URL including path and parameters. + authMode: + Authentication mode, either `"token"` (default) or `"pwd"`. + + Returns: + The response from the request (as a dictionary). + """ + logger.info("entry: _put") + if logger.level == logging.DEBUG: + logger.debug("params: " + self._locals(locals())) + + res = self._req("PUT", url, authMode, data=data, resKey=resKey, jsonData=jsonData) + + if logger.level == logging.DEBUG: + logger.debug("return: " + str(res)) + logger.info("exit: _put") + + return res - def _delete(self, url: str, authMode: str = "token") -> Union[dict, list]: + def _delete(self, url: str, authMode: str = "token", data: dict = None, resKey=None, jsonData=False) -> Union[dict, list]: """Generic DELETE method. Args: @@ -404,7 +428,7 @@ def _delete(self, url: str, authMode: str = "token") -> Union[dict, list]: if logger.level == logging.DEBUG: logger.debug("params: " + self._locals(locals())) - res = self._req("DELETE", url, authMode) + res = self._req("DELETE", url, authMode, data=data, resKey=resKey, jsonData=jsonData) if logger.level == logging.DEBUG: logger.debug("return: " + str(res)) diff --git a/pyTigerGraph/pyTigerGraphQuery.py b/pyTigerGraph/pyTigerGraphQuery.py index 8aff5afd..2b05e693 100644 --- a/pyTigerGraph/pyTigerGraphQuery.py +++ b/pyTigerGraph/pyTigerGraphQuery.py @@ -7,7 +7,7 @@ import logging from datetime import datetime -from typing import TYPE_CHECKING, Union +from typing import TYPE_CHECKING, Union, Optional if TYPE_CHECKING: import pandas as pd @@ -591,3 +591,96 @@ def getStatistics(self, seconds: int = 10, segments: int = 10) -> dict: logger.info("exit: getStatistics") return ret + + def describeQuery(self, queryName: str, queryDescription: str, parameterDescriptions: dict = {}): + """Add a query description and parameter descriptions. + + Args: + queryName: + The name of the query to describe. + queryDescription: + A description of the query. + parameterDescriptions (optional): + A dictionary of parameter descriptions. The keys are the parameter names and the values are the descriptions. + + Returns: + The response from the database. + """ + logger.info("entry: describeQuery") + + if parameterDescriptions: + params = {"queries": [ + {"queryName": queryName, + "description": queryDescription, + "parameters": [{"paramName": k, "description": v} for k, v in parameterDescriptions.items()]} + ]} + else: + params = {"queries": [ + {"queryName": queryName, + "description": queryDescription} + ]} + if logger.level == logging.DEBUG: + logger.debug("params: " + params) + res = self._put(self.gsUrl+"/gsqlserver/gsql/description?graph="+self.graphname, data=params, authMode="pwd", jsonData=True) + + if logger.level == logging.DEBUG: + logger.debug("return: " + str(res)) + logger.info("exit: describeQuery") + + return res + + def getQueryDescription(self, queryName: Optional[Union[str, list]] = "all"): + """Get the description of a query. + + Args: + queryName: + The name of the query to get the description of. + If multiple query descriptions are desired, pass a list of query names. + If set to "all", returns the description of all queries. + + Returns: + The description of the query(ies). + """ + logger.info("entry: getQueryDescription") + if logger.level == logging.DEBUG: + logger.debug("params: " + self._locals(locals())) + + if isinstance(queryName, list): + queryName = ",".join(queryName) + + res = self._get(self.gsUrl+"/gsqlserver/gsql/description?graph="+self.graphname+"&query="+queryName, authMode="pwd", resKey=None) + if not res["error"]: + if logger.level == logging.DEBUG: + logger.debug("exit: getQueryDescription") + return res["queries"] + else: + raise TigerGraphException(res["message"], res["code"]) + + def dropQueryDescription(self, queryName: str, dropParamDescriptions: bool = True): + """Drop the description of a query. + + Args: + queryName: + The name of the query to drop the description of. + If set to "*", drops the description of all queries. + dropParamDescriptions: + Whether to drop the parameter descriptions as well. Defaults to True. + + Returns: + The response from the database. + """ + logger.info("entry: dropQueryDescription") + if logger.level == logging.DEBUG: + logger.debug("params: " + self._locals(locals())) + if dropParamDescriptions: + params = {"queries": [queryName], "queryParameters": [queryName+".*"]} + else: + params = {"queries": [queryName]} + print(params) + res = self._delete(self.gsUrl+"/gsqlserver/gsql/description?graph="+self.graphname, authMode="pwd", data=params, jsonData=True) + + if logger.level == logging.DEBUG: + logger.debug("return: " + str(res)) + logger.info("exit: dropQueryDescription") + + return res \ No newline at end of file