Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
Hi Qlik Community,
I am wondering if anyone knows how to successfully import an app (.qvf) file from one's local system, to a Cloud tenant, through the Qlik API's?
I have tried several different approaches, none of them seeming to work. I have then tried to reverse engineer the approach that Qlik themselves use through the GUI. From what I can see, these are the steps:
1) POST request to API end-point "api/v1/temp-contents/files", in order to create an upload resource. Response should return a location with a file id for resource.
2) PATCH request to API end-point "api/v1/temp-contents/files/{fileId}" to upload bytes of file to created resource.
3) POST request to API end-point "api/v1/apps/import", with request body containing fileId, spaceId etc.
However, this approach does not work as intended, as no response is returned from step 1.
Therefore, I was wondering if someone knows the "correct" way to do it? 🙂
Kind regards
PythonMCSJ
Here's an example using the library QlikSenseRestClient https://www.nuget.org/packages/QlikSenseRestClient/
var url = "<tenant url>";
var apiKey = "<api key>";
var appPath = @"C:\path\to\app.qvf";
var client = new RestClient(url);
client.AsApiKeyViaQcs(apiKey);
var appFile = File.ReadAllBytes(appPath);
var rsp = client.Post<JToken>("/api/v1/apps/import", appFile);
Console.WriteLine(rsp);
Hi @PythonMCSJ
To import an app, you just have to do only step 3 and send the file in the POST request - you don't need to use temp-contents. It might not totally match the context of your set up, but we have a tutorial here (see section 2) which shows how to upload an app to a shared space and a standard response.
Here's the command to take it from your local system and post it into the space. You can also remove the spaceId parameter to drop it into your personal space:
curl -L -X POST "https://<TARGET_TENANT>/api/v1/apps/import?spaceId=<SHARED_SPACE_ID>" \
--header "Content-Type: application/octet-stream" \
--header "Authorization: Bearer <TARGET_ACCESS_TOKEN>" \
--data-binary "@<APP_NAME>.qvf"
If you do want to deploy to a space then your user will need the appropriate access rights to that space.
Hi Dave,
Thanks for your reply! This is essentially the approach I have tried to implement, however I am trying to do it in C#. I am having trouble with "converting" the curl statement you posted to an equivalent using an HttpClient in C# - can you help me with that?
Kind regards,
PythonMCSJ
HI PythonMCSJ,
Here is the same http request as node.js
const https = require('https')
const options = {
hostname: 'https://your-tenant.us.qlikcloud.com',
port: 443,
path: '/api/v1/apps/import',
method: 'POST',
headers: {
'Content-Type': 'application/octet-stream',
'Authorization': 'Bearer <API-key>'
}
}
const req = https.request(options)
req.write(streamData)
The details of the APIs can be found here Apps | Qlik Developer Portal
I'm afraid C# is not a familiar area...all I can offer is a generated snippet using RestClient
var client = new RestClient("https://{{target_tenant}}.<qcs-region>.qlikcloud.com/api/v1/apps/import?spaceId={{shared_space_id}}");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Accept", "application/json");
request.AddHeader("Content-Type", "application/octet-stream");
request.AddHeader("Authorization", "Bearer {{target_access_token}}");
request.AddParameter("application/octet-stream", "<file contents here>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
Here's an example using the library QlikSenseRestClient https://www.nuget.org/packages/QlikSenseRestClient/
var url = "<tenant url>";
var apiKey = "<api key>";
var appPath = @"C:\path\to\app.qvf";
var client = new RestClient(url);
client.AsApiKeyViaQcs(apiKey);
var appFile = File.ReadAllBytes(appPath);
var rsp = client.Post<JToken>("/api/v1/apps/import", appFile);
Console.WriteLine(rsp);
Hi all,
Thank you very much for the guidance! I managed to make it work with an HttpClient - turns out that my errors were a result of manually setting the content-type of the POST request to "application/octet-stream". Removing this, and simply uploading the appFile as in the example of @Øystein_Kolsrud, it now works as intended!
Again, thank you very much!
Kind regards,
PythonMCSJ