Package: qsea
TitleQSEA refers to the Qlik Sense Engine API.DescriptionQSEA is designed to automate basic operations with Qlik Sense Enterprise apps in a Pythonic way. With QSEA, you can quickly view and edit variables, master measures, and dimensions, as well as main sheet objects. For example, you can replace variables in all master measures of your app with just one line of code.formsinApp.measures:ms.update(definition=replace(ms.definition,'$(var1)','$(var2)'))or quickly move all measures from one app to another:formsinApp1.measures:App2.measures.add(name=ms.name,definition=ms.definition)InstallationpipinstallqseaTable of ContentsGetting startedFull GuideApp classApp.load()App.save()App.reload_data()App.childrenAppChildren classAppChildren addVariable classVariable propertiesVariable.update()Variable.delete()Variable.rename()Variable.get_layout()Measure classMeasure propertiesMeasure.update()Measure.delete()Measure.rename()Measure.get_layout()Dimension classDimension propertiesDimension.update()Dimension.delete()Dimension.rename()Dimension.get_layout()Sheet classSheet propertiesSheet.load()Sheet.get_layout()Field classField propertiesObject classObject propertiesObject.export_data()Object.load()Object.get_layout()ObjectChildren classObjectMeasure classObjectMeasure propertiesObjectMeasure.update()ObjectMeasure.delete()ObjectDImension classObjectDimension propertiesObjectDimension.update()ObjectDimension.delete()LicenseGetting startedQSEA uses the Qlik Sense Engine API via the Qlik Sense Proxy Service as its main tool, so you'll need the correct API credentials to start working with QSEA. Please refer to the following links for help.https://help.qlik.com/en-US/sense-developer/May2023/Subsystems/EngineAPI/Content/Sense_EngineAPI/GettingStarted/connecting-to-engine-api.htmhttps://help.qlik.com/en-US/cloud-services/Subsystems/Hub/Content/Sense_Hub/Admin/mc-generate-api-keys.htmYour credentials should look something like thisheader_user={'Authorization':'Bearer <Very long API KEY>'}qlik_url="wss://server.domain.com[/virtual proxy]/app/"Now we can connect to the Qlik Server:conn=qsea.Connection(header_user,qlik_url)Let's create an App object, which represents the application in Qlik Sense.app=qsea.App(conn,'MyAppName')By default the App class object is almost empty. Use theload()function to make use of it:app.load()Now all variables, master measures, and dimensions are uploaded to our App object. We can access them by their name:var=app.variables['MyVar']var.definitionms=app.measures['MyMeasure']ms.label_expressionOr, we can overview their properties via a pandas DataFrame.app.dimensions.dfLet's create a new measure:app.measures.add(name='MyMeasure',definition='sum(Sales)')or update a variable:var.update(definition='sum(Sales)')Save the app to ensure that the changes are reflected in the real Qlik Sense application.app.save()Let's copy the set of master dimensions into a new app:source_app=qsea.App(conn,'Source AppName')target_app=qsea.App(conn,'Target AppName')source_app.load()target_app.load()fordiminsource_app.dimensions:ifdim.namenotin[target_dim.namefortarget_dimintarget_app.dimensions]:target_app.dimensions.add(name=dim.name,definition=dim.definition)target_app.save()For unknown reasons, on certain instances of Qlik Sense, changes in the App may not be visible in the Qlik Sense interface. The usual workaround is to make a new copy of the Application (via QMC or Hub). Usually, all changes can be seen in the copy.Note that as it stands, only basic properties, such as names, definitions, and a couple of others, can be accessed via the qsea module.Most read-only operations (such as loading apps) can be performed on published apps. However, it is recommended to modify objects only in unpublished apps.Besides master measures, master dimensions, and variables, tables and charts in the App can also be uploaded.It's highly recommended to make a backup copy of your application.app.load()sh=app.sheets['MySheet']sh.load()forobjinsh.objects:formsonobj.measures:print(ms.definition)Good luck!Full GuideConnection classThe class that represents a dictionary of websocket connections to Qlik Sense Engine API
Since one websocket connection can be used only for one app, this class is used to handle all websocket connections
New websocket connections are created automatically when a new app object is createdNote that the Qlik Sense Engine API has a limit of active parallel connections. Since there is no way to terminate the existing connection (except restarting the proxy server that is generally unacceptable), one have to wait for the Qlik Sense Engine to terminate some of the old sessions.
There is no way to reconnect to an existing connection if the Connection class object is recreated. Thus, it is highly recommended to avoid recreating the Connection class object in order to avoid reaching the limit of active connections.App classThe class, representing the Qlik Sense application. This is the main object to work with. The class is empty when created; run theload()function to make use of it.App.load()Loads data from the Qlik Sense application into an App object.Args:depth (int): depth of loading1 - app + variables, measures, sheets, fields, dimensions (default value)2 - everything from 1 + sheet objects (tables, sharts etc.)3 - everything from 2 + object dimensions and measuresDifferent levels can be useful when working with large apps, as a full load can be time-consuming. Only dimensions and measures from standard Qlik Sense charts are uploaded. Uploading dimensions from filter panes is currently not supported.App.load(level=3)App.save()You have to save the App object for the changes to be reflected in the Qlik Sense Application. Note that it is recommended to modify objects only in unpublished apps.App.save()App.reload_data()Starts the script of reloading data into the Qlik Sense Application.App.reload_data()App.childrenapp.load(level = 1) creates several objects of AppChildren classAppChildren classThe class contains collections of master objects in the Qlik Sense Application:app.variables: a collection of Variable class objects, representing the variables of the Qlik Sense applicationapp.measures: a collection of Measure class objects, representing the master measures of the Qlik Sense applicationapp.dimensions: a collection of Dimension class objects, representing the master dimensions of the Qlik Sense applicationapp.sheets: a collection of Sheet class objects, representing the sheets of the Qlik Sense applicationapp.fields: a collection of Field class objects, representing the fields of the Qlik Sense applicationYou can access the main information about each group of objects in a pandas DataFrame via the.dfattribute:app.variables.dfAppChildren.add()Use theadd()function to add new variables, master measures or master dimensions to the app.Args:name (str): Name of the object to be created.definition (str): Definition of the object to be created.description (str, optional): Description of the object to be created. Defaults to ''.label (str, optional): Label of the object to be created. Defaults to ''.label_expression (str, optional): Label expression of the object to be created. Defaults to ''.format_type (str, optional): Format type of the object to be created. Defaults to 'U'.'U' for auto'F' for number'M' for money'D' for date'IV' for duration'R' for otherformat_ndec (int, optional): Number of decimals of the object to be created. Defaults to 10.format_use_thou (int, optional): Use thousands separator for the object to be created. Defaults to 0.format_dec (str, optional): Decimal separator for the object to be created. Defaults to ','.format_thou (str, optional): Thousands separator for the object to be created. Defaults to ''.Returns: True if the object was created successfully, False otherwise.
Only parameters applicable to the specific class will be usedApp.variables.add(name='MyVar',definition='sum(Sales)')App.measures.add(name='MyFunc',definition='sum(Sales)',format_type='F')App.dimensions.add(name='MyDim',definition='Customer')Variable classThe class represents variables of the application and is a member of the App.variables collection. You can access a specific variable by its name or iterate through them:var=app.variables['MyVar']print(var.definition)forvarinapp.variables:ifvar.definition=='sum(Sales)':var.update(name='varSales')Variable propertiesname: this is the name of the variable you generally use in the Qlik Sense interfacedefinition: the formula behind the variabledescription: the description of the variableauxiliaryhandle: the internal handle of the object in the Qlik Sense Engine API; can be  used to access the variable via thequery()functionapp_handle: the handle of the parent App objectid: Qlik Sense internal id of the variableparent: App-children object; you can access the App class object like thisvar.parent.parentcreated_date: creation date of the variable, as stored in Qlik Sensemodified_date: date of the last modification of the variable, as stored in Qlik Sensescript_created: True if the variable is created via the application load script, False if not.Variable.update()Updates the variable on the Qlik Sense ServerArgs:definition (str, optional): new definition of the variable (leaveNoneto keep the old value)description (str, optional): new description of the variable (leaveNoneto keep the old value)Returns:
True if the variable was updated successfully, False otherwisevar=app.variables['MyVar']var.update(definition='sum(Sales)')app.save()Variable.delete()Deletes the variable from the Qlik Sense ServerReturns:
True if the variable was deleted successfully, False otherwisevar=app.variables['MyVar']var.delete()app.save()Variable.rename()Renames the variable on the Qlik Sense Server. Since there is no direct method to rename the variable, it essentially  deletes the variable with the old name, and creates a new one, with the new name.Returns:
True if the variable is renamed successfully, False otherwisevar=app.variables['MyVar']var.rename('MyVarNewName')app.save()Variable.get_layout()Returns the json layout of the variable; a shortcut to the GetLayout method of the Engine APIvar.get_layout()Measure classThe class represents master measures of the application and is a member of the App.measures collection. You can access a specific measure by its name or iterate through them.ms=app.measures['MyMeasure']print(ms.definition)formsinapp.measures:ifms.definition=='sum(Sales)':ms.update(name='Sales')Measure propertiesname: the name of the measure you generally use in the Qlik Sense interfacedefinition: the formula behind the measuredescription: the description of the measurelabel: the label of the measure, as it appears in chartslabel_expression: the label expression of the measureformat_type: Format type of the object'U' for auto'F' for number'M' for money'D' for date'IV' for duration'R' for otherformat_ndec: Number of decimals for the objectformat_use_thou: Use thousands separator for the objectformat_dec: Decimal separator for the objectformat_thou: Thousands separator for the objectauxiliaryhandle: the internal handle of the object in the Qlik Sense Engine API; can be used to access the measure via thequery()functionapp_handle: the handle of the parent App objectid: Qlik Sense internal id of the measureparent: AppChildren object; you can access the App class object like thisms.parent.parentcreated_date: creation date of the measure, as stored in Qlik Sensemodified_date: date of the last modification of the measure, as stored in Qlik SenseMeasure.update()Updates the measure on the Qlik Sense ServerArgs:definition (str, optional): The definition of the measuredescription (str, optional): the description of the measurelabel (str, optional): the label of the measure, as it appears in chartslabel_expression (str, optional): the label expression of the measureformat_type (str, optional): Format type of the object to be created. Defaults to 'U'.'U' for auto'F' for number'M' for money'D' for date'IV' for duration'R' for otherformat_ndec (int, optional): Number of decimals for the object to be created. Defaults to 10.format_use_thou (int, optional): Use thousands separator for the object to be created. Defaults to 0.format_dec (str, optional): Decimal separator for the object to be created. Defaults to ','.format_thou (str, optional): Thousands separator for the object to be created. Defaults to ''.Returns:
True if the measure was updated successfully, False otherwisems=app.measures['MyMeasure']ms.update(definition='sum(Sales)',label='Total Sales',format_type='F')app.save()Measure.delete()Deletes the measure from the Qlik Sense ServerReturns:
True if the measure was deleted successfully, False otherwisems=app.measures['MyMeasure']ms.delete()app.save()Measure.rename()Renames the measure on the Qlik Sense Server.Returns:
True if the measure was renamed successfully, False otherwisems=app.measures['MyMeasure']ms.rename('MyMeasureNewName')app.save()Measure.get_layout()Returns the json layout of the measure; a shortcut to the GetLayout method of the Engine APIms.get_layout()Dimension classThe class represents master dimensions of the application and is a member of the App.dimensions collection. You can access a specific dimension by its name or iterate through them. Note that hierarchical dimensions are not yet supported."dim=app.dimensions['MyDimension']print(dim.definition)fordiminapp.dimensions:ifdim.definition=='[Customer]':dim.update(name='Customer_dimension')Dimension propertiesname: the name of the dimension you generally use in the Qlik Sense interfacedefinition: the formula behind the dimensionlabel: the label of the dimension, as it appears in chartsauxiliaryhandle: the internal handle of the object in the Qlik Sense Engine API; can be used to access the dimension via thequery()functionapp_handle: the handle of the parent App objectid: Qlik Sense internal id of the dimensionparent: AppChildren object; you can access the App class object like thisdim.parent.parentcreated_date: creation date of the dimension, as stored in Qlik Sensemodified_date: date of the last modification of the dimension, as stored in Qlik SenseDimension.update()Updates the dimension on the Qlik Sense ServerArgs:definition (str, optional): The definition of the dimensionlabel (str, optional): the label of the dimension, as it appears in chartsReturns:
True if the dimension was updated successfully, False otherwisedim=app.dimensions['MyDimension']dim.update(definition='Customer',label='Customer_dimension')app.save()Dimension.delete()Deletes the dimension from the Qlik Sense ServerReturns:
True if the dimension was deleted successfully, False otherwisedim=app.dimensions['MyDimension']dim.delete()app.save()Dimension.rename()Renames the dimension on the Qlik Sense Server.Returns:
True if the dimension was renamed succesfully, False otherwisedim=app.dimensions['MyDimension']dim.rename('MyDimensionNewName')app.save()Dimension.get_layout()Returns the json layout of the dimension; a shortcut to the GetLayout method of the Engine APIdim.get_layout()Sheet classThe class represents the sheets of the application and is a member of the App.sheets collection. You can access objects on the sheets, such as charts and tables, via the Sheet class object.forshinapp.sheets:print(sh.name)Sheet propertiesname: that's the name of the sheetdescription: the description of the sheetauxiliaryhandle: the internal handle of the object in Qlik Sense Engine API; can be used to access the sheet via thequery()functionapp_handle: the handle of the parent App objectid: Qlik Sense internal id of the sheetparent: AppChildren object; you can access the App class object like thisms.parent.parentcreated_date: creation date of the sheet, as stored in Qlik Sensemodified_date: date of the last modification of the sheet, as stored in Qlik Sensepublished: True if the sheet is published, False if notapproved: True if the sheet is approved, False if notowner_id: GUID of the owner of the sheetowner_name: name of the owner of the sheetSheet.load()Loads objects from the sheet in a Qlik Sense application into a Sheet class objectsh=App.sheets['MySheet']sh.load()forobjinsh.objects:print(obj.type)Sheet.get_layout()Returns the json layout of the sheet; a shortcut to the GetLayout method of the Engine APIsh.get_layout()Field classThe class represents the fields of the application and is a member of the App.fields collection. You can only use the class for information purposes; no changes can be made with fields via QSEA."forfldinapp.fields:print(field.table_name,field.name)Field propertiesname: name of the field, as it appears in the modeltable_name: name of the table, containing the fieldinformation_density, non_nulls, rows_count, subset_ratio, distinct_values_count, present_distinct_values, key_type, tags: properties of the fields as they can be found in the data modelauxiliaryhandle: internal handle of the field objectapp_handle: handle of the parent App objectObject classThe class represents the objects on the sheet, such as charts and tables, and is a member of the SheetChildren collection.Object propertiestype: type of the object, such as 'piechart' or 'pivot-table'col, row, colspan, rowspan, bounds_y, bounds_x, bounds_width, bounds_height: parameters referring to the location of an object on the sheetauxiliaryhandle: the internal handle of the object in the Qlik Sense Engine API; can be used to access the object via thequery()functionsheet_handle: handle of the parent sheetsheet: the Sheet object, on which the object itself is locatedid: Qlik Sense internal id of the objectparent: SheetChildren objectObject.export_data()Performs data export of an object (such as a table or chart) to an xslx or csv file.Args:file_type (str, optional): 'xlsx' or 'csv', 'xlsx' by defaultReturns: the path to the downloaded file in case of success, None if failedObject.load()Loads measures and dimensions of the object in a Qlik Sense application into an Object class instance.sh=App.sheets['MySheet']sh.load()forobjinsh.objects:ifobj.type=='piechart':obj.load()print(obj.dimensions.count)Object.get_layout()Returns the json layout of the object; a shortcut to the GetLayout method of the Engine APIobj.get_layout()ObjectChildren classThe class contains collections of measures and dimensions in the object on the sheet:object.measures: a collection of ObjectMeasure class objects, representing the measures in the object on the sheetobject.dimensions: a collection of ObjectDimension class objects, representing the dimensions in the object on the sheetYou can access the main information in pandas DataFrame via.df:App.sheets['MySheet'].objects['object_id'].measures.dfAdding measures and dimensions to app objects is not supported yet.ObjectMeasure classThis class represents measures of the object on the sheet and is a member of the object.measures collection. Since there may be no specific name for the measure in the object, the internal Qlik ID is used instead of the name. Thus, you can either iterate through measures or call them by the internal Qlik ID:ms=obj.measures['measure_id']print(ms.definition)formsinobj.measures:ifms.definition=='sum(Sales)':ms.update(definition='sum(Incomes)')ObjectMeasure propertiesname: internal Qlik id of the measuredefinition: the formula behind the measurelabel: the label of the measure, as it appears in the chartslabel_expression: the label expression of the measurecalc_condition: calculation condition for the measurelibrary_id: if a master measure is used, this refers to its IDformat_type: Format type of the object'U' for auto'F' for number'M' for money'D' for date'IV' for duration'R' for otherformat_ndec: Number of decimals of the objectformat_use_thou: Use thousands separator for the objectformat_dec: Decimal separator for the objectformat_thou: Thousands separator for the objectauxiliaryapp_handle: the handle of the parent App objectparent: ObjectChildren objectobject: you can access the Object class object like thisms.objectObjectMeasure.update()Updates the measure in the object on the sheet.Args:definition (str, optional): The definition of the measurelabel (str, optional): the new label of the measure, as it appears in chartslabel_expression (str, optional): the label expression of the measurecalc_condition (str, optional): calculation condition for the measurelibrary_id (str, optional): id of the master measureformat_type (str, optional): Format type of the object. Defaults to 'U'.'U' for auto'F' for number'M' for money'D' for date'IV' for duration'R' for otherformat_use_thou (int, optional): Use thousands separator for the object. Defaults to 0.format_dec (str, optional): Decimal separator for the object. Defaults to ','.format_thou (str, optional): Thousands separator for the object. Defaults to ''.Returns:
True if the measure was updated successfully, False otherwisems=obj.measures['measure_id']ms.update(definition='sum(Sales)',label='Total Sales',format_type='F')app.save()ObjectMeasure.delete()Deletes the measure from the object on the sheetReturns:
True if the measure was deleted successfully, False otherwisems=obj.measures['measure_id']ms.delete()app.save()ObjectDimension classThis class represents dimensions of the object on the sheet and is a member of the object.dimensions collection. Since there may be no specific name for the dimension in the object, the internal Qlik ID is used instead of the name. Thus, you can either iterate through dimensions or call them by the internal Qlik ID:dim=obj.measures['dimension_id']print(dim.definition)fordiminobj.dimensions:ifdim.definition=='[Customer]':dim.update(definition='[Supplier]')Note that hierarchical dimensions are not supported yet.ObjectDimension propertiesname: internal Qlik id of the dimensiondefinition: the formula behind the dimensionlabel: the label of the dimension, as it appears in the chartsauxiliaryapp_handle: the handle of the parent App objectparent: ObjectChildren objectobject: you can access the Object class object like thisdim.objectObjectDimension.update()Updates the dimension in the object on the sheetArgs:definition (str, optional): the definition of the dimensionlabel (str, optional): the label of the dimension, as it appears in chartscalc_condition (str, optional): calculation condition for the dimensionReturns:
True if the dimension was updated successfully, False otherwisedim=obj.dimensions['dimension_id']dim.update(definition='Customer',label='Customer_dimension')app.save()ObjectDimension.delete()Deletes the dimension from the Qlik Sense ServerReturns:
True if the dimension was deleted successfully, False otherwisedim=app.dimensions['dimension_id']dim.delete()app.save()LicenseThis project is licensed under the MIT License - see theLICENSEfile for details.History[0.0.17] - 2024-01-31Fixed some problems that occured if the connection class object was recreated before terminating the connection to Qlik Sense Engine API[0.0.16] - 2023-10-03Minor changes[0.0.15] - 2023-10-03Minor changes[0.0.14] - 2023-10-01Addedobject.export_data() function which performs data export of an object (such as a table or chart) to an xslx or csv fileget_layout() function for measures, dimensions, variables, sheets and objects; the functions return the json layout