Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
Feb 23, 2021 4:08:26 AM
Jan 25, 2019 9:48:37 AM
This is a Python example to call the Qlik Sense Engine API.
Here is a simple script using the websocket-client module to call the Engine API. Note that the Qlik Sense virtual proxy is set to header authentication.
import websocket import ssl import json header_user = {'header_user': 'user1'} ws = websocket.create_connection("wss://qlikserver1.domain.local/hdr/app/", sslopt={"cert_reqs": ssl.CERT_NONE},header=header_user) ws.send(json.dumps({ "handle": -1, "method": "GetDocList", "params": [], "outKey": -1, "id": 1 })) result = ws.recv() while result: result=ws.recv() y = json.loads(result) print(y) ws.close()
Example of results:
{'jsonrpc': '2.0', 'method': 'OnConnected', 'params': {'qSessionState': 'SESSION_CREATED'}} {'jsonrpc': '2.0', 'id': 1, 'result': {'qDocList': [{'qDocName': 'test1', 'qConnectedUsers': 0, 'qFileTime': 0, 'qFileSize': 176418, 'qDocId': '9b428869-0fba-4ba5-9f94-901ae2fdf041', 'qMeta': {'createdDate': '2018-11-29T09:28:40.588Z', 'modifiedDate': '2018-12-17T15:13:56.860Z', 'published': True, 'publishTime': '2018-12-17T15:13:56.782Z', 'privileges': ['read', 'offlineaccess'], 'description': '', 'dynamicColor': '', 'create': None, 'stream': {'id': 'aaec8d41-5201-43ab-809f-3063750dfafd', 'name': 'Everyone'}, 'canCreateDataConnections': False}, 'qLastReloadTime': '2018-11-29T09:30:42.121Z', 'qTitle': 'test1', 'qThumbnail': {}}]}}
@Damien_V , hi!
Tell me, please, when I try to use this code for myself, I encounter an authorization problem. Can you tell me how to specify a username and password for authorization when using the Qlik Engine API.
Thanks!
Hello @g_bolshakov
This code sample is using header authentication, so you need to create a virtual proxy in the QMC that is using header authentication.
header authentication is not secure if not used in combination with an external proxy/reverse proxy that would limit which end user is allowed to send the header to Qlik Sense.
I would recommend you use JWT authentication, it's simple to set up and more secure.
Then just update this line:
header_user = {'header_user': 'user1'}
to
header_user = {'Authorization': 'Bearer (your jwt token)'}
You can generate a test JWT token from https://jwt.io
Hi @g_bolshakov , did you find how to authenticate with a username and password? I am also struggling with this. Thanks!
If you mean username and password for Windows credentials, then it's not possible directly as the Engine API websocket cannot handle Windows authentication directly.
You would need to rebuild one part of the authentication workflow in your code, validate Windows credentials and issue a ticket by calling the Qlik Proxy API for example.
Or you can use JWT authentication as previously suggested, still that you would be up to you to validate user credentials within your code upfront before injecting the JWT token.
Thanks, @Damien_V ,
I've managed to rebuild part of the authentication workflow, issuing a ticket by calling the Qlik Proxy API for example, as you mentioned.
Best,
Hi @Damien_V ,
This get information about an app, but is there a way to receive a result from a app, like example, execute it and get the result ?
@Damien_V , thank you for this! I've been able to get it connect. Is there any documentation or examples that you might point me to better understand how to actually query and instantiate different objects? For example, when I use the Engine Explorer, I can call different methods tied to different objects (App, sheet, or data table, for example).
I don't yet understand how I can (or if I need to) instantiate these different objects to then query for children, and ultimately run an exportData on the data table. Any materials you could point me to for further learning would be appreciated.
Geoff
I believe what you are searching for is EvaluateEx() ?
It will evaluate an expression in the app and return the result
https://help.qlik.com/en-US/sense-developer/November2020/APIs/EngineAPI/services-Doc-EvaluateEx.html
@beatYesterday When you open/instantiate an app or an object, it will return a handle (check the "qHandle" parameter in the response of the request to know the number)
You will need to use the handle number in your new request to indicate which object you want to query.
The handle for the global interface where you can create/open app is always -1, but the other handles will vary based on the order in which you have opened the different objects.
I'm trying to do exactly as you recommend, use WS to connect and product ExportData object, and then navigate to the csv temp location via a get request in Python. However, when I try to navigate to the file location I am prompted to enter in the credentials, even though I'm sending the request(I think) to use the certificates. I have also tried using the Session API to generate a new sesssionID via POST request, and then use that SessionID with a subsequent GET request to the csv file.
I have verified that a user session is being created on the Qlik server with the POST request, but the GET request for the file still redirects to the login page. Below is the code I'm using for this:
createSessionURL = "https://host/qps/session?xrfkey=1234567890123457"
postHeaders={ "X-Qlik-User": "UserDirectory=<DIRECTORY>;UserId=<USER>",
"X-Qlik-XrfKey": "1234567890123457",
"COntent-type":"application/json"
}
body ="""
{
"UserDirectory": "<DIRECTORY>",
"UserId": "<USER>",
"Attributes": [ ],
"SessionId": "11111111"
}
"""
#use created session ID to get output of Engine API exportData function
r = requests.post(createSessionURL, headers= postHeaders, cert =(pemPath,pemKeyPath), verify=False, allow_redirects=True, data=body)
#set headers
getHeaders = { "X-Qlik-User": "UserDirectory=<DIRECTORY>;UserId=<USER>",
"X-Qlik-XrfKey": "1234567890123457",
"X-Qlik-Session": "11111111"
}
csvURL = "https://host/tempcontent/<randomlyGeneratedPath>.csv?serverNodeId=<SERVERNODE>&xrfkey=1234567890123457'
#make call for file
r2 = requests.get(csvURL, headers= getHeaders, cert =(pemPath,pemKeyPath), verify=False, allow_redirects=True)
Thank you again for your assistance and guidance,