Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
Hi, I'm trying to connect to the engine api of qlik sense enterprise via a virtual proxy and have primarily been following https://community.qlik.com/t5/Official-Support-Articles/Qlik-Sense-call-Qlik-Sense-Engine-API-with-P... and https://community.qlik.com/t5/Integration-Extension-APIs/Can-t-perform-a-simple-Engine-API-call-to-a...
This is the current code I have, which is failing at the connection creation with "ValueError: scheme https is invalid". I have tried ws instead of wss, but this just causes the call to hang, and I've tried simply sslopt={"cert_reqs": ssl.CERT_NONE}, but I get the same value error.
import websocket
import ssl
import json
userdirectory = '<directory>'
userid = '<user>'
cert_path = '/path/to/cert-folder'
certs = ({"ca_certs":f'{cert_path}/root.pem',
"certfile": f'{cert_path}/client.pem',
"keyfile": f'{cert_path}/client_key.pem',
"cert_reqs": ssl.CERT_NONE,
"server_side": False})
header_user = {'header_user': f'{userdirectory}\\{userid}'}
ssl_context = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
ssl_context.load_cert_chain(certfile=f'{cert_path}/client.pem', keyfile=f'{cert_path}/client_key.pem')
ws = websocket.create_connection(
"wss://<domain>/<proxy-prefix>/app",
sslopt={"cert_reqs": ssl.CERT_NONE; "ssl_context": ssl_context},
header=header_user
)
print("Sending message")
ws.send(json.dumps({
"handle": -1,
"method": "GetDocList",
"params": [],
"outKey": -1,
"id": 1
}))
result = ws.recv()
print(result)
ws.close()
ok, I tried on my end and if you are trying to connect with certificates, you have to connect directly to 4747 port (check if the port is open from Qlik Server).
Furthermore I have changed the way you are passing the certs. Below code works for me.
from websocket import create_connection
import json
import ssl
host = 'QMI-QS-f716'
cert_path = './certs'
user_directory, user_id = "QMI-QS-f716","qlik"
url = "wss://{0}:4747/app/".format(host)
certs = ({"ca_certs": f'{cert_path}/root.pem',
"certfile": f'{cert_path}/client.pem',
"keyfile": f'{cert_path}/client_key.pem',
"cert_reqs":ssl.CERT_REQUIRED,
"server_side": False
})
ssl.match_hostname = lambda cert, hostname: True
ws = create_connection(url, sslopt=certs,header={'X-Qlik-User: UserDirectory={0}; UserId={1}'.format(user_directory, user_id)})
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()
Hey @jjb427 when you are passing a user in the headers you should use this syntax
headers: {
'X-Qlik-User': `UserDirectory=${encodeURIComponent(config.userDirectory)}; UserId=${encodeURIComponent(config.userId)}`,
}
Please fix this and try again.
Hi @alex_colombo, I tried that header format (python code below), but I am continuing to get the "scheme https is invalid" error
encoded_user_directory = urllib.parse.quote(user_directory)
encoded_user_id = urllib.parse.quote(user_id)
x_qlik_user_header = f"UserDirectory={encoded_user_directory}; UserId={encoded_user_id}"
headers = [
f"X-Qlik-User: {x_qlik_user_header}"
]
ok, I tried on my end and if you are trying to connect with certificates, you have to connect directly to 4747 port (check if the port is open from Qlik Server).
Furthermore I have changed the way you are passing the certs. Below code works for me.
from websocket import create_connection
import json
import ssl
host = 'QMI-QS-f716'
cert_path = './certs'
user_directory, user_id = "QMI-QS-f716","qlik"
url = "wss://{0}:4747/app/".format(host)
certs = ({"ca_certs": f'{cert_path}/root.pem',
"certfile": f'{cert_path}/client.pem',
"keyfile": f'{cert_path}/client_key.pem',
"cert_reqs":ssl.CERT_REQUIRED,
"server_side": False
})
ssl.match_hostname = lambda cert, hostname: True
ws = create_connection(url, sslopt=certs,header={'X-Qlik-User: UserDirectory={0}; UserId={1}'.format(user_directory, user_id)})
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()
Hi @alex_colombo, thank you so much for your help with this. We would actually like to authenticate using the virtual proxy as opposed to certificates, but I've got this working with the following code:
import websocket
import ssl
import json
user_directory, user_id = "<user_directory>","<user_id>"
header_user = {'header_user': f'{user_directory}\\{user_id}'}
ws = websocket.create_connection("wss://<host>/<proxy-prefix>/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()