qe-api-client 2.7.0__py3-none-any.whl → 2.9.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qe_api_client/api_classes/engine_app_api.py +107 -47
- qe_api_client/api_classes/engine_generic_object_api.py +63 -6
- qe_api_client/engine.py +301 -22
- qe_api_client/structs.py +128 -3
- {qe_api_client-2.7.0.dist-info → qe_api_client-2.9.0.dist-info}/METADATA +4 -2
- {qe_api_client-2.7.0.dist-info → qe_api_client-2.9.0.dist-info}/RECORD +9 -9
- {qe_api_client-2.7.0.dist-info → qe_api_client-2.9.0.dist-info}/WHEEL +1 -1
- {qe_api_client-2.7.0.dist-info → qe_api_client-2.9.0.dist-info}/licenses/LICENSE +0 -0
- {qe_api_client-2.7.0.dist-info → qe_api_client-2.9.0.dist-info}/top_level.txt +0 -0
@@ -26,7 +26,7 @@ class EngineAppApi:
|
|
26
26
|
"""
|
27
27
|
self.engine_socket = socket
|
28
28
|
|
29
|
-
def get_script(self, doc_handle):
|
29
|
+
def get_script(self, doc_handle: int):
|
30
30
|
"""
|
31
31
|
Retrieves the script of the app identified by the document handle.
|
32
32
|
|
@@ -43,7 +43,7 @@ class EngineAppApi:
|
|
43
43
|
except KeyError:
|
44
44
|
return response['error']
|
45
45
|
|
46
|
-
def set_script(self, doc_handle, script):
|
46
|
+
def set_script(self, doc_handle: int, script):
|
47
47
|
"""
|
48
48
|
Sets the script of the app identified by the document handle.
|
49
49
|
|
@@ -61,7 +61,7 @@ class EngineAppApi:
|
|
61
61
|
except KeyError:
|
62
62
|
return response['error']
|
63
63
|
|
64
|
-
def do_reload(self, doc_handle, param_list=[]):
|
64
|
+
def do_reload(self, doc_handle: int, param_list=[]):
|
65
65
|
"""
|
66
66
|
Triggers a reload of the app identified by the document handle.
|
67
67
|
|
@@ -79,7 +79,7 @@ class EngineAppApi:
|
|
79
79
|
except KeyError:
|
80
80
|
return response['error']
|
81
81
|
|
82
|
-
def do_reload_ex(self, doc_handle, param_list={}):
|
82
|
+
def do_reload_ex(self, doc_handle: int, param_list={}):
|
83
83
|
"""
|
84
84
|
Triggers an extended reload of the app identified by the document handle.
|
85
85
|
|
@@ -98,7 +98,7 @@ class EngineAppApi:
|
|
98
98
|
except KeyError:
|
99
99
|
return response['error']
|
100
100
|
|
101
|
-
def get_app_layout(self, doc_handle):
|
101
|
+
def get_app_layout(self, doc_handle: int):
|
102
102
|
"""
|
103
103
|
Retrieves the layout structure of the app identified by the document handle.
|
104
104
|
|
@@ -115,7 +115,7 @@ class EngineAppApi:
|
|
115
115
|
except KeyError:
|
116
116
|
return response['error']
|
117
117
|
|
118
|
-
def get_object(self, app_handle, object_id):
|
118
|
+
def get_object(self, app_handle: int, object_id: str):
|
119
119
|
"""
|
120
120
|
Retrieves a specific object from the app identified by the document handle.
|
121
121
|
|
@@ -134,7 +134,7 @@ class EngineAppApi:
|
|
134
134
|
except KeyError:
|
135
135
|
return response['error']
|
136
136
|
|
137
|
-
def get_field(self, doc_handle, field_name, state_name=""):
|
137
|
+
def get_field(self, doc_handle: int, field_name, state_name=""):
|
138
138
|
"""
|
139
139
|
Retrieves a specific field from the app identified by the document handle.
|
140
140
|
|
@@ -154,7 +154,7 @@ class EngineAppApi:
|
|
154
154
|
except KeyError:
|
155
155
|
return response['error']
|
156
156
|
|
157
|
-
def create_object(self, doc_handle, prop):
|
157
|
+
def create_object(self, doc_handle: int, prop):
|
158
158
|
"""
|
159
159
|
Creates a new object in the app identified by the document handle.
|
160
160
|
|
@@ -177,7 +177,7 @@ class EngineAppApi:
|
|
177
177
|
# You can create multiple states within a Qlik Sense app and apply these states to specific objects within the app. # NOQA
|
178
178
|
# Objects in a given state are not affected by user selections in the other states. # NOQA
|
179
179
|
# Call GetAppLayout() afterwards to get the latest states
|
180
|
-
def add_alternate_state(self, doc_handle, state_name):
|
180
|
+
def add_alternate_state(self, doc_handle: int, state_name):
|
181
181
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "AddAlternateState",
|
182
182
|
"params": [state_name]})
|
183
183
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -188,7 +188,7 @@ class EngineAppApi:
|
|
188
188
|
|
189
189
|
# AddFieldFromExpression method: Adds a field on the fly. !! The expression of a field on the fly is persisted but # NOQA
|
190
190
|
# not its values. !!
|
191
|
-
def add_field_from_expression(self, doc_handle, field_name, expr_value):
|
191
|
+
def add_field_from_expression(self, doc_handle: int, field_name, expr_value):
|
192
192
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "AddFieldFromExpression",
|
193
193
|
"params": [field_name, expr_value]})
|
194
194
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -199,7 +199,7 @@ class EngineAppApi:
|
|
199
199
|
|
200
200
|
# CheckExpression method: Checks whether an expression is valid or not
|
201
201
|
# qErrorMsg is empty if it's valid
|
202
|
-
def check_expression(self, doc_handle, expr_value):
|
202
|
+
def check_expression(self, doc_handle: int, expr_value):
|
203
203
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "CheckExpression",
|
204
204
|
"params": [expr_value]})
|
205
205
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -211,7 +211,7 @@ class EngineAppApi:
|
|
211
211
|
# CheckScriptSyntax method: Checks whether a load script is valid or not
|
212
212
|
# Used AFTER doing SetScript method
|
213
213
|
# errors are displayed in an array discussing positions of characters in script where failing # NOQA
|
214
|
-
def check_script(self, doc_handle):
|
214
|
+
def check_script(self, doc_handle: int):
|
215
215
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "CheckScriptSyntax", "params": {}})
|
216
216
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
217
217
|
try:
|
@@ -219,7 +219,7 @@ class EngineAppApi:
|
|
219
219
|
except KeyError:
|
220
220
|
return response['error']
|
221
221
|
|
222
|
-
def clear_all(self, doc_handle, locked_also=False, alt_state=""):
|
222
|
+
def clear_all(self, doc_handle: int, locked_also=False, alt_state=""):
|
223
223
|
"""
|
224
224
|
Clear selections in fields for current state. Locked fields are not cleared by default.
|
225
225
|
|
@@ -239,7 +239,7 @@ class EngineAppApi:
|
|
239
239
|
# CreateConnection method: Creates a connection. A connection indicates from which data source, the data should # NOQA
|
240
240
|
# be taken. The connection can be: an ODBC connection, OLEDB connection, a custom connection, a folder connection # NOQA
|
241
241
|
# (lib connection), an internet connection, Single Sign-On
|
242
|
-
def create_connection(self, doc_handle, connect_name, connect_string, connect_type, user_name, password,
|
242
|
+
def create_connection(self, doc_handle: int, connect_name, connect_string, connect_type, user_name, password,
|
243
243
|
mod_date="", meta="", sso_passthrough="LOG_ON_SERVICE_USER"):
|
244
244
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "CreateConnection",
|
245
245
|
"params": [{"qName": connect_name, "qMeta": meta, "qConnectionString": connect_string,
|
@@ -255,7 +255,7 @@ class EngineAppApi:
|
|
255
255
|
# can contain the same dimension.
|
256
256
|
# Parameters:
|
257
257
|
# qProp (MANDATORY: send dim_id, dim_title, dim_grouping, dim_field, dim_label, meta_def (optional) # NOQA
|
258
|
-
def create_dimension(self, doc_handle, prop):
|
258
|
+
def create_dimension(self, doc_handle: int, prop):
|
259
259
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "CreateDimension",
|
260
260
|
"params": {"qProp": prop}})
|
261
261
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -265,7 +265,7 @@ class EngineAppApi:
|
|
265
265
|
return response['error']
|
266
266
|
|
267
267
|
# DestroyDimension method: Removes a dimension
|
268
|
-
def destroy_dimension(self, doc_handle, dim_id):
|
268
|
+
def destroy_dimension(self, doc_handle: int, dim_id):
|
269
269
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "DestroyDimension",
|
270
270
|
"params": {"qId": dim_id}})
|
271
271
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -275,7 +275,7 @@ class EngineAppApi:
|
|
275
275
|
return response["error"]
|
276
276
|
|
277
277
|
# DestroyMeasure method: Removes a measure
|
278
|
-
def destroy_measure(self, doc_handle, measure_id):
|
278
|
+
def destroy_measure(self, doc_handle: int, measure_id):
|
279
279
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "DestroyDimension",
|
280
280
|
"params": [{measure_id}]})
|
281
281
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -285,7 +285,7 @@ class EngineAppApi:
|
|
285
285
|
return response['error']
|
286
286
|
|
287
287
|
# DestroyObject method: Removes an app object. The children of the object (if any) are removed as well. # NOQA
|
288
|
-
def destroy_object(self, doc_handle, object_id):
|
288
|
+
def destroy_object(self, doc_handle: int, object_id):
|
289
289
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "DestroyObject",
|
290
290
|
"params": [{object_id}]})
|
291
291
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -295,7 +295,7 @@ class EngineAppApi:
|
|
295
295
|
return response['error']
|
296
296
|
|
297
297
|
# DestroySessionObject method: Removes a session object. The children of the object (if any) are removed as well. # NOQA
|
298
|
-
def destroy_session_object(self, doc_handle, object_id):
|
298
|
+
def destroy_session_object(self, doc_handle: int, object_id):
|
299
299
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "DestroySessionObject",
|
300
300
|
"params": [{object_id}]})
|
301
301
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -305,7 +305,7 @@ class EngineAppApi:
|
|
305
305
|
return response['error']
|
306
306
|
|
307
307
|
# DestroySessionVariable method: Removes an transient variable.
|
308
|
-
def destroy_session_variable(self, doc_handle, var_id):
|
308
|
+
def destroy_session_variable(self, doc_handle: int, var_id):
|
309
309
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "DestroySessionVariable",
|
310
310
|
"params": [{var_id}]})
|
311
311
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -317,7 +317,7 @@ class EngineAppApi:
|
|
317
317
|
# DestroyVariableById method: Removes a varable..
|
318
318
|
# Script-defined variables cannot be removed using the DestroyVariableById method or the # NOQA
|
319
319
|
# DestroyVariableByName method.
|
320
|
-
def destroy_variable_by_id(self, doc_handle, var_name):
|
320
|
+
def destroy_variable_by_id(self, doc_handle: int, var_name):
|
321
321
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "DestroyVariableById",
|
322
322
|
"params": [{var_name}]})
|
323
323
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -331,7 +331,7 @@ class EngineAppApi:
|
|
331
331
|
# can contain the same dimension.
|
332
332
|
# Parameters:
|
333
333
|
# qProp (MANDATORY: send dim_id, dim_title, dim_grouping, dim_field, dim_label, meta_def (optional) # NOQA
|
334
|
-
def create_measure(self, doc_handle, prop):
|
334
|
+
def create_measure(self, doc_handle: int, prop):
|
335
335
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "CreateMeasure",
|
336
336
|
"params": {"qProp": prop}})
|
337
337
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -364,7 +364,7 @@ class EngineAppApi:
|
|
364
364
|
# ### Example: The variable x contains the text string Sum(Sales). In a chart, you define the expression $(x)/12. # NOQA
|
365
365
|
# The effect is exactly the same as having the chart expression Sum(Sales)/12. However, if you change the value of the variable x to Sum(Budget), # NOQA
|
366
366
|
# the data in the chart are immediately recalculated with the expression interpreted as Sum(Budget)/12. # NOQA
|
367
|
-
def create_session_variable(self, doc_handle, var_id="", var_name="", var_comment="", var_def=""):
|
367
|
+
def create_session_variable(self, doc_handle: int, var_id="", var_name="", var_comment="", var_def=""):
|
368
368
|
msg = json.dumps(
|
369
369
|
{"jsonrpc": "2.0", "id": 0, "handle": doc_handle,
|
370
370
|
"method": "CreateSessionVariable", "params": [{
|
@@ -393,7 +393,7 @@ class EngineAppApi:
|
|
393
393
|
# The effect is exactly the same as having the chart expression Sum(Sales)/12. # NOQA
|
394
394
|
# However, if you change the value of the variable x to Sum(Budget),
|
395
395
|
# the data in the chart are immediately recalculated with the expression interpreted as Sum(Budget)/12. # NOQA
|
396
|
-
def create_variable(self, doc_handle, var_id="", var_name="", var_comment="", var_def=""):
|
396
|
+
def create_variable(self, doc_handle: int, var_id="", var_name="", var_comment="", var_def=""):
|
397
397
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle,
|
398
398
|
"method": "CreateVariable", "params": [{
|
399
399
|
"qInfo": {
|
@@ -435,7 +435,7 @@ class EngineAppApi:
|
|
435
435
|
|
436
436
|
# DoSave method: Saves an app - All objects and data in the data model are saved. # NOQA
|
437
437
|
# Desktop only - server auto saves
|
438
|
-
def do_save(self, doc_handle, file_name=""):
|
438
|
+
def do_save(self, doc_handle: int, file_name=""):
|
439
439
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "DoSave",
|
440
440
|
"params": {"qFileName": file_name}})
|
441
441
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -446,7 +446,7 @@ class EngineAppApi:
|
|
446
446
|
|
447
447
|
# Evaluate method: Evaluates an expression as a string. (Actually uses EvaluateEx, which is better for giving the data type back to python) # NOQA
|
448
448
|
# Parameters: qExpression
|
449
|
-
def expr_eval(self, doc_handle, expr):
|
449
|
+
def expr_eval(self, doc_handle: int, expr):
|
450
450
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "EvaluateEx",
|
451
451
|
"params": {"qExpression": expr}})
|
452
452
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -456,7 +456,7 @@ class EngineAppApi:
|
|
456
456
|
return response['error']
|
457
457
|
|
458
458
|
# GetAllInfos method: Get the identifier and the type of any generic object in an app by using the GetAllInfos method. # NOQA
|
459
|
-
def get_all_infos(self, doc_handle):
|
459
|
+
def get_all_infos(self, doc_handle: int):
|
460
460
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetAllInfos", "params": []})
|
461
461
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
462
462
|
try:
|
@@ -465,7 +465,7 @@ class EngineAppApi:
|
|
465
465
|
return response['error']
|
466
466
|
|
467
467
|
# GetAppProperties method: Gets the properties of an app.
|
468
|
-
def get_app_properties(self, doc_handle):
|
468
|
+
def get_app_properties(self, doc_handle: int):
|
469
469
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetAppProperties", "params": []})
|
470
470
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
471
471
|
try:
|
@@ -475,7 +475,7 @@ class EngineAppApi:
|
|
475
475
|
|
476
476
|
# GetConnection method: Retrieves a connection and returns: The creation time of the connection, The identifier of # NOQA
|
477
477
|
# the connection, The type of the connection, The name of the connection, The connection string # NOQA
|
478
|
-
def get_connection(self, doc_handle, connection_id):
|
478
|
+
def get_connection(self, doc_handle: int, connection_id):
|
479
479
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetConnection",
|
480
480
|
"params": [connection_id]})
|
481
481
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -485,7 +485,7 @@ class EngineAppApi:
|
|
485
485
|
return response['error']
|
486
486
|
|
487
487
|
# GetConnections method: Lists the connections in an app
|
488
|
-
def get_connections(self, doc_handle):
|
488
|
+
def get_connections(self, doc_handle: int):
|
489
489
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetConnections", "params": []})
|
490
490
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
491
491
|
try:
|
@@ -494,7 +494,7 @@ class EngineAppApi:
|
|
494
494
|
return response['error']
|
495
495
|
|
496
496
|
# GetDatabaseInfo: Get information about an ODBC, OLEDB or CUSTOM connection # NOQA
|
497
|
-
def get_db_info(self, doc_handle, connection_id):
|
497
|
+
def get_db_info(self, doc_handle: int, connection_id):
|
498
498
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetDatabaseInfo",
|
499
499
|
"params": [connection_id]})
|
500
500
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -504,7 +504,7 @@ class EngineAppApi:
|
|
504
504
|
return response['error']
|
505
505
|
|
506
506
|
# GetDatabaseOwners: List the owners of a database for a ODBC, OLEDB or CUSTOM connection # NOQA
|
507
|
-
def get_db_owners(self, doc_handle, connection_id):
|
507
|
+
def get_db_owners(self, doc_handle: int, connection_id):
|
508
508
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetDatabaseOwners",
|
509
509
|
"params": [connection_id]})
|
510
510
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -514,7 +514,7 @@ class EngineAppApi:
|
|
514
514
|
return response['error']
|
515
515
|
|
516
516
|
# GetDatabases: List the databases of a ODBC, OLEDB or CUSTOM connection
|
517
|
-
def get_databases(self, doc_handle, connection_id):
|
517
|
+
def get_databases(self, doc_handle: int, connection_id):
|
518
518
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetDatabases",
|
519
519
|
"params": [connection_id]})
|
520
520
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -525,7 +525,7 @@ class EngineAppApi:
|
|
525
525
|
|
526
526
|
# GetDatabaseTableFields: List the fields in a table for a ODBC, OLEDB or CUSTOM connection # NOQA
|
527
527
|
# Parameters taken are: connection_id (mandatory), db_name, db_owner, table_name (mandatory) # NOQA
|
528
|
-
def get_db_table_fields(self, doc_handle, connection_id, db_name="", db_owner="", table_name=""):
|
528
|
+
def get_db_table_fields(self, doc_handle: int, connection_id, db_name="", db_owner="", table_name=""):
|
529
529
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetDatabaseTableFields",
|
530
530
|
"params": [connection_id, db_name, db_owner, table_name]})
|
531
531
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -536,7 +536,7 @@ class EngineAppApi:
|
|
536
536
|
|
537
537
|
# GetDatabaseTablePreview: Preview the data in the fields in a table for a ODBC, OLEDB or CUSTOM connection # NOQA
|
538
538
|
# Parameters taken are: connection_id (mandatory), db_name, db_owner, table_name (mandatory) # NOQA
|
539
|
-
def get_db_table_preview(self, doc_handle, connection_id, db_name="", db_owner="", table_name=""):
|
539
|
+
def get_db_table_preview(self, doc_handle: int, connection_id, db_name="", db_owner="", table_name=""):
|
540
540
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetDatabaseTablePreview",
|
541
541
|
"params": [connection_id, db_name, db_owner, table_name]})
|
542
542
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -547,7 +547,7 @@ class EngineAppApi:
|
|
547
547
|
|
548
548
|
# GetDatabaseTables: List the tables in a database for a specific owner and for a ODBC, OLEDB or CUSTOM connection # NOQA
|
549
549
|
# Parameters taken are: connection_id (mandatory), db_name, db_owner
|
550
|
-
def get_db_tables(self, doc_handle, connection_id, db_name="", db_owner=""):
|
550
|
+
def get_db_tables(self, doc_handle: int, connection_id, db_name="", db_owner=""):
|
551
551
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetDatabaseTables",
|
552
552
|
"params": [connection_id, db_name, db_owner]})
|
553
553
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -560,7 +560,7 @@ class EngineAppApi:
|
|
560
560
|
# GetEmptyScript: Creates a script that contains one section. This section contains Set statements that give # NOQA
|
561
561
|
# localized information from the regional settings of the computer.
|
562
562
|
# Parameter: none
|
563
|
-
def get_empty_script(self, doc_handle):
|
563
|
+
def get_empty_script(self, doc_handle: int):
|
564
564
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetEmptyScript", "params": []})
|
565
565
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
566
566
|
try:
|
@@ -570,7 +570,7 @@ class EngineAppApi:
|
|
570
570
|
|
571
571
|
# GetFieldDescription: Get the description of a field
|
572
572
|
# Parameter: field name
|
573
|
-
def get_field_descr(self, doc_handle, field_name):
|
573
|
+
def get_field_descr(self, doc_handle: int, field_name):
|
574
574
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetFieldDescription",
|
575
575
|
"params": {"qFieldName": field_name}})
|
576
576
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -585,7 +585,7 @@ class EngineAppApi:
|
|
585
585
|
# qRelativePath: Path of the connection file
|
586
586
|
# qDataFormat: Type of the file
|
587
587
|
# qTable (MOSTLY MANDATORY): Name of the table ***This parameter must be set for XLS, XLSX, HTML and XML files.*** # NOQA
|
588
|
-
def get_file_table_fields(self, doc_handle, connection_id,
|
588
|
+
def get_file_table_fields(self, doc_handle: int, connection_id,
|
589
589
|
rel_path="", data_fmt="", table_name=""):
|
590
590
|
msg = json.dumps(
|
591
591
|
{"jsonrpc": "2.0", "id": 0, "handle": doc_handle,
|
@@ -605,7 +605,7 @@ class EngineAppApi:
|
|
605
605
|
# qRelativePath: Path of the connection file
|
606
606
|
# qDataFormat: Type of the file
|
607
607
|
# qTable (MOSTLY MANDATORY): Name of the table ***This parameter must be set for XLS, XLSX, HTML and XML files.*** # NOQA
|
608
|
-
def get_file_table_preview(self, doc_handle, connection_id, rel_path="", data_fmt="", table_name=""):
|
608
|
+
def get_file_table_preview(self, doc_handle: int, connection_id, rel_path="", data_fmt="", table_name=""):
|
609
609
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetFileTablePreview",
|
610
610
|
"params": [connection_id, rel_path, {"qType": data_fmt}, table_name]})
|
611
611
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -620,7 +620,7 @@ class EngineAppApi:
|
|
620
620
|
# qRelativePath: Path of the connection file
|
621
621
|
# qDataFormat: Type of the file (XML, JSON)
|
622
622
|
# qTable (MOSTLY MANDATORY): Name of the table ***This parameter must be set for XLS, XLSX, HTML and XML files.*** # NOQA
|
623
|
-
def get_file_table_ex(self, doc_handle, connection_id,
|
623
|
+
def get_file_table_ex(self, doc_handle: int, connection_id,
|
624
624
|
rel_path="", data_fmt=""):
|
625
625
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetFileTablesEx",
|
626
626
|
"params": [connection_id, rel_path, {"qType": data_fmt}]})
|
@@ -635,7 +635,7 @@ class EngineAppApi:
|
|
635
635
|
# qConnectionId (MANDATORY): Identifier of the connection.
|
636
636
|
# qRelativePath: Path of the connection file
|
637
637
|
# qDataFormat: Type of the file (XML, JSON)
|
638
|
-
def get_file_tables(self, doc_handle, connection_id, rel_path="", data_fmt=""):
|
638
|
+
def get_file_tables(self, doc_handle: int, connection_id, rel_path="", data_fmt=""):
|
639
639
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetFileTables",
|
640
640
|
"params": [connection_id, rel_path, {"qType": data_fmt}]})
|
641
641
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -646,7 +646,7 @@ class EngineAppApi:
|
|
646
646
|
|
647
647
|
# GetFolderItemsForConnection method: List the items for a folder connection # NOQA
|
648
648
|
# Parameter: connection_id
|
649
|
-
def get_folder_items_for_connection(self, doc_handle, connection_id):
|
649
|
+
def get_folder_items_for_connection(self, doc_handle: int, connection_id):
|
650
650
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetFolderItemsForConnection",
|
651
651
|
"params": [connection_id]})
|
652
652
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -656,7 +656,7 @@ class EngineAppApi:
|
|
656
656
|
return response['error']
|
657
657
|
|
658
658
|
# GetAllInfos method: Get the identifier and the type of any generic object in an app by using the GetAllInfos method. # NOQA
|
659
|
-
def get_lineage(self, doc_handle):
|
659
|
+
def get_lineage(self, doc_handle: int):
|
660
660
|
"""
|
661
661
|
Gets the lineage information of the app. The lineage information includes the LOAD and STORE statements from
|
662
662
|
the data load script associated with this app.
|
@@ -674,7 +674,7 @@ class EngineAppApi:
|
|
674
674
|
except KeyError:
|
675
675
|
return response['error']
|
676
676
|
|
677
|
-
def create_session_object(self, doc_handle, prop):
|
677
|
+
def create_session_object(self, doc_handle: int, prop):
|
678
678
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "CreateSessionObject",
|
679
679
|
"params": {"qProp": prop}})
|
680
680
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -683,7 +683,7 @@ class EngineAppApi:
|
|
683
683
|
except KeyError:
|
684
684
|
return response['error']
|
685
685
|
|
686
|
-
def get_set_analysis(self, doc_handle, state_name="", bookmark_id=""):
|
686
|
+
def get_set_analysis(self, doc_handle: int, state_name="", bookmark_id=""):
|
687
687
|
msg = json.dumps({"jsonrpc": "2.0", "id": 3, "handle": doc_handle, "method": "GetSetAnalysis",
|
688
688
|
"params": {"qStateName": state_name, "qBookmarkId": bookmark_id}})
|
689
689
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
@@ -701,7 +701,7 @@ class EngineAppApi:
|
|
701
701
|
except KeyError:
|
702
702
|
return response['error']
|
703
703
|
|
704
|
-
def get_variable_by_id(self, doc_handle, variable_id):
|
704
|
+
def get_variable_by_id(self, doc_handle: int, variable_id):
|
705
705
|
"""
|
706
706
|
Gets the handle of a variable.
|
707
707
|
|
@@ -715,6 +715,66 @@ class EngineAppApi:
|
|
715
715
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetVariableById",
|
716
716
|
"params": {"qId": variable_id}})
|
717
717
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
718
|
+
try:
|
719
|
+
return response['result']['qReturn']
|
720
|
+
except KeyError:
|
721
|
+
return response['error']
|
722
|
+
|
723
|
+
|
724
|
+
def create_bookmark(self, doc_handle: int, prop: dict):
|
725
|
+
"""
|
726
|
+
Creates a bookmark.
|
727
|
+
|
728
|
+
Parameters:
|
729
|
+
doc_handle (int): The handle identifying the document.
|
730
|
+
prop (dict): Bookmark properties.
|
731
|
+
|
732
|
+
Returns:
|
733
|
+
dict: The handle of the generic bookmark.
|
734
|
+
"""
|
735
|
+
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "CreateBookmark",
|
736
|
+
"params": {"qProp": prop}})
|
737
|
+
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
738
|
+
try:
|
739
|
+
return response['result']['qReturn']
|
740
|
+
except KeyError:
|
741
|
+
return response['error']
|
742
|
+
|
743
|
+
|
744
|
+
def get_bookmarks(self, doc_handle: int, options: dict):
|
745
|
+
"""
|
746
|
+
Returns all bookmarks compatible with options.
|
747
|
+
|
748
|
+
Parameters:
|
749
|
+
doc_handle (int): The handle identifying the document.
|
750
|
+
qOptions (dict): Bookmark type filter and requested properties.
|
751
|
+
|
752
|
+
Returns:
|
753
|
+
list: The resulting list.
|
754
|
+
"""
|
755
|
+
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": doc_handle, "method": "GetBookmarks",
|
756
|
+
"params": {"qOptions": options}})
|
757
|
+
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
758
|
+
try:
|
759
|
+
return response['result']
|
760
|
+
except KeyError:
|
761
|
+
return response['error']
|
762
|
+
|
763
|
+
|
764
|
+
def get_bookmark(self, app_handle: int, bookmark_id: str):
|
765
|
+
"""
|
766
|
+
Retrieves a specific bookmark from the app identified by the document handle.
|
767
|
+
|
768
|
+
Parameters:
|
769
|
+
app_handle (int): The handle identifying the app document.
|
770
|
+
bookmark_id (str): The ID of the bookmark to retrieve.
|
771
|
+
|
772
|
+
Returns:
|
773
|
+
dict: The retrieved object (qReturn). In case of an error, returns the error information.
|
774
|
+
"""
|
775
|
+
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": app_handle, "method": "GetBookmark",
|
776
|
+
"params": {"qId": bookmark_id}})
|
777
|
+
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
718
778
|
try:
|
719
779
|
return response['result']['qReturn']
|
720
780
|
except KeyError:
|
@@ -124,7 +124,7 @@ class EngineGenericObjectApi:
|
|
124
124
|
except KeyError:
|
125
125
|
return response["error"]
|
126
126
|
|
127
|
-
def get_hypercube_data(self, handle, path
|
127
|
+
def get_hypercube_data(self, handle: int, path: str, pages: list):
|
128
128
|
"""
|
129
129
|
Retrieves the data from a specific hypercube in a generic object.
|
130
130
|
|
@@ -137,14 +137,14 @@ class EngineGenericObjectApi:
|
|
137
137
|
dict: The data from the hypercube. In case of an error, returns the error information.
|
138
138
|
"""
|
139
139
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": handle, "method": "GetHyperCubeData",
|
140
|
-
"params": {"qPath": path, "qPages":
|
140
|
+
"params": {"qPath": path, "qPages": pages}})
|
141
141
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
142
142
|
try:
|
143
143
|
return response["result"]
|
144
144
|
except KeyError:
|
145
145
|
return response["error"]
|
146
146
|
|
147
|
-
def get_hypercube_pivot_data(self, handle, path
|
147
|
+
def get_hypercube_pivot_data(self, handle: int, path: str, pages: list):
|
148
148
|
"""
|
149
149
|
Retrieves the pivot data from a specific hypercube in a generic object.
|
150
150
|
|
@@ -157,14 +157,14 @@ class EngineGenericObjectApi:
|
|
157
157
|
dict: The pivot data from the hypercube. In case of an error, returns the error information.
|
158
158
|
"""
|
159
159
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": handle, "method": "GetHyperCubePivotData",
|
160
|
-
"params": {"qPath": path, "qPages":
|
160
|
+
"params": {"qPath": path, "qPages": pages}})
|
161
161
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
162
162
|
try:
|
163
163
|
return response["result"]
|
164
164
|
except KeyError:
|
165
165
|
return response["error"]
|
166
166
|
|
167
|
-
def get_hypercube_stack_data(self, handle, path
|
167
|
+
def get_hypercube_stack_data(self, handle: int, path: str, pages: list, max_no_cells: int = 10000):
|
168
168
|
"""
|
169
169
|
Retrieves the values of a stacked pivot table. It is possible to retrieve specific pages of data.
|
170
170
|
|
@@ -179,7 +179,7 @@ class EngineGenericObjectApi:
|
|
179
179
|
dict: The pivot data from the hypercube. In case of an error, returns the error information.
|
180
180
|
"""
|
181
181
|
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": handle, "method": "GetHyperCubeStackData",
|
182
|
-
"params": {"qPath": path, "qPages":
|
182
|
+
"params": {"qPath": path, "qPages": pages, "qMaxNbrCells": max_no_cells}})
|
183
183
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
184
184
|
try:
|
185
185
|
return response["result"]
|
@@ -208,3 +208,60 @@ class EngineGenericObjectApi:
|
|
208
208
|
return response["result"]
|
209
209
|
except KeyError:
|
210
210
|
return response["error"]
|
211
|
+
|
212
|
+
|
213
|
+
def get_properties(self, handle: int):
|
214
|
+
"""
|
215
|
+
Retrieves the properties of a specific generic object.
|
216
|
+
|
217
|
+
Parameters:
|
218
|
+
handle (int): The handle identifying the generic object.
|
219
|
+
|
220
|
+
Returns:
|
221
|
+
dict: The properties of the generic object (qLayout). In case of an error, returns the error information.
|
222
|
+
"""
|
223
|
+
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": handle, "method": "GetProperties", "params": {}})
|
224
|
+
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
225
|
+
try:
|
226
|
+
return response["result"]["qProp"]
|
227
|
+
except KeyError:
|
228
|
+
return response["error"]
|
229
|
+
|
230
|
+
|
231
|
+
def embed_snapshot_object(self, handle: int, snapshot_id: str):
|
232
|
+
"""
|
233
|
+
Adds a snapshot to a generic object. Only one snapshot can be embedded in a generic object. If you embed a
|
234
|
+
snapshot in an object that already contains a snapshot, the new snapshot overwrites the previous one.
|
235
|
+
|
236
|
+
Parameters:
|
237
|
+
handle (int): The handle identifying the generic object.
|
238
|
+
snapshot_id (str): The id of the snapshot to be embeded.
|
239
|
+
|
240
|
+
Returns:
|
241
|
+
update
|
242
|
+
"""
|
243
|
+
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": handle, "method": "EmbedSnapshotObject",
|
244
|
+
"params": {"qId": snapshot_id}})
|
245
|
+
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
246
|
+
try:
|
247
|
+
return response["result"]
|
248
|
+
except KeyError:
|
249
|
+
return response["error"]
|
250
|
+
|
251
|
+
|
252
|
+
def get_parent(self, handle: int):
|
253
|
+
"""
|
254
|
+
Returns the type of the object and the corresponding handle to the parent object in the hiearchy.
|
255
|
+
|
256
|
+
Parameters:
|
257
|
+
handle (int): The handle identifying the generic object.
|
258
|
+
|
259
|
+
Returns:
|
260
|
+
{ "qType": "GenericObject", "qHandle": <handle of the object> }
|
261
|
+
"""
|
262
|
+
msg = json.dumps({"jsonrpc": "2.0", "id": 0, "handle": handle, "method": "GetParent", "params": {}})
|
263
|
+
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
264
|
+
try:
|
265
|
+
return response["result"]["qReturn"]
|
266
|
+
except KeyError:
|
267
|
+
return response["error"]
|
qe_api_client/engine.py
CHANGED
@@ -12,6 +12,8 @@ import qe_api_client.structs as structs
|
|
12
12
|
import math
|
13
13
|
import pandas as pd
|
14
14
|
import numpy as np
|
15
|
+
from datetime import datetime, timezone
|
16
|
+
import time
|
15
17
|
|
16
18
|
|
17
19
|
class QixEngine:
|
@@ -135,9 +137,9 @@ class QixEngine:
|
|
135
137
|
# Define of the single dimension properties
|
136
138
|
nx_info = self.structs.nx_info(obj_type="dimension")
|
137
139
|
if dim_color is None:
|
138
|
-
coloring = self.structs.
|
140
|
+
coloring = self.structs.dim_coloring()
|
139
141
|
else:
|
140
|
-
coloring = self.structs.
|
142
|
+
coloring = self.structs.dim_coloring(base_color={"color": dim_color, "index": dim_color_index})
|
141
143
|
|
142
144
|
nx_library_dimension_def = self.structs.nx_library_dimension_def(grouping="N", field_definitions=[dim_def],
|
143
145
|
field_labels=[dim_title],
|
@@ -213,7 +215,8 @@ class QixEngine:
|
|
213
215
|
|
214
216
|
|
215
217
|
def create_master_measure(self, app_handle: int, mes_title: str, mes_def: str, mes_label: str = "",
|
216
|
-
mes_desc: str = "", mes_tags: list = None
|
218
|
+
mes_desc: str = "", mes_tags: list = None, mes_color: str = None,
|
219
|
+
mes_color_index: int = -1, gradient: dict = None):
|
217
220
|
"""
|
218
221
|
Creates a master measure.
|
219
222
|
|
@@ -224,6 +227,8 @@ class QixEngine:
|
|
224
227
|
mes_label (str, optional): The label of the measure.
|
225
228
|
mes_desc (str, optional): The description of the measure.
|
226
229
|
mes_tags (list, optional): The tags of the measure.
|
230
|
+
mes_color (str, optional): The color of the measure.
|
231
|
+
mes_color_index (int, optional): The index of the color of the measure.
|
227
232
|
|
228
233
|
Returns:
|
229
234
|
dict: The handle and Id of the measure.
|
@@ -233,8 +238,17 @@ class QixEngine:
|
|
233
238
|
|
234
239
|
# Define of the measure properties
|
235
240
|
nx_info = self.structs.nx_info(obj_type="measure")
|
241
|
+
|
242
|
+
if mes_color is None:
|
243
|
+
coloring = self.structs.mes_coloring()
|
244
|
+
else:
|
245
|
+
coloring = self.structs.mes_coloring(base_color={"color": mes_color, "index": mes_color_index})
|
246
|
+
|
247
|
+
if gradient is not None:
|
248
|
+
coloring.update({"gradient": gradient})
|
249
|
+
|
236
250
|
nx_library_measure_def = self.structs.nx_library_measure_def(label=mes_title, mes_def=mes_def,
|
237
|
-
label_expression=mes_label)
|
251
|
+
label_expression=mes_label, coloring=coloring)
|
238
252
|
gen_mes_props = self.structs.generic_measure_properties(nx_info=nx_info,
|
239
253
|
nx_library_measure_def=nx_library_measure_def,
|
240
254
|
title=mes_title, description=mes_desc, tags=mes_tags)
|
@@ -439,6 +453,203 @@ class QixEngine:
|
|
439
453
|
return chart
|
440
454
|
|
441
455
|
|
456
|
+
def create_snapshot(self, app_handle: int, object_id: str, snapshot_title: str = "", snapshot_description: str = "",
|
457
|
+
object_width: float = 1280, object_height: float = 720, bounding_client_width: float = 1280,
|
458
|
+
bounding_client_height: float = 720, rtl: bool = False, parent_width: float = 1280, parent_height: float = 720,
|
459
|
+
content_width: float = 1280, content_height: float = 720, chart_data_scroll_offset_start: int = 0,
|
460
|
+
chart_data_scroll_offset_end: int = 53, chart_data_legend_scroll_offset: int = 0, chart_data_zoom_min = 0,
|
461
|
+
chart_data_zoom_max = 0):
|
462
|
+
"""
|
463
|
+
Creates a snapshot object.
|
464
|
+
|
465
|
+
Parameters:
|
466
|
+
app_handle (int): The handle of the app.
|
467
|
+
object_id (str): The id of the object.
|
468
|
+
snapshot_title (str): The title of the snapshot.
|
469
|
+
snapshot_description (str): The description of the snapshot.
|
470
|
+
object_width (float): The width of the snapshot object.
|
471
|
+
object_height (float): The height of the snapshot object.
|
472
|
+
bounding_client_width (float): The width of the bounding client.
|
473
|
+
bounding_client_height (float): The height of the bounding client.
|
474
|
+
rtl (bool): Controls the rendering of content with right-to-left (RTL) language support.
|
475
|
+
parent_width (float): The width of the parent object.
|
476
|
+
parent_height (float): The height of the parent object.
|
477
|
+
content_width (float): The width of the content object.
|
478
|
+
content_height (float): The height of the content object.
|
479
|
+
chart_data_scroll_offset_start (int): Scroll offset start.
|
480
|
+
chart_data_scroll_offset_end (int): Scroll offset end.
|
481
|
+
chart_data_legend_scroll_offset (int): Legend scroll offset.
|
482
|
+
chart_data_zoom_min: Minimum chart data zoom.
|
483
|
+
chart_data_zoom_max: Maximum chart data zoom.
|
484
|
+
|
485
|
+
Returns:
|
486
|
+
dict: The handle and Id of the created snapshot.
|
487
|
+
"""
|
488
|
+
# Get chart object
|
489
|
+
chart_obj = self.eaa.get_object(app_handle=app_handle, object_id=object_id)
|
490
|
+
chart_obj_handle = self.get_handle(chart_obj)
|
491
|
+
|
492
|
+
# Get sheet object
|
493
|
+
sheet_obj = self.get_object_sheet(app_handle=app_handle, obj_id=object_id)
|
494
|
+
sheet_id = self.get_id(sheet_obj)
|
495
|
+
|
496
|
+
# Get the visualization type
|
497
|
+
chart_obj_layout = self.egoa.get_layout(handle=chart_obj_handle)
|
498
|
+
visualization = chart_obj_layout["visualization"]
|
499
|
+
|
500
|
+
# Attribut "qInfo" changed
|
501
|
+
chart_obj_layout["qInfo"] = {"qType": "snapshot"}
|
502
|
+
|
503
|
+
# Attribut "qMetaDef" added
|
504
|
+
chart_obj_layout["qMetaDef"] = {"title": snapshot_title, "description": snapshot_description}
|
505
|
+
|
506
|
+
# Attribut "creationDate" added
|
507
|
+
chart_obj_layout["creationDate"] = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
|
508
|
+
|
509
|
+
# Attribut "permissions" added
|
510
|
+
chart_obj_layout["permissions"] = {"update": True, "publish": False, "export": False, "exportData": True,
|
511
|
+
"changeOwner": False, "remove": True}
|
512
|
+
|
513
|
+
# Attribut "visualizationType" added
|
514
|
+
chart_obj_layout["visualizationType"] = visualization
|
515
|
+
|
516
|
+
# Attribut "sourceObjectId" added
|
517
|
+
chart_obj_layout["sourceObjectId"] = object_id
|
518
|
+
|
519
|
+
# Attribut "sheetId" added
|
520
|
+
chart_obj_layout["sheetId"] = sheet_id
|
521
|
+
|
522
|
+
# Attribut "timestamp" added
|
523
|
+
chart_obj_layout["timestamp"] = int(time.time() * 1000)
|
524
|
+
|
525
|
+
# Attribut "isClone" added
|
526
|
+
chart_obj_layout["isClone"] = False
|
527
|
+
|
528
|
+
# Attribut "supportExport" added
|
529
|
+
chart_obj_layout["supportExport"] = True
|
530
|
+
|
531
|
+
# Attribut "qIncludeVariables" added
|
532
|
+
chart_obj_layout["qIncludeVariables"] = True
|
533
|
+
|
534
|
+
# Build the special snapshot parameters for the different chart types.
|
535
|
+
if visualization in ["sn-table", "pivot-table"]:
|
536
|
+
# Attribut "snapshotData" added
|
537
|
+
chart_obj_layout["snapshotData"] = {
|
538
|
+
"object": {
|
539
|
+
"size": {
|
540
|
+
"w": object_width,
|
541
|
+
"h": object_height,
|
542
|
+
"boundingClientWidth": bounding_client_width,
|
543
|
+
"boundingClientHeight": bounding_client_height
|
544
|
+
}
|
545
|
+
},
|
546
|
+
"rtl": rtl,
|
547
|
+
"parent": {
|
548
|
+
"h": parent_height,
|
549
|
+
"w": parent_width
|
550
|
+
}
|
551
|
+
}
|
552
|
+
|
553
|
+
elif visualization in ["combochart", "barchart"]:
|
554
|
+
# Attribut "snapshotData" added
|
555
|
+
chart_obj_layout["snapshotData"] = {
|
556
|
+
"object": {
|
557
|
+
"size": {
|
558
|
+
"w": object_width,
|
559
|
+
"h": object_height,
|
560
|
+
"boundingClientWidth": bounding_client_width,
|
561
|
+
"boundingClientHeight": bounding_client_height
|
562
|
+
}
|
563
|
+
},
|
564
|
+
"rtl": rtl,
|
565
|
+
"content": {
|
566
|
+
"size": {
|
567
|
+
"w": content_width,
|
568
|
+
"h": content_height
|
569
|
+
},
|
570
|
+
"chartData": {
|
571
|
+
"scrollOffset": {
|
572
|
+
"start": chart_data_scroll_offset_start,
|
573
|
+
"end": chart_data_scroll_offset_end
|
574
|
+
},
|
575
|
+
"legendScrollOffset": chart_data_legend_scroll_offset
|
576
|
+
}
|
577
|
+
},
|
578
|
+
"parent": {
|
579
|
+
"h": parent_height,
|
580
|
+
"w": parent_width
|
581
|
+
}
|
582
|
+
}
|
583
|
+
|
584
|
+
elif visualization in ["linechart"]:
|
585
|
+
# Attribut "snapshotData" added
|
586
|
+
chart_obj_layout["snapshotData"] = {
|
587
|
+
"object": {
|
588
|
+
"size": {
|
589
|
+
"w": object_width,
|
590
|
+
"h": object_height,
|
591
|
+
"boundingClientWidth": bounding_client_width,
|
592
|
+
"boundingClientHeight": bounding_client_height
|
593
|
+
}
|
594
|
+
},
|
595
|
+
"rtl": rtl,
|
596
|
+
"content": {
|
597
|
+
"size": {
|
598
|
+
"w": content_width,
|
599
|
+
"h": content_height
|
600
|
+
},
|
601
|
+
"chartData": {
|
602
|
+
"zoom": {
|
603
|
+
"min": chart_data_zoom_min,
|
604
|
+
"max": chart_data_zoom_max
|
605
|
+
}
|
606
|
+
}
|
607
|
+
},
|
608
|
+
"parent": {
|
609
|
+
"h": parent_height,
|
610
|
+
"w": parent_width
|
611
|
+
}
|
612
|
+
}
|
613
|
+
|
614
|
+
else:
|
615
|
+
print("Chart type not supported.")
|
616
|
+
|
617
|
+
# Create snapshot
|
618
|
+
snapshot = self.eaa.create_bookmark(doc_handle=app_handle, prop=chart_obj_layout)
|
619
|
+
snapshot.update({"visualization": visualization})
|
620
|
+
|
621
|
+
return snapshot
|
622
|
+
|
623
|
+
|
624
|
+
def embed_snapshot(self, app_handle: int, snapshot_id: str, slide_id: str):
|
625
|
+
"""
|
626
|
+
Embeds a created snapshot object on a slide.
|
627
|
+
|
628
|
+
Parameters:
|
629
|
+
app_handle (int): The handle of the app.
|
630
|
+
snapshot_id (str): The id of the snapshot.
|
631
|
+
slide_id (str): The id of the slide to embed.
|
632
|
+
"""
|
633
|
+
# Get the slide, where the snapshot should be embeded.
|
634
|
+
slide = self.eaa.get_object(app_handle=app_handle, object_id=slide_id)
|
635
|
+
slide_handle = self.get_handle(slide)
|
636
|
+
|
637
|
+
# Get the visualization type of the snapshot
|
638
|
+
snapshot = self.eaa.get_bookmark(app_handle=app_handle, bookmark_id=snapshot_id)
|
639
|
+
snapshot_handle = self.get_handle(snapshot)
|
640
|
+
snapshot_layout = self.egoa.get_layout(handle=snapshot_handle)
|
641
|
+
visualization_type = snapshot_layout["visualizationType"]
|
642
|
+
|
643
|
+
# create the snapshot
|
644
|
+
slideitem_snapshot_properties = self.structs.slideitem_snapshot_properties(snapshot_id=snapshot_id,
|
645
|
+
visualization_type=visualization_type)
|
646
|
+
slideitem_snapshot = self.egoa.create_child(handle=slide_handle, prop=slideitem_snapshot_properties)
|
647
|
+
slideitem_snapshot_handle = self.get_handle(slideitem_snapshot)
|
648
|
+
|
649
|
+
slideitem_snapshot_embeded = self.egoa.embed_snapshot_object(handle=slideitem_snapshot_handle,
|
650
|
+
snapshot_id=snapshot_id)
|
651
|
+
|
652
|
+
|
442
653
|
def get_app_lineage_info(self, app_handle):
|
443
654
|
"""
|
444
655
|
Gets the lineage information of the app. The lineage information includes the LOAD and STORE statements from
|
@@ -488,19 +699,60 @@ class QixEngine:
|
|
488
699
|
|
489
700
|
Parameters:
|
490
701
|
obj : dict
|
491
|
-
The object containing the
|
702
|
+
The object containing the id.
|
492
703
|
|
493
704
|
Returns:
|
494
|
-
int: The
|
705
|
+
int: The id value.
|
495
706
|
|
496
707
|
Raises:
|
497
|
-
ValueError: If the
|
708
|
+
ValueError: If the id value is invalid.
|
498
709
|
"""
|
499
710
|
try:
|
500
711
|
return obj["qGenericId"]
|
501
712
|
except ValueError:
|
502
713
|
return "Bad id value in " + obj
|
503
714
|
|
715
|
+
@staticmethod
|
716
|
+
def get_type(obj):
|
717
|
+
"""
|
718
|
+
Retrieves the type from a given object.
|
719
|
+
|
720
|
+
Parameters:
|
721
|
+
obj : dict
|
722
|
+
The object containing the type.
|
723
|
+
|
724
|
+
Returns:
|
725
|
+
int: The type value.
|
726
|
+
|
727
|
+
Raises:
|
728
|
+
ValueError: If the type value is invalid.
|
729
|
+
"""
|
730
|
+
try:
|
731
|
+
return obj["qGenericType"]
|
732
|
+
except ValueError:
|
733
|
+
return "Bad type value in " + obj
|
734
|
+
|
735
|
+
|
736
|
+
def get_object_sheet(self, app_handle: int, obj_id: str):
|
737
|
+
"""
|
738
|
+
Retrieves the sheet from a given chart object.
|
739
|
+
|
740
|
+
Parameters:
|
741
|
+
app_handle (int): The handle of the app.
|
742
|
+
obj_id (str): The ID of the object.
|
743
|
+
|
744
|
+
Returns:
|
745
|
+
dict: The sheet object with handle and id.
|
746
|
+
"""
|
747
|
+
parent_obj = self.eaa.get_object(app_handle=app_handle, object_id=obj_id)
|
748
|
+
while self.get_type(parent_obj) != "sheet":
|
749
|
+
obj = parent_obj
|
750
|
+
obj_handle = self.get_handle(obj)
|
751
|
+
parent_obj = self.egoa.get_parent(handle=obj_handle)
|
752
|
+
|
753
|
+
return parent_obj
|
754
|
+
|
755
|
+
|
504
756
|
def get_chart_data(self, app_handle, obj_id):
|
505
757
|
"""
|
506
758
|
Retrieves the data from a given chart object.
|
@@ -526,14 +778,25 @@ class QixEngine:
|
|
526
778
|
# Determine the number of the columns and the rows the table has and splits in certain circumstances the table
|
527
779
|
# calls
|
528
780
|
no_of_columns = obj_layout['qHyperCube']['qSize']['qcx']
|
781
|
+
|
782
|
+
if no_of_columns == 0:
|
783
|
+
return 'The chart either contains no columns or has a calculation condition!'
|
784
|
+
|
529
785
|
width = no_of_columns
|
530
786
|
no_of_rows = obj_layout['qHyperCube']['qSize']['qcy']
|
531
787
|
height = int(math.floor(10000 / no_of_columns))
|
532
788
|
|
533
789
|
# Extract the dimension and measure titles and concat them to column names.
|
534
|
-
|
535
|
-
|
536
|
-
|
790
|
+
dimension_info = obj_layout['qHyperCube'].get('qDimensionInfo', [])
|
791
|
+
measure_info = obj_layout['qHyperCube'].get('qMeasureInfo', [])
|
792
|
+
column_info = dimension_info + measure_info
|
793
|
+
|
794
|
+
# Build the column mapping using qEffectiveInterColumnSortOrder
|
795
|
+
sort_order = sorted(obj_layout['qHyperCube']['qEffectiveInterColumnSortOrder'])
|
796
|
+
sort_order_positive = [x for x in sort_order if x >= 0]
|
797
|
+
column_names = []
|
798
|
+
for i in sort_order_positive:
|
799
|
+
column_names.append(column_info[i]["qFallbackTitle"])
|
537
800
|
|
538
801
|
# if the type of the charts has a straight data structure
|
539
802
|
if (obj_layout['qInfo']['qType'] in ['table', 'sn-table', 'piechart', 'scatterplot', 'combochart', 'barchart']
|
@@ -546,7 +809,7 @@ class QixEngine:
|
|
546
809
|
# Retrieves the hypercube data in a loop (because of limitation from 10.000 cells per call)
|
547
810
|
while no_of_rows > page * height:
|
548
811
|
nx_page = self.structs.nx_page(left=0, top=page * height, width=width, height=height)
|
549
|
-
hc_data = self.egoa.get_hypercube_data(obj_handle, '/qHyperCubeDef', nx_page)[
|
812
|
+
hc_data = self.egoa.get_hypercube_data(handle=obj_handle, path='/qHyperCubeDef', pages=[nx_page])[
|
550
813
|
'qDataPages'][0]['qMatrix']
|
551
814
|
data_values.extend(hc_data)
|
552
815
|
page += 1
|
@@ -563,9 +826,10 @@ class QixEngine:
|
|
563
826
|
|
564
827
|
# Supporting function to traverse all subnodes to get all dimensions
|
565
828
|
def get_all_dimensions(node):
|
566
|
-
|
567
|
-
|
568
|
-
|
829
|
+
label = node.get('qText', '') # Leerer String, falls nicht vorhanden
|
830
|
+
dimensions = [label]
|
831
|
+
|
832
|
+
if 'qSubNodes' in node and node['qSubNodes']:
|
569
833
|
sub_dimensions = []
|
570
834
|
for sub_node in node['qSubNodes']:
|
571
835
|
sub_dimensions.extend([dimensions + d for d in get_all_dimensions(sub_node)])
|
@@ -573,13 +837,25 @@ class QixEngine:
|
|
573
837
|
else:
|
574
838
|
return [dimensions]
|
575
839
|
|
576
|
-
#
|
840
|
+
# Supporting function to get all column headers for the pivot table
|
841
|
+
def get_column_paths(node):
|
842
|
+
label = node.get('qText', '')
|
843
|
+
current_path = [label]
|
844
|
+
|
845
|
+
if 'qSubNodes' in node and node['qSubNodes']:
|
846
|
+
paths = []
|
847
|
+
for sub in node['qSubNodes']:
|
848
|
+
for path in get_column_paths(sub):
|
849
|
+
paths.append(current_path + path)
|
850
|
+
return paths
|
851
|
+
else:
|
852
|
+
return [current_path]
|
853
|
+
|
577
854
|
col_headers = []
|
578
855
|
nx_page_top = self.structs.nx_page(left=0, top=0, width=width, height=1)
|
579
|
-
hc_top = self.egoa.get_hypercube_pivot_data(obj_handle, '/qHyperCubeDef', nx_page_top)[
|
580
|
-
'qDataPages'][0]['qTop']
|
856
|
+
hc_top = self.egoa.get_hypercube_pivot_data(handle=obj_handle, path='/qHyperCubeDef', pages=[nx_page_top])['qDataPages'][0]['qTop']
|
581
857
|
for top_node in hc_top:
|
582
|
-
col_headers.extend(
|
858
|
+
col_headers.extend(get_column_paths(top_node))
|
583
859
|
|
584
860
|
# Paging variables
|
585
861
|
page = 0
|
@@ -591,13 +867,13 @@ class QixEngine:
|
|
591
867
|
nx_page = self.structs.nx_page(left=0, top=page * height, width=width, height=height)
|
592
868
|
|
593
869
|
# Retrieves the row headers for the pivot table
|
594
|
-
hc_left = self.egoa.get_hypercube_pivot_data(obj_handle, '/qHyperCubeDef', nx_page)[
|
870
|
+
hc_left = self.egoa.get_hypercube_pivot_data(handle=obj_handle, path='/qHyperCubeDef', pages=[nx_page])[
|
595
871
|
'qDataPages'][0]['qLeft']
|
596
872
|
for left_node in hc_left:
|
597
873
|
row_headers.extend(get_all_dimensions(left_node))
|
598
874
|
|
599
875
|
# Retrieves the data for the pivot table
|
600
|
-
hc_data = self.egoa.get_hypercube_pivot_data(obj_handle, '/qHyperCubeDef', nx_page)[
|
876
|
+
hc_data = self.egoa.get_hypercube_pivot_data(handle=obj_handle, path='/qHyperCubeDef', pages=[nx_page])[
|
601
877
|
'qDataPages'][0]['qData']
|
602
878
|
for row in hc_data:
|
603
879
|
data_values.append([cell['qText'] for cell in row])
|
@@ -610,12 +886,15 @@ class QixEngine:
|
|
610
886
|
|
611
887
|
# Creates the Dataframe
|
612
888
|
df = pd.DataFrame(data_values, index=row_index, columns=col_index)
|
889
|
+
index_levels = df.index.nlevels
|
890
|
+
df.index.names = column_names[:index_levels]
|
891
|
+
df = df.reset_index()
|
613
892
|
|
614
893
|
# if the type of the charts has a stacked data structure
|
615
894
|
elif obj_layout['qInfo']['qType'] in ['barchart'] and obj_layout['qHyperCube']['qStackedDataPages'] != []:
|
616
895
|
max_no_cells = no_of_columns * no_of_rows
|
617
896
|
nx_page = self.structs.nx_page(left=0, top=0, width=no_of_columns, height=no_of_rows)
|
618
|
-
hc_data = self.egoa.get_hypercube_stack_data(obj_handle, '/qHyperCubeDef', nx_page, max_no_cells)[
|
897
|
+
hc_data = self.egoa.get_hypercube_stack_data(handle=obj_handle, path='/qHyperCubeDef', pages=[nx_page], max_no_cells=max_no_cells)[
|
619
898
|
'qDataPages'][0]['qData'][0]['qSubNodes']
|
620
899
|
|
621
900
|
# Transform the nested structure into a flat DataFrame
|
@@ -701,7 +980,7 @@ class QixEngine:
|
|
701
980
|
# Retrieves the hypercube data in a loop (because of limitation from 10.000 cells per call)
|
702
981
|
while no_of_rows > page * height:
|
703
982
|
nx_page = self.structs.nx_page(left=0, top=page * height, width=width, height=height)
|
704
|
-
hc_data = self.egoa.get_hypercube_data(hc_obj_handle, '/qHyperCubeDef', nx_page)['qDataPages'][0]['qMatrix']
|
983
|
+
hc_data = self.egoa.get_hypercube_data(handle=hc_obj_handle, path='/qHyperCubeDef', pages=[nx_page])['qDataPages'][0]['qMatrix']
|
705
984
|
data_values.extend(hc_data)
|
706
985
|
page += 1
|
707
986
|
|
qe_api_client/structs.py
CHANGED
@@ -277,14 +277,18 @@ def nx_library_dimension_def(grouping: str = "N", field_definitions: list = None
|
|
277
277
|
|
278
278
|
|
279
279
|
def nx_library_measure_def(label: str, mes_def: str, grouping: str = "N", expressions: list = None,
|
280
|
-
active_expression: int = 0, label_expression:str = "", num_format: dict = None
|
280
|
+
active_expression: int = 0, label_expression:str = "", num_format: dict = None,
|
281
|
+
coloring: dict = None):
|
282
|
+
if coloring is None:
|
283
|
+
coloring = {}
|
281
284
|
if num_format is None:
|
282
285
|
num_format = {}
|
283
286
|
if expressions is None:
|
284
287
|
expressions = []
|
285
288
|
return {
|
286
289
|
"qLabel": label, "qDef": mes_def,"qGrouping": grouping, "qExpressions": expressions,
|
287
|
-
"qActiveExpression": active_expression, "qLabelExpression": label_expression, "qNumFormat": num_format
|
290
|
+
"qActiveExpression": active_expression, "qLabelExpression": label_expression, "qNumFormat": num_format,
|
291
|
+
"coloring": coloring
|
288
292
|
}
|
289
293
|
|
290
294
|
|
@@ -509,7 +513,7 @@ def color_map(colors: list = None, nul: dict = None, oth: dict = None, pal: str
|
|
509
513
|
}
|
510
514
|
|
511
515
|
|
512
|
-
def
|
516
|
+
def dim_coloring(change_hash: str = None, color_map_ref: str = "", has_value_colors: bool = False, base_color: dict = None):
|
513
517
|
if base_color is None:
|
514
518
|
base_color = {"color": "none", "index": 0}
|
515
519
|
return {
|
@@ -520,6 +524,15 @@ def coloring(change_hash: str = None, color_map_ref: str = "", has_value_colors:
|
|
520
524
|
}
|
521
525
|
|
522
526
|
|
527
|
+
def mes_coloring(base_color: dict = None, _gradient: dict = None):
|
528
|
+
coloring = {}
|
529
|
+
if base_color is not None:
|
530
|
+
coloring.update({"baseColor": base_color})
|
531
|
+
if _gradient is not None:
|
532
|
+
coloring.update({"gradient": _gradient})
|
533
|
+
return coloring
|
534
|
+
|
535
|
+
|
523
536
|
def color_map_properties(dim_id: str, prop_def:dict = None, extends_id: str = "", state_name: str = "",
|
524
537
|
_color_map: dict = None):
|
525
538
|
|
@@ -539,3 +552,115 @@ def value_color(value: str, color: str, index: int = -1):
|
|
539
552
|
"value": value,
|
540
553
|
"baseColor": {"color": color, "index": index}
|
541
554
|
}
|
555
|
+
|
556
|
+
|
557
|
+
def color(_color: str, index: int = -1):
|
558
|
+
return {"color": _color, "index": index}
|
559
|
+
|
560
|
+
|
561
|
+
def gradient(colors: list = None, break_types: list = None, limits: list = None, limit_type: str = "percent"):
|
562
|
+
if colors is None:
|
563
|
+
colors = [color(_color="#332288"), color(_color="#117733")]
|
564
|
+
if break_types is None:
|
565
|
+
break_types = [False]
|
566
|
+
if limits is None:
|
567
|
+
limits = [0.5]
|
568
|
+
return {"colors": colors, "breakTypes": break_types, "limits": limits, "limitType": limit_type}
|
569
|
+
|
570
|
+
|
571
|
+
def static_content_url_def(url: str = None):
|
572
|
+
if url is None:
|
573
|
+
return {}
|
574
|
+
else:
|
575
|
+
return {"qUrl": url}
|
576
|
+
|
577
|
+
|
578
|
+
def story_properties(title: str = "", description: str = "", extends_id: str = "", state_name: str = "", rank: int = 0,
|
579
|
+
thumbnail_url: str = None):
|
580
|
+
|
581
|
+
info = nx_info(obj_type="story")
|
582
|
+
prop_def = {"title": title, "description": description}
|
583
|
+
if thumbnail_url is None:
|
584
|
+
thumbnail = {"qStaticContentUrlDef": static_content_url_def()}
|
585
|
+
else:
|
586
|
+
thumbnail = {"qStaticContentUrlDef": static_content_url_def(url=thumbnail_url)}
|
587
|
+
child_list_def = {"qData": {"title": "/title", "rank": "/rank"}}
|
588
|
+
|
589
|
+
return {
|
590
|
+
"qInfo": info, "qExtendsId": extends_id, "qMetaDef": prop_def, "qStateName": state_name, "rank": rank,
|
591
|
+
"thumbnail": thumbnail, "qChildListDef": child_list_def
|
592
|
+
}
|
593
|
+
|
594
|
+
|
595
|
+
def slide_properties(extends_id: str = "", prop_def: dict = None, state_name: str = ""):
|
596
|
+
|
597
|
+
if prop_def is None:
|
598
|
+
prop_def = {}
|
599
|
+
info = nx_info(obj_type="slide")
|
600
|
+
child_list_def = {"qData": {"title": "/title", "sheetId": "/sheetId", "ratio": "/ratio", "position": "/position",
|
601
|
+
"dataPath": "/dataPath", "srcPath": "/srcPath", "visualization": "/visualization",
|
602
|
+
"visualizationType": "/visualizationType", "style": "/style"}}
|
603
|
+
|
604
|
+
return {
|
605
|
+
"qInfo": info, "qExtendsId": extends_id, "qMetaDef": prop_def, "qStateName": state_name, "qChildListDef": child_list_def
|
606
|
+
}
|
607
|
+
|
608
|
+
|
609
|
+
def slideitem_text_properties(ratio: bool = True, position_top: str = "3.69985%", position_left: str = "31.25000%",
|
610
|
+
position_width: str = "39.57903%", position_height: str = "11.28086%",
|
611
|
+
position_z_index: int = 1, position_right: str = "auto",
|
612
|
+
visualization_type: str = "", style_color: str = "#6E6E6E",
|
613
|
+
style_text: str = ""):
|
614
|
+
|
615
|
+
position = {"top": position_top, "left": position_left, "width": position_width, "height": position_height,
|
616
|
+
"z-index": position_z_index, "right": position_right}
|
617
|
+
info = nx_info(obj_type="slideitem")
|
618
|
+
|
619
|
+
return {
|
620
|
+
"qInfo": info, "qExtendsId": "", "qMetaDef": {}, "qStateName": "",
|
621
|
+
"qEmbeddedSnapshotDef": {}, "title": "", "sheetId": "", "ratio": ratio,
|
622
|
+
"position": position, "visualization": "text", "visualizationType": visualization_type,
|
623
|
+
"style": {"color": style_color, "text": style_text}
|
624
|
+
}
|
625
|
+
|
626
|
+
|
627
|
+
def slideitem_shape_properties(ratio: bool = True, position_top: str = "3.69985%", position_left: str = "31.25000%",
|
628
|
+
position_width: str = "39.57903%", position_height: str = "11.28086%",
|
629
|
+
position_z_index: int = 1, position_right: str = "auto",
|
630
|
+
visualization_type: str = "", style_color: str = "#000000"):
|
631
|
+
|
632
|
+
position = {"top": position_top, "left": position_left, "width": position_width, "height": position_height,
|
633
|
+
"z-index": position_z_index, "right": position_right}
|
634
|
+
info = nx_info(obj_type="slideitem")
|
635
|
+
|
636
|
+
return {
|
637
|
+
"qInfo": info, "qExtendsId": "", "qMetaDef": {}, "qStateName": "",
|
638
|
+
"qEmbeddedSnapshotDef": {}, "title": "", "sheetId": "", "ratio": ratio,
|
639
|
+
"position": position, "dataPath": "../resources/img/storytelling/shapes/" + visualization_type + ".svg",
|
640
|
+
"visualization": "shape", "visualizationType": visualization_type,
|
641
|
+
"style": {"color": style_color, "colorPaletteIndex": -1}
|
642
|
+
}
|
643
|
+
|
644
|
+
|
645
|
+
def slideitem_snapshot_properties(snapshot_id: str, visualization_type: str, ratio: bool = True,
|
646
|
+
position_top: str = "14.81481%", position_left: str = "2.08333%",
|
647
|
+
position_width: str = "95.83334%", position_height: str = "81.4814875%",
|
648
|
+
position_z_index: int = 1):
|
649
|
+
|
650
|
+
position = {"top": position_top, "left": position_left, "width": position_width, "height": position_height,
|
651
|
+
"z-index": position_z_index}
|
652
|
+
info = nx_info(obj_type="slideitem")
|
653
|
+
|
654
|
+
return {
|
655
|
+
"qInfo": info, "qExtendsId": "", "qMetaDef": {}, "qStateName": "", "qEmbeddedSnapshotDef": {}, "title": "",
|
656
|
+
"sheetId": "", "ratio": ratio, "position": position, "visualization": "snapshot",
|
657
|
+
"visualizationType": visualization_type, "style": {"id": snapshot_id}
|
658
|
+
}
|
659
|
+
|
660
|
+
|
661
|
+
def nx_get_bookmark_options(types: list, data: dict = None):
|
662
|
+
if data is None:
|
663
|
+
data = {}
|
664
|
+
return {
|
665
|
+
"qTypes": types, "qData": data
|
666
|
+
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: qe-api-client
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.9.0
|
4
4
|
Summary: Python client for the Qlik Engine JSON API
|
5
5
|
Home-page: https://github.com/lr-bicc/qe-api-client
|
6
6
|
Author: Rumen Vasilev
|
@@ -11,8 +11,10 @@ Classifier: Operating System :: OS Independent
|
|
11
11
|
Requires-Python: >=3.6
|
12
12
|
Description-Content-Type: text/markdown
|
13
13
|
License-File: LICENSE
|
14
|
-
Requires-Dist: websocket-client>=0.
|
14
|
+
Requires-Dist: websocket-client>=1.0.0
|
15
15
|
Requires-Dist: pandas>=2.2.0
|
16
|
+
Requires-Dist: numpy>=2.0.0
|
17
|
+
Requires-Dist: uuid>=1.0
|
16
18
|
Dynamic: author
|
17
19
|
Dynamic: author-email
|
18
20
|
Dynamic: classifier
|
@@ -1,17 +1,17 @@
|
|
1
1
|
qe_api_client/__init__.py,sha256=bypB4CIjpHtf5Pu_NwtJajC69zqQD7qB9jo8cCX0B54,23
|
2
|
-
qe_api_client/engine.py,sha256=
|
2
|
+
qe_api_client/engine.py,sha256=ErLb7KXpnH6UC7jNvZWdkW2_aeW7GCmvH8IzTcCDj0Q,68103
|
3
3
|
qe_api_client/engine_communicator.py,sha256=q6x7ix2Ev8yGmTTm7cf1vHcidOihKM0HjDXeJ-dZYjk,1133
|
4
|
-
qe_api_client/structs.py,sha256=
|
4
|
+
qe_api_client/structs.py,sha256=iZRy54jDyAk8ZD4rtrKxefnBcXcB1aRE0oxpOxoYcDM,28078
|
5
5
|
qe_api_client/api_classes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
|
-
qe_api_client/api_classes/engine_app_api.py,sha256=
|
6
|
+
qe_api_client/api_classes/engine_app_api.py,sha256=umVY3jtNyk4am_9XH1yAbng2BRGAF-sg_JSssbXcF5M,39962
|
7
7
|
qe_api_client/api_classes/engine_field_api.py,sha256=zCLIR7rmxqwIrJYK_-uHVEhMvBcEP2qofuX8ZPygqCA,5479
|
8
8
|
qe_api_client/api_classes/engine_generic_dimension_api.py,sha256=oSZoRT-j4hsCVnUm1OSg7XZPWXhUzFLY_53kM0KwPHs,2122
|
9
9
|
qe_api_client/api_classes/engine_generic_measure_api.py,sha256=uj4i_ykX9F9Dtk78fOidMBhzSP8vEucEfrB6MrLwgPI,1340
|
10
|
-
qe_api_client/api_classes/engine_generic_object_api.py,sha256=
|
10
|
+
qe_api_client/api_classes/engine_generic_object_api.py,sha256=_69Pf-Tp5vRB_LX76uQr8x03DstS_OOBVVw8h-9nwlA,12345
|
11
11
|
qe_api_client/api_classes/engine_generic_variable_api.py,sha256=sWXZpE-GLfcMijmfORnDNrJ6lmXX3x5TRHlkEu_i0BQ,2027
|
12
12
|
qe_api_client/api_classes/engine_global_api.py,sha256=G6QQHI36WOo7W25zg4Uz__gMSLC2ptNTvbBdElPzgZI,27535
|
13
|
-
qe_api_client-2.
|
14
|
-
qe_api_client-2.
|
15
|
-
qe_api_client-2.
|
16
|
-
qe_api_client-2.
|
17
|
-
qe_api_client-2.
|
13
|
+
qe_api_client-2.9.0.dist-info/licenses/LICENSE,sha256=2bm9uFabQZ3Ykb_SaSU_uUbAj2-htc6WJQmS_65qD00,1073
|
14
|
+
qe_api_client-2.9.0.dist-info/METADATA,sha256=g4aMmiMpkgRMvNe60MHsywPsl1dT8FLmmvH-VorJ9Wk,2437
|
15
|
+
qe_api_client-2.9.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
16
|
+
qe_api_client-2.9.0.dist-info/top_level.txt,sha256=m_43YagP8UtZgJHmZEfu0vlBNwt36M01-Qby2jByMnk,14
|
17
|
+
qe_api_client-2.9.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|