Skip to main content
Announcements
Have questions about Qlik Connect? Join us live on April 10th, at 11 AM ET: SIGN UP NOW
cancel
Showing results for 
Search instead for 
Did you mean: 
Not applicable

QlikSense Import App via QRS and Powershell

Hi,

I'm trying to get Powershell to import an App on the central node of a QS 2.1.1 deployment. It is multi-node (if that makes any difference).

So far, I have successfully set up a Virtual Proxy for header auth and tested it using such commands as:

<server>/qrs/user/count?xrfkey=<xrfkey>

and all the relevant headers. This powershell script is based on QRSAPI - Remove Unwanted Users with PowerShell

However, when I come to use the "/qrs/app/import?name={name}&keepdata={keepdata}&replace={replace}" call

API ref: https://help.qlik.com/sense/2.1/en-US/developer/#../Subsystems/RepositoryServiceAPI/Content/Reposito...

I'm getting a "The remote server returned an error: (403) Forbidden." response.

I'm getting a "The remote server returned an error: (400) Bad Request" (I'd missed off the xrfkey in the above error on this specific call - doh)

The App is in %ProgramData%\Qlik\Sense\Apps folder.


Details:

----------

POST request to: http://<machinename>/<prefix>/qrs/app/import?name=<app name to be assigned>


Xrfkey, UserId and headers required by the virtual proxy have all been set correctly (I believe).



body = "{

            'id':'00000000-0000-0000-0000-000000000000',

            'columns':

                [

                    {

                        'name':'current_filename.qvf',

                    }

                ]

        }"


content type = "application/json"


I'm pretty certain that it is down to my usage of this API call as GET requests seem to work fine. Can anyone help please?


Thanks,


Dave

11 Replies
konrad_mattheis
Luminary Alumni
Luminary Alumni

Hi David,

frist try this Import app example so you can check if its working on you server. Than you can go the next step and do it with PowerShell.

bye

Konrad

Not applicable
Author

Thanks Konrad, we've got powershell to work with GETs and POSTs using a Virtual Proxy for header auth, so we know it's not a config issue.

We currently believe the problem is in the format of the POST for the specific API call to import


This works:


PS> QRScall.ps1

Command: http://<server.com>/<proxy_prefix>/qrs/license/requestaccesstype?Xrfkey=blah

Content-Type: application/json

Method: POST

Body: {

   "sessionID": "xxxxxxx",

   "hosttname": "[localhost, local]"

}

accessGranted     accessType                     accessTypeResultCode     schemaPath                                   

-------------              ----------                           --------------------                   ----------                                   

False                   0                                    3                                     AccessTypeResult

This doesn't:

PS> QRScall.ps1

Command: http://<server.com>/<proxy_prefix>/qrs/import?name=AppName?Xrfkey=blah

Content-Type: application/json

Method: POST

Body: {"name":"example.qvf"}

Invoke-RestMethod : The remote server returned an error: (400) Bad Request.

At QRScall:64 char:21

+         $response = Invoke-RestMethod $command -ContentType $contenttype -Header ...

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException

    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

The only difference was the call URL and the content of body in the post.

Thanks,

Dave

konrad_mattheis
Luminary Alumni
Luminary Alumni

Hi Dave,

to help you I would sugest 2 different things:

1. you attach your PS scripts or send them direct to me.

2. you try to make the upload with curl, if it is working use tools like fiddler / wireshark to record the real traffic between the server and the script for the curl upload and your ps1 upload and attach this.

bye Konrad

Not applicable
Author

Hi Konrad,

Thanks for your help. I finally got it working remotely, using Python's request module.

One thing to note: even if it the docs say the body should be a string, actually, by submitting it as a json of a string, it worked. I appreciate there are a lot of API calls, so this might not always be the case, but it is for the import call.

Dave

Anonymous
Not applicable
Author

Hi David,

Would you happen to have a code example to share for the Import POST call?

Struggling with the same thing here (actually looking to use the Upload call but figured once I get the Import working that should be easier to manage) and I'm running into the same issues as you I think.

Cheers,

Johannes

Not applicable
Author

Hi Johannes,

Sorry for the slow reply, but here is what works with Python:

xrfkey ={'key': 'Xrfkey', 'value': '<something>'}

headers ={

    'X-Qlik-Xrfkey': '<something>',

    'Content-Type': 'application/json'

    'Accept': 'application/json, text/plain, */*'

}

path_to_cert =<path to cert>

path_to_cert_key =<path to cert key>

AppName ='target name'# what it will appear as in QS.

payload ='filename'# that has already been moved to the PROGRAMDATA\Qlik\Sense\Apps folder, filename is a string at this point

qrs_url ='https://<domain_name>:4242/qrs/app/import?'+xrfkey['key'] +'='+xrfkey['value'] +'&name=<AppName>&keepdata=true'

# using json=payload ensure the string is encoded to JSON, which the QRS wants - it would not work for us as a string.

result =requests.post(

    qrs_url, json=payload, cert=(self.path_to_cert, self.path_to_cert_key), headers=self.headers, verify=False,

)

Notes: we are using certificates, not the header authentication proxy.


Kind Regards,


Dave

Not applicable
Author

Following node.js code works fine in my environment:

It imports an qvf file which is named as FindLongLat.qvf into qliksense server as an app which is named as FindLongLatImported.

----------------------------------------------------------------------------------------------------------------------

var https = require('https');

var fs = require('fs');

var options = {

    "rejectUnauthorized": false,

   hostname: '<hostname>',

   path: '/qrs/app/import?xrfkey=0123456789abcdef&name=FindLongLatImported',

   method: 'POST',

   port:4242,

    headers: {

      'x-qlik-xrfkey' : '0123456789abcdef',

      'X-Qlik-User' : 'UserDirectory= Internal; UserId= sa_repository',

      'Content-Type': 'application/json'

   },

   key: fs.readFileSync("C:\\client_key.pem"),

   cert: fs.readFileSync("C:\\client.pem"),

};

var req = https.request(options, function (res) {

    var responseString = "";

    res.on("data", function (data) {

        responseString += data;

    });

    res.on("end", function () {

        console.log(responseString);

    });

});

req.write('"FindLongLat.qvf"');

req.end();

----------------------------------------------------------------------------------------------------------------------

Please note that the catch is the double quotes around the qvf file name which is passed as body to the request.

So, req.write('FindLongLat.qvf') does NOT work, whereas req.write('"FindLongLat.qvf"') works fine.

Hope it helps,

Regards,

Anonymous
Not applicable
Author

Hi Dave,

I am using the similar code and facing an issue -- Call failed with code: 400, "The specified filename is invalid." Did you ever face this problem ? I am exactly using the same code as you have mentioned in python script !

Thanks,

Raghuveer G.

Not applicable
Author

Hi Raghuveer,

I didn't have a problem in Python, can you tell me which file it is trying to/should access? If you can share the code that would be even better.

Kind Regards,

Dave