Skip to main content

Qlik Sense: call Qlik Sense Engine API with Python

No ratings
cancel
Showing results for 
Search instead for 
Did you mean: 
Damien_Villaret
Support
Support

Qlik Sense: call Qlik Sense Engine API with Python

Last Update:

Feb 23, 2021 4:08:26 AM

Updated By:

Sonja_Bauernfeind

Created date:

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': {}}]}}


 

Labels (1)
Comments
g_bolshakov
Contributor III
Contributor III

@Damien_Villaret , 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!

Damien_Villaret
Support
Support

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

ricardolsmendes
Contributor
Contributor

Hi @g_bolshakov , did you find how to authenticate with a username and password? I am also struggling with this. Thanks!

Damien_Villaret
Support
Support

Hi @ricardolsmendes 

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.

ricardolsmendes
Contributor
Contributor

Thanks, @Damien_Villaret , 

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,

eduardo_dimperio
Specialist II
Specialist II

Hi @Damien_Villaret ,

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 ?

beatYesterday
Contributor III
Contributor III

@Damien_Villaret , 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

Damien_Villaret
Support
Support

@eduardo_dimperio 

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

Damien_Villaret
Support
Support

@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.

beatYesterday
Contributor III
Contributor III

@Damien_Villaret , 

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,

Contributors
Version history
Last update:
‎2021-02-23 04:08 AM
Updated by: