Skip to main content
Announcements
Customer Spotlight: Discover what’s possible with embedded analytics Oct. 16 at 10:00 AM ET: REGISTER NOW
cancel
Showing results for 
Search instead for 
Did you mean: 
jjb427
Partner - Contributor III
Partner - Contributor III

"ValueError: scheme https is invalid" when trying to connect to engine api via proxy

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()

 

Labels (2)
1 Solution

Accepted Solutions
alex_colombo
Employee
Employee

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()

View solution in original post

4 Replies
alex_colombo
Employee
Employee

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.

jjb427
Partner - Contributor III
Partner - Contributor III
Author

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}"
]

 

alex_colombo
Employee
Employee

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()
jjb427
Partner - Contributor III
Partner - Contributor III
Author

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()