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': {}}]}}
All,
After further research and trial and error I was able to figure out how to do this. I'm adding the general code of how I did this below for others' reference.
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"
}
"""
#CREATE A SESSION OBJECT
s = requests.Session()
#use created session ID to get output of Engine API exportData function, this returns a session object with the sessionID you define
r = s.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'
#set Qlik Session Cookie with the same sessionID defined in post requests
s.cookies.set("X-Qlik-Session", '11111111', domain = <qlikHostDomain>)
#make call for file
r2 = s.get(csvURL, headers= getHeaders, cert =(pemPath,pemKeyPath), verify=False, allow_redirects=True)
Can you also give an example in Qlik Sense Desktop?
Hello @su_
The same example applies to Qlik Sense Desktop. See Connecting to the Qlik Engine JSON API.
What will change is:
Qlik Sense Enterprise: wss://server.domain.com:4747/app/ or wss://server.domain.com[/virtual proxy]/app/
Qlik Sense Desktop: ws://localhost:4848/app/
All the best,
Sonja
Hello @Sonja_Bauernfeind,
I wrote this code to submit 2 API requests
I was able to get proper responses from the Qlik server for each API request, but the dimension was never created. I wonder if you would have any clue? See codes and responses below
Code:
import websockets
import json
import asyncio
import time
url = "ws://localhost:4848/app/"
req_open_doc = {
"method": "OpenDoc",
"handle": -1,
"params": [
"C:\\Users\\my_directory\\my_dashboard.qvf"
],
"id": 1,
"outKey": -1,
}
req_create_dim = {
"jsonrpc": "2.0",
"handle": 1,
"id": 2,
"method": "CreateDimension",
"params": {
"qProp": {
"qInfo": {
"qId": "aaaaa",
"qType": "dimension"
},
"qDim": {
"qGrouping": 'N',
"qFieldDefs": [
"AAC-VERSION PACKAGES"
],
"qFieldLabels": [
""
],
"qLabelExpression": ""
},
"qMetaDef": {
"title": "HelloFeature",
"description": "",
"tags": [
"group_HeyFeatureGroup"
]
}
}
}
}
async def call_api():
async with websockets.connect(url) as ws:
await ws.send(json.dumps(req_open_doc))
result = await ws.recv()
print(result)
result = await ws.recv()
print(result)
await ws.send(json.dumps(req_create_dim))
result = await ws.recv()
print(result)
# result = await ws.recv()
# print(result)
asyncio.get_event_loop().run_until_complete(call_api())
Response:
{"jsonrpc":"2.0","method":"OnConnected","params":{"qSessionState":"SESSION_CREATED"}}
{"jsonrpc":"2.0","id":1,"result":{"qReturn":{"qType":"Doc","qHandle":1,"qGenericId":"C:\\my_directory\\my_dashboard.qvf"}},"change":[1]}
{"jsonrpc":"2.0","id":2,"result":{"qReturn":{"qType":"GenericDimension","qHandle":2,"qGener
Hello @su_
If you require assistance troubleshooting custom code, please post your question directly in the relevant forum: Integration, Extensions & APIs. If you need direct engagement from Qlik to assist you, I would recommend our Professional Services.
All the best,
Sonja
Hi All, I am trying to use webscocket Api to connect Qlik Cloud , to pull a table from the cloud and to convert it to the Dataframe panda but I am having issue. It was connecting to the cloud but could not pull the table to my jupyter notebook. here is the code:
import asyncio
import websockets
import json
import pandas as pd
import nest_asyncio
# Apply the nest_asyncio patch
nest_asyncio.apply()
# Configuration
qlikcloud_url = "wss://mytenant.eu.qlikcloud.com//app/f5555629-bb12-4983-854b-1ed7c9682f55"
api_key = "api key"
app_id = "f5555629-bb12-4983-854b-1ed7c9682f55"
table_object_id = 'ZgGPbV'
async def get_table_data():
async with websockets.connect(
qlikcloud_url,
extra_headers={
"Authorization": f"Bearer {api_key}"
}
) as websocket:
# Open the app
open_doc_request = {
"jsonrpc": "2.0",
"id": 1,
"method": "OpenDoc",
"handle": -1,
"params": {
"qDocName": app_id,
"qNoData": True
}
}
await websocket.send(json.dumps(open_doc_request))
response = await websocket.recv()
open_doc_response = json.loads(response)
print(f"Open Doc Response: {open_doc_response}")
# Check if the 'result' key is in the open doc response
if 'result' in open_doc_response:
doc_handle = open_doc_response['result']['qReturn']['qHandle']
print(f"Document Handle: {doc_handle}")
# Get the object handle
get_object_request = {
"jsonrpc": "2.0",
"id": 2,
"method": "GetObject",
"handle": doc_handle,
"params": {
"qId": table_object_id
}
}
await websocket.send(json.dumps(get_object_request))
response = await websocket.recv()
get_object_response = json.loads(response)
print(f"Get Object Response: {get_object_response}")
if 'result' in get_object_response:
object_handle = get_object_response['result']['qReturn']['qHandle']
print(f"Object Handle: {object_handle}")
# Get the layout of the object
get_layout_request = {
"jsonrpc": "2.0",
"id": 3,
"method": "GetLayout",
"handle": object_handle,
"params": {}
}
await websocket.send(json.dumps(get_layout_request))
response = await websocket.recv()
layout_response = json.loads(response)
print(f"Table Layout: {layout_response}")
# Check if the 'result' key is in the layout response
if 'result' in layout_response and 'qLayout' in layout_response['result']:
qLayout = layout_response['result']['qLayout']
# Send request to get table data
get_data_request = {
"jsonrpc": "2.0",
"id": 4, "method": "GetHyperCubeData",
"handle": object_handle,
"params": {
"qPath": "/qHyperCubeDef",
"qPages": [{"qTop": 0, "qLeft": 0, "qHeight": 1000, "qWidth": 10}]
}
}
await websocket.send(json.dumps(get_data_request))
response = await websocket.recv()
table_data_response = json.loads(response)
print(f"Table Data: {table_data_response}")
# Check if 'result' key is in the table data response
if 'result' in table_data_response:
table_data = table_data_response['result']['qDataPages'][0]
print(f"Table Data Pages: {table_data}")
rows = table_data['qMatrix']
columns = qLayout['qHyperCube']['qDimensionInfo'] + qLayout['qHyperCube']['qMeasureInfo']
parsed_data = []
for row in rows:
parsed_row = {}
for col, value in zip(columns, row): parsed_row[col['qFallbackTitle']] = value['qText']
parsed_data.append(parsed_row)
# Convert to DataFrame
df = pd.DataFrame(parsed_data)
print(df)
# Optionally save to CSV
df.to_csv("qlikcloud_table_data.csv", index=False)
else:
print("Error: 'result' key not found in table data response.")
else:
print("Error: 'qLayout' key not found in layout response.")
else:
print("Error: 'result' key not found in GetObject response.")
else:
print("Error: 'result' key not found in OpenDoc response.")
print(f"Full OpenDoc Response: {open_doc_response}")
# Run the async function
asyncio.get_event_loop().run_until_complete(get_table_data())
but I keep on getting this error:
pen Doc Response: {'jsonrpc': '2.0', 'method': 'OnConnected', 'params': {'qSessionState': 'SESSION_ATTACHED'}}
Error: 'result' key not found in OpenDoc response.
Full OpenDoc Response: {'jsonrpc': '2.0', 'method': 'OnConnected', 'params': {'qSessionState': 'SESSION_ATTACHED'}}