qe-api-client 2.7.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.
Files changed (32) hide show
  1. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/PKG-INFO +4 -2
  2. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_app_api.py +107 -47
  3. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_generic_object_api.py +63 -6
  4. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/qe_api_client/engine.py +301 -22
  5. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/qe_api_client/structs.py +128 -3
  6. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/qe_api_client.egg-info/PKG-INFO +4 -2
  7. qe_api_client-2.9.0/qe_api_client.egg-info/requires.txt +4 -0
  8. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/setup.py +5 -3
  9. qe_api_client-2.9.0/test/test.py +36 -0
  10. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/test/test_app_api.py +1 -1
  11. qe_api_client-2.7.0/qe_api_client.egg-info/requires.txt +0 -2
  12. qe_api_client-2.7.0/test/test.py +0 -43
  13. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/LICENSE +0 -0
  14. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/README.md +0 -0
  15. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/qe_api_client/__init__.py +0 -0
  16. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/__init__.py +0 -0
  17. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_field_api.py +0 -0
  18. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_generic_dimension_api.py +0 -0
  19. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_generic_measure_api.py +0 -0
  20. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_generic_variable_api.py +0 -0
  21. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/qe_api_client/api_classes/engine_global_api.py +0 -0
  22. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/qe_api_client/engine_communicator.py +0 -0
  23. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/qe_api_client.egg-info/SOURCES.txt +0 -0
  24. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/qe_api_client.egg-info/dependency_links.txt +0 -0
  25. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/qe_api_client.egg-info/top_level.txt +0 -0
  26. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/setup.cfg +0 -0
  27. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/test/test_api.py +0 -0
  28. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/test/test_chart_content.py +0 -0
  29. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/test/test_field_api.py +0 -0
  30. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/test/test_global_api.py +0 -0
  31. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/test/test_labs.py +0 -0
  32. {qe_api_client-2.7.0 → qe_api_client-2.9.0}/test/test_pyqlikengine.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qe-api-client
3
- Version: 2.7.0
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.47.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
@@ -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="/qHyperCubeDef", pages={}):
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": [pages]}})
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="/qHyperCubeDef", pages={}):
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": [pages]}})
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="/qHyperCubeDef", pages={}, max_no_cells=10000):
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": [pages], "qMaxNbrCells": max_no_cells}})
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"]