How do you pass SET parameters using pyTigerGraph

I have a query that requires SET parameters for a NOT IN where clause. I’m having problems with sending that through pyTigerGraph. For instance the simple query

CREATE QUERY test_passing_parameters(SET<string> params) FOR GRAPH plustoken { 
  /* Write query logic here */ 
  PRINT params; 
}

from the GSQL client works as expected:

GSQL > run query test_passing_parameters(["hola", "mundo"])
{
  "error": false,
  "message": "",
  "version": {
    "schema": 2,
    "edition": "enterprise",
    "api": "v2"
  },
  "results": [{"params": [
    "mundo",
    "hola"
  ]}]
}

But that same query sent through pyTigerGraph:

conn.runInstalledQuery("test_passing_parameters", params={"params": ["hola", "mundo"]})

returns a list of a single string:

[{'params': ["['hola', 'mundo']"]}]

What is the right format for sending SET parameters in Python?

Hi,

I am not very familiar with pyTigerGraph, but I just took a look at the source code. It uses the urllib.parse module to parse parameters from dict to query strings and appends the query strings to the end of the URL. This means that {"params": ["hola", "mundo"]} becomes 'params=%5B%27hola%27%2C%20%27mundo%27%5D', which is ['hola', 'mundo'] when decoded.

When parameters are supplied in query strings, TigerGraph’s Run installed query REST endpoint needs sets and bags to be formatted as params=hola&params=mundo in order for RESTPP to parse the parameters correctly. See Query String Parameters, so ['hola', 'mundo'] won’t work.

What you can do is format your params as query strings to begin with. That way, pyTigerGraph won’t try to change it:
conn.runInstalledQuery("test_passing_parameters", params="params=hola&params=mundo")

I just tested it and it seems to work:
>>> conn.runInstalledQuery("setTest", params="params=hola&params=mundo") [{'params': ['mundo', 'hola']}]

Hope this helps!

Best,
Lenny

1 Like

Thanks, it worked!! If I have time, this is a good candidate for a PR so I don’t need to remember this witchery.

Note that this technique doesn’t just apply to pyTigerGraph, but also applies to any API calls where you want to pass multiple values for a SET argument, here is another example

import requests 
graphQuery = 'zMarkTest?params=hola&params=mundo' 
myUrl = 'https://' + graphServer + ':' + graphPort + '/query/' + graphName + '/' + graphQuery  
response = requests.get(myUrl) 
print ("status = ", response.status_code, '\n') 
r = response.json()
1 Like

Just my 2 cents as a developer. If an API is exposing a set or bag and I’m working in Python I would expect those concepts to be mapped to set and list. Same thing if I’m doing Java, I would expect java.util.Set and java.util.List. Right now you are exposing the internal implementation to the API users, in fact the resolution of the issue involved digging into the HTTP calls in the code.

I would strongly encourage to make a more idiomatic API.