Skip to main content
Announcements
SYSTEM MAINTENANCE: Thurs., Sept. 19, 1 AM ET, Platform will be unavailable for approx. 60 minutes.
cancel
Showing results for 
Search instead for 
Did you mean: 
kcrouse
Contributor II
Contributor II

Using Engine API to create new app for a specific user

Hi all,

Sorry if this is clearly explained somewhere - I can't find it, but it seems so straightforward.

I'm automating some of our work by building a Python library that interacts with the Qlik Sense Engine JSON API, using certificates that authenticate as an administrator.

Basically, what I am looking to do is create a new app (no problem), set an autogenerated load script (no problem), and assign it to a user determined on the fly [problem].

I don't see a parameter to set the owner/user of the app or to move it to a user's workspace.  It's not supposed to be published at this point and just be in their work stream.  How can I accomplish this?  I've searched through the JSON Engine API docs, but there is very little about users.

 

 

Labels (3)
1 Solution

Accepted Solutions
kcrouse
Contributor II
Contributor II
Author

Hi everyone, I have now had a chance to explore the QRS in depth and have found two ways to accomplish this.  For those who may come upon this thread in the future, these features should be able to be extrapolated to (a) other objects that aren't Apps and (b) other fields besides owner as well.

Set up:

In both options below, I am assuming you have fetched the App JSON through one of various methods, such as GET to /qrs/app/{id}  or GET to /qrs/app/full with various parameters.  

Option 1: Create A Selection and Modify Just the Field you are Interested in 

First option 1, you will need at least the hexidecimal app id  and the modifiedDate from the App JSON. The Modified Date is critical - if it's not the exact same date as the app, this will fail. This prevents a race condition in which a field is updated by one user between when another one gets the app's info and attempts to update it.

Step 1: Create a new "selection" entity via a POST 

POST to /qrs/selection with data along the following lines : 

{
  "items":[ {
       "type": "App",
       "objectID": "{hex_app_id}",
  }],
}

 

That will return a new selection json object, and you will want the *id* value from that , which below is {selection_id}

Step 2: Send the update

PUT to /qrs/selection/{selection_id}/app/synthetic  with data along the lines of :

{
  "properties": [{
      "name": "owner",
      "value": {new_owner_hex_id},
      "valueIsModified": True
  }],
  "type": "App",
  "LatestModifiedDate": {app_modified_date_and_time},
}

 

Step 3: Delete the Selection

DELETE to /qrs/selection/{selection_id}

 

Option 2: Do a direct update of the object itself

This method grabs the app's full json and performs a REST update via a PUT call. It's simpler in that you don't have to deal with selections, but it can be a bit less obvious what's going on if you are inspecting the data.

Step 1: Create the json object with your updates.

The json object MUST INCLUDE the last modifiedDate and modifiedByUserName  . So, if you had gotten the app data by calling /qrs/app/{hex_app_id}, it will be those returned fields.

Aside from those, you can add any fields you want to update and replace. There's clearly a hierarchy of fields. I have tested it with only adding in the owner "id" and putting in an incorrect "name", and everything was set based on the ID.

Alternatively, it's fine to leave in fields that aren't changed, as well. If you are lazy, you can get the full app json, just modify the desired fields in place, and submit the entire json entity back in the put statement.

Here's an example of a json payload that only modifies the owner information:

{
    'modifiedByUserName': {last_modified_by_user_name}, 
    'modifiedDate': {last_modified_date}, 
    'owner': {
         'id': {user_hex_id} 
         'userDirectory': {user_directory}, 
    }
}

 

Step 2: PUT to /qrs/app/{hex_app_id}  with data set to your json payload.

 

 

View solution in original post

3 Replies
Øystein_Kolsrud
Employee
Employee

It is the repository that is responsible for this type activity, and the engine API is quite limited with regards to what functionality it exposes in this domain. A rule of thumb is that the engine is responsible for app contents, while the repository is responsible for app management. You can read more about the repository API here:

https://help.qlik.com/en-US/sense-developer/November2019/Subsystems/RepositoryServiceAPI/Content/Sen...

with the reference here:

https://help.qlik.com/en-US/sense-developer/November2019/APIs/RepositoryServiceAPI/index.html

To set owner of an app you would probably use this endpoint:

https://help.qlik.com/en-US/sense-developer/November2019/APIs/RepositoryServiceAPI/index.html?page=6...

kcrouse
Contributor II
Contributor II
Author

Aha!  Thanks so much, Yko!  

I'll be planning to explore that this week!

kcrouse
Contributor II
Contributor II
Author

Hi everyone, I have now had a chance to explore the QRS in depth and have found two ways to accomplish this.  For those who may come upon this thread in the future, these features should be able to be extrapolated to (a) other objects that aren't Apps and (b) other fields besides owner as well.

Set up:

In both options below, I am assuming you have fetched the App JSON through one of various methods, such as GET to /qrs/app/{id}  or GET to /qrs/app/full with various parameters.  

Option 1: Create A Selection and Modify Just the Field you are Interested in 

First option 1, you will need at least the hexidecimal app id  and the modifiedDate from the App JSON. The Modified Date is critical - if it's not the exact same date as the app, this will fail. This prevents a race condition in which a field is updated by one user between when another one gets the app's info and attempts to update it.

Step 1: Create a new "selection" entity via a POST 

POST to /qrs/selection with data along the following lines : 

{
  "items":[ {
       "type": "App",
       "objectID": "{hex_app_id}",
  }],
}

 

That will return a new selection json object, and you will want the *id* value from that , which below is {selection_id}

Step 2: Send the update

PUT to /qrs/selection/{selection_id}/app/synthetic  with data along the lines of :

{
  "properties": [{
      "name": "owner",
      "value": {new_owner_hex_id},
      "valueIsModified": True
  }],
  "type": "App",
  "LatestModifiedDate": {app_modified_date_and_time},
}

 

Step 3: Delete the Selection

DELETE to /qrs/selection/{selection_id}

 

Option 2: Do a direct update of the object itself

This method grabs the app's full json and performs a REST update via a PUT call. It's simpler in that you don't have to deal with selections, but it can be a bit less obvious what's going on if you are inspecting the data.

Step 1: Create the json object with your updates.

The json object MUST INCLUDE the last modifiedDate and modifiedByUserName  . So, if you had gotten the app data by calling /qrs/app/{hex_app_id}, it will be those returned fields.

Aside from those, you can add any fields you want to update and replace. There's clearly a hierarchy of fields. I have tested it with only adding in the owner "id" and putting in an incorrect "name", and everything was set based on the ID.

Alternatively, it's fine to leave in fields that aren't changed, as well. If you are lazy, you can get the full app json, just modify the desired fields in place, and submit the entire json entity back in the put statement.

Here's an example of a json payload that only modifies the owner information:

{
    'modifiedByUserName': {last_modified_by_user_name}, 
    'modifiedDate': {last_modified_date}, 
    'owner': {
         'id': {user_hex_id} 
         'userDirectory': {user_directory}, 
    }
}

 

Step 2: PUT to /qrs/app/{hex_app_id}  with data set to your json payload.