nabeel-oz / qlik-py-tools

Data Science algorithms for Qlik implemented as a Python Server Side Extension (SSE).
https://nabeel-oz.github.io/qlik-py-tools/
MIT License
186 stars 87 forks source link

Calling python functions in the data load editor #37

Closed sagarkolte closed 5 years ago

sagarkolte commented 5 years ago

Hi Nabeel, I have written a library of functions in Python which I am able to successfully call from Qlik sense. However I wish to achieve the following: Given a list of selections by the user from a drop down menu in the app, I pass this list to my python function and save the output in a variable which I can use repeatedly. Could you please help me with some direction here? Thanks.

nabeel-oz commented 5 years ago

Hi @sagarkolte ,

Is there a reason you can't pass the list of selections with every SSE call? For e.g. store the list of selections in a Qlik variable and use that as one of the parameters for your SSE function calls.

However, what you have asked should be doable:

On the Qlik side you could have a variable that has a SSE function as the expression. This function should take in the list of selections as an argument.

On the Python side you then need an object that retains it's state during multiple SSE calls. One option is to extend the ExtensionService class in __main__.py with a variable to store your list.

If you are building a new class and define your SSE function as a @staticmethod, you will need to store your list in a class variable as any instance of the class will only exist during a single call.

And if you want the list to survive a restart of the SSE you'll need to save it to disk with something like joblib or pickle.

Hope that helps.

sagarkolte commented 5 years ago

Hi Nabeel, Thanks, I have a (perhaps stupid) follow up question regarding the following part of your reply:

“This function should take in the list of selections as an argument.”

Can you please tell me how I store the selection of a drop down list into a variable?

Thanks and Regards

nabeel-oz commented 5 years ago

It depends on what you mean by a drop down list. If you're referring to a standard listbox and want to get selections from a field, there are standard Qlik functions such as GetFieldSelections or Concat. You'll find more details on these at the Qlik Help site.

If you mean that you want a dropdown to control the value of a variable in your app, you would use an input control such as the Variable Input bundled extension.

sagarkolte commented 5 years ago

Thanks Nabeel, I will be trying this when I reach office. By the way, just for clarity’s sake to answer your question:

“Is there a reason you can't pass the list of selections with every SSE call?”

I can’t, as it takes 4 seconds for the function to run and I will end up making more than 400 calls to the function.

Regards

nabeel-oz commented 5 years ago

Hi @sagarkolte , just curious if those are 400 unique SSE calls? Is each call being made with a different set of data or parameters? I ask because if it's just the same call being made by multiple users, Qlik will cache the results and avoid unnecessary computation.

sagarkolte commented 5 years ago

Hi Nabeel, Indeed they are not. Each call is with the same set of parameters. But still it takes very long for the charts to finish rendering. Any idea why this might be? We are not on the latest version on Qliksense though.

Regards

sagarkolte commented 5 years ago

Hi Nabeel, Actually thanks for being so helpful, I would like to take this opportunity to ask you your opinion on the following:

My python function accepts a list of strings and is supposed to return a table with two columns of type float. The intention here is for Qlik to plot a scatter plot using the two columns.

But apparently we cannot return a table to Qlik. So I converted that table into a json string and passed it to Qlik. I then use the Subfield and TextBetween functions to parse the json string and get back the float values.

Is there a better way to do this?

Thanks.

nabeel-oz commented 5 years ago

On your first question of the charts would just be waiting for the SSE response so performance improvements can only be made on the Python side.

You can experiment with a single call and check that it is getting cached in Qlik. Make a set of selections and remove them, then make them again. The chart should render without a SSE call the second time. You can then add more calls and see if anything gets pushed out of the cache.

On your second question, you're right that currently a SSE can't return a table to a chart object (it can in the load script though). Usually this should not be a problem in the frontend as each SSE call is made through a measure or dimension which is a single column rather than a table. But if you need to return a table, the workaround is what you did; concatenate the values in Python in some way and the parse them in Qlik using SubField.

sagarkolte commented 5 years ago

Hi Nabeel, Thanks. My response is in two parts:

  1. I tried making a single call and repeating the set of selections. The output from the function is not being cached. Is there a way to turn caching on?

  2. You say that the SSE can return a table in the load script, how does one do this? Could you please share a sample code which demonstrates this?

Thanks much!

nabeel-oz commented 5 years ago
  1. Caching should be on by default, so you should think of any quirks of your app which might be stopping the expression from getting cached. There is a description of the caching mechanism and some examples at Qlik-OSS here.

  2. The LOAD ... EXTENSION syntax can be used to call a SSE from the load script as described here. Look at the 'Loading from analytic connections' example. For a working example you can refer to the Sample_App_Forecasting_Simple.qvf.

sagarkolte commented 5 years ago

Hi Nabeel, Thanks so much for sharing the sample qvf. We realised that we were using excel sheets without natively importing them and that was causing the delay in getting the results. Somehow it was preventing the cache too. Everything is working fine now. However we would like to overcome this final challenge:

Using GetFieldSelection like function in the load editor. For example in your qvf file you have the vHospital variable. You seem to have saved a static value in this variable. We would like to store the user selection in this variable.

Thanks!

sagarkolte commented 5 years ago

Hi Nabeel, I think this is the right time to close the issue as we have successfully overcome the challenges, thanks to your help. Regards.