qe-api-client 2.8.0__tar.gz → 2.9.0__tar.gz
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-2.8.0 → qe_api_client-2.9.0}/PKG-INFO +1 -1
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_app_api.py +107 -47
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_generic_object_api.py +45 -6
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client/engine.py +249 -9
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client/structs.py +99 -1
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client.egg-info/PKG-INFO +1 -1
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/setup.py +1 -1
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/test/test_app_api.py +1 -1
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/LICENSE +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/README.md +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client/__init__.py +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/__init__.py +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_field_api.py +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_generic_dimension_api.py +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_generic_measure_api.py +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_generic_variable_api.py +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_global_api.py +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client/engine_communicator.py +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client.egg-info/SOURCES.txt +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client.egg-info/dependency_links.txt +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client.egg-info/requires.txt +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client.egg-info/top_level.txt +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/setup.cfg +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/test/test.py +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/test/test_api.py +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/test/test_chart_content.py +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/test/test_field_api.py +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/test/test_global_api.py +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/test/test_labs.py +0 -0
- {qe_api_client-2.8.0 → qe_api_client-2.9.0}/test/test_pyqlikengine.py +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:
|
{qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_generic_object_api.py
RENAMED
@@ -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"]
|
@@ -224,5 +224,44 @@ class EngineGenericObjectApi:
|
|
224
224
|
response = json.loads(self.engine_socket.send_call(self.engine_socket, msg))
|
225
225
|
try:
|
226
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"]
|
227
266
|
except KeyError:
|
228
267
|
return response["error"]
|
@@ -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:
|
@@ -451,6 +453,203 @@ class QixEngine:
|
|
451
453
|
return chart
|
452
454
|
|
453
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
|
+
|
454
653
|
def get_app_lineage_info(self, app_handle):
|
455
654
|
"""
|
456
655
|
Gets the lineage information of the app. The lineage information includes the LOAD and STORE statements from
|
@@ -500,19 +699,60 @@ class QixEngine:
|
|
500
699
|
|
501
700
|
Parameters:
|
502
701
|
obj : dict
|
503
|
-
The object containing the
|
702
|
+
The object containing the id.
|
504
703
|
|
505
704
|
Returns:
|
506
|
-
int: The
|
705
|
+
int: The id value.
|
507
706
|
|
508
707
|
Raises:
|
509
|
-
ValueError: If the
|
708
|
+
ValueError: If the id value is invalid.
|
510
709
|
"""
|
511
710
|
try:
|
512
711
|
return obj["qGenericId"]
|
513
712
|
except ValueError:
|
514
713
|
return "Bad id value in " + obj
|
515
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
|
+
|
516
756
|
def get_chart_data(self, app_handle, obj_id):
|
517
757
|
"""
|
518
758
|
Retrieves the data from a given chart object.
|
@@ -569,7 +809,7 @@ class QixEngine:
|
|
569
809
|
# Retrieves the hypercube data in a loop (because of limitation from 10.000 cells per call)
|
570
810
|
while no_of_rows > page * height:
|
571
811
|
nx_page = self.structs.nx_page(left=0, top=page * height, width=width, height=height)
|
572
|
-
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])[
|
573
813
|
'qDataPages'][0]['qMatrix']
|
574
814
|
data_values.extend(hc_data)
|
575
815
|
page += 1
|
@@ -613,7 +853,7 @@ class QixEngine:
|
|
613
853
|
|
614
854
|
col_headers = []
|
615
855
|
nx_page_top = self.structs.nx_page(left=0, top=0, width=width, height=1)
|
616
|
-
hc_top = self.egoa.get_hypercube_pivot_data(obj_handle, '/qHyperCubeDef', nx_page_top)['qDataPages'][0]['qTop']
|
856
|
+
hc_top = self.egoa.get_hypercube_pivot_data(handle=obj_handle, path='/qHyperCubeDef', pages=[nx_page_top])['qDataPages'][0]['qTop']
|
617
857
|
for top_node in hc_top:
|
618
858
|
col_headers.extend(get_column_paths(top_node))
|
619
859
|
|
@@ -627,13 +867,13 @@ class QixEngine:
|
|
627
867
|
nx_page = self.structs.nx_page(left=0, top=page * height, width=width, height=height)
|
628
868
|
|
629
869
|
# Retrieves the row headers for the pivot table
|
630
|
-
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])[
|
631
871
|
'qDataPages'][0]['qLeft']
|
632
872
|
for left_node in hc_left:
|
633
873
|
row_headers.extend(get_all_dimensions(left_node))
|
634
874
|
|
635
875
|
# Retrieves the data for the pivot table
|
636
|
-
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])[
|
637
877
|
'qDataPages'][0]['qData']
|
638
878
|
for row in hc_data:
|
639
879
|
data_values.append([cell['qText'] for cell in row])
|
@@ -654,7 +894,7 @@ class QixEngine:
|
|
654
894
|
elif obj_layout['qInfo']['qType'] in ['barchart'] and obj_layout['qHyperCube']['qStackedDataPages'] != []:
|
655
895
|
max_no_cells = no_of_columns * no_of_rows
|
656
896
|
nx_page = self.structs.nx_page(left=0, top=0, width=no_of_columns, height=no_of_rows)
|
657
|
-
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)[
|
658
898
|
'qDataPages'][0]['qData'][0]['qSubNodes']
|
659
899
|
|
660
900
|
# Transform the nested structure into a flat DataFrame
|
@@ -740,7 +980,7 @@ class QixEngine:
|
|
740
980
|
# Retrieves the hypercube data in a loop (because of limitation from 10.000 cells per call)
|
741
981
|
while no_of_rows > page * height:
|
742
982
|
nx_page = self.structs.nx_page(left=0, top=page * height, width=width, height=height)
|
743
|
-
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']
|
744
984
|
data_values.extend(hc_data)
|
745
985
|
page += 1
|
746
986
|
|
@@ -565,4 +565,102 @@ def gradient(colors: list = None, break_types: list = None, limits: list = None,
|
|
565
565
|
break_types = [False]
|
566
566
|
if limits is None:
|
567
567
|
limits = [0.5]
|
568
|
-
return {"colors": colors, "breakTypes": break_types, "limits": limits, "limitType": limit_type}
|
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
|
+
}
|
@@ -64,7 +64,7 @@ class TestAppApi(unittest.TestCase):
|
|
64
64
|
|
65
65
|
# Call the get_hypercube_data to get the resulting json object,
|
66
66
|
# using the handle and nx page as paramters
|
67
|
-
hc_data = self.qixe.egoa.get_hypercube_data(hc_handle,"/qHyperCubeDef",nx_page)
|
67
|
+
hc_data = self.qixe.egoa.get_hypercube_data(handle=hc_handle,path="/qHyperCubeDef",pages=[nx_page])
|
68
68
|
|
69
69
|
self.assertTrue(type(hc_data is {}),"Unexpected type of hypercube data")
|
70
70
|
first_element_number = hc_data["qDataPages"][0]["qMatrix"][0][0]["qElemNumber"] # NOQA
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_generic_measure_api.py
RENAMED
File without changes
|
{qe_api_client-2.8.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_generic_variable_api.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|