pyxecm 2.0.0__py3-none-any.whl → 2.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyxecm might be problematic. Click here for more details.
- pyxecm/__init__.py +2 -1
- pyxecm/avts.py +79 -33
- pyxecm/customizer/api/app.py +45 -796
- pyxecm/customizer/api/auth/__init__.py +1 -0
- pyxecm/customizer/api/{auth.py → auth/functions.py} +2 -64
- pyxecm/customizer/api/auth/router.py +78 -0
- pyxecm/customizer/api/common/__init__.py +1 -0
- pyxecm/customizer/api/common/functions.py +47 -0
- pyxecm/customizer/api/{metrics.py → common/metrics.py} +1 -1
- pyxecm/customizer/api/common/models.py +21 -0
- pyxecm/customizer/api/{payload_list.py → common/payload_list.py} +6 -1
- pyxecm/customizer/api/common/router.py +72 -0
- pyxecm/customizer/api/settings.py +25 -0
- pyxecm/customizer/api/terminal/__init__.py +1 -0
- pyxecm/customizer/api/terminal/router.py +87 -0
- pyxecm/customizer/api/v1_csai/__init__.py +1 -0
- pyxecm/customizer/api/v1_csai/router.py +87 -0
- pyxecm/customizer/api/v1_maintenance/__init__.py +1 -0
- pyxecm/customizer/api/v1_maintenance/functions.py +100 -0
- pyxecm/customizer/api/v1_maintenance/models.py +12 -0
- pyxecm/customizer/api/v1_maintenance/router.py +76 -0
- pyxecm/customizer/api/v1_otcs/__init__.py +1 -0
- pyxecm/customizer/api/v1_otcs/functions.py +61 -0
- pyxecm/customizer/api/v1_otcs/router.py +179 -0
- pyxecm/customizer/api/v1_payload/__init__.py +1 -0
- pyxecm/customizer/api/v1_payload/functions.py +179 -0
- pyxecm/customizer/api/v1_payload/models.py +51 -0
- pyxecm/customizer/api/v1_payload/router.py +499 -0
- pyxecm/customizer/browser_automation.py +568 -326
- pyxecm/customizer/customizer.py +204 -430
- pyxecm/customizer/guidewire.py +907 -43
- pyxecm/customizer/k8s.py +243 -56
- pyxecm/customizer/m365.py +104 -15
- pyxecm/customizer/payload.py +1943 -885
- pyxecm/customizer/pht.py +19 -2
- pyxecm/customizer/servicenow.py +22 -5
- pyxecm/customizer/settings.py +9 -6
- pyxecm/helper/xml.py +69 -0
- pyxecm/otac.py +1 -1
- pyxecm/otawp.py +2104 -1535
- pyxecm/otca.py +569 -0
- pyxecm/otcs.py +201 -37
- pyxecm/otds.py +35 -13
- {pyxecm-2.0.0.dist-info → pyxecm-2.0.1.dist-info}/METADATA +6 -29
- pyxecm-2.0.1.dist-info/RECORD +76 -0
- {pyxecm-2.0.0.dist-info → pyxecm-2.0.1.dist-info}/WHEEL +1 -1
- pyxecm-2.0.0.dist-info/RECORD +0 -54
- /pyxecm/customizer/api/{models.py → auth/models.py} +0 -0
- {pyxecm-2.0.0.dist-info → pyxecm-2.0.1.dist-info}/licenses/LICENSE +0 -0
- {pyxecm-2.0.0.dist-info → pyxecm-2.0.1.dist-info}/top_level.txt +0 -0
pyxecm/__init__.py
CHANGED
|
@@ -4,10 +4,11 @@ from .avts import AVTS
|
|
|
4
4
|
from .coreshare import CoreShare
|
|
5
5
|
from .otac import OTAC
|
|
6
6
|
from .otawp import OTAWP
|
|
7
|
+
from .otca import OTCA
|
|
7
8
|
from .otcs import OTCS
|
|
8
9
|
from .otds import OTDS
|
|
9
10
|
from .otiv import OTIV
|
|
10
11
|
from .otmm import OTMM
|
|
11
12
|
from .otpd import OTPD
|
|
12
13
|
|
|
13
|
-
__all__ = ["AVTS", "OTAC", "OTAWP", "OTCS", "OTDS", "OTIV", "OTMM", "OTPD", "CoreShare"]
|
|
14
|
+
__all__ = ["AVTS", "OTAC", "OTAWP", "OTCA", "OTCS", "OTDS", "OTIV", "OTMM", "OTPD", "CoreShare"]
|
pyxecm/avts.py
CHANGED
|
@@ -10,18 +10,35 @@ import base64
|
|
|
10
10
|
import json
|
|
11
11
|
import logging
|
|
12
12
|
import os
|
|
13
|
+
import platform
|
|
14
|
+
import sys
|
|
13
15
|
import time
|
|
16
|
+
from importlib.metadata import version
|
|
14
17
|
|
|
15
18
|
import requests
|
|
16
19
|
|
|
17
|
-
|
|
20
|
+
APP_NAME = "pyxecm"
|
|
21
|
+
APP_VERSION = version("pyxecm")
|
|
22
|
+
MODULE_NAME = APP_NAME + ".avts"
|
|
18
23
|
|
|
19
|
-
|
|
24
|
+
PYTHON_VERSION = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
|
|
25
|
+
OS_INFO = f"{platform.system()} {platform.release()}"
|
|
26
|
+
ARCH_INFO = platform.machine()
|
|
27
|
+
REQUESTS_VERSION = requests.__version__
|
|
28
|
+
|
|
29
|
+
USER_AGENT = (
|
|
30
|
+
f"{APP_NAME}/{APP_VERSION} ({MODULE_NAME}/{APP_VERSION}; "
|
|
31
|
+
f"Python/{PYTHON_VERSION}; {OS_INFO}; {ARCH_INFO}; Requests/{REQUESTS_VERSION})"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
REQUEST_HEADERS = {"User-Agent": USER_AGENT, "accept": "application/json", "Content-Type": "application/json"}
|
|
20
35
|
|
|
21
36
|
REQUEST_TIMEOUT = 60
|
|
22
37
|
REQUEST_RETRY_DELAY = 20
|
|
23
38
|
REQUEST_MAX_RETRIES = 2
|
|
24
39
|
|
|
40
|
+
default_logger = logging.getLogger(MODULE_NAME)
|
|
41
|
+
|
|
25
42
|
|
|
26
43
|
class AVTS:
|
|
27
44
|
"""Configure and interact with Aviator Search REST API."""
|
|
@@ -33,19 +50,17 @@ class AVTS:
|
|
|
33
50
|
|
|
34
51
|
def __init__(
|
|
35
52
|
self,
|
|
36
|
-
otds_url: str,
|
|
37
53
|
client_id: str,
|
|
38
54
|
client_secret: str,
|
|
39
55
|
base_url: str,
|
|
40
56
|
username: str,
|
|
41
57
|
password: str,
|
|
58
|
+
otds_url: str,
|
|
42
59
|
logger: logging.Logger = default_logger,
|
|
43
60
|
) -> None:
|
|
44
|
-
"""Initialize the AVTS object.
|
|
61
|
+
"""Initialize the Aviator Search (AVTS) object.
|
|
45
62
|
|
|
46
63
|
Args:
|
|
47
|
-
otds_url (str):
|
|
48
|
-
The URL of the OTDS Server used by Aviator Search.
|
|
49
64
|
client_id (str):
|
|
50
65
|
The client ID for the Aviator Search oAuth client.
|
|
51
66
|
client_secret (str):
|
|
@@ -56,6 +71,8 @@ class AVTS:
|
|
|
56
71
|
User with administrative permissions in Aviator Search.
|
|
57
72
|
password (str):
|
|
58
73
|
Password of the user with administrative permissions in Aviator Search.
|
|
74
|
+
otds_url (str):
|
|
75
|
+
The URL of the OTDS Server used by Aviator Search.
|
|
59
76
|
logger (logging.Logger, optional):
|
|
60
77
|
The logging object to use for all log messages. Defaults to default_logger.
|
|
61
78
|
|
|
@@ -69,15 +86,16 @@ class AVTS:
|
|
|
69
86
|
avts_config = {}
|
|
70
87
|
|
|
71
88
|
# Store the credentials and parameters in a config dictionary:
|
|
72
|
-
avts_config["otdsUrl"] = otds_url
|
|
73
89
|
avts_config["clientId"] = client_id
|
|
74
90
|
avts_config["clientSecret"] = client_secret
|
|
75
91
|
avts_config["baseUrl"] = base_url
|
|
76
92
|
avts_config["username"] = username
|
|
77
93
|
avts_config["password"] = password
|
|
94
|
+
avts_config["otdsUrl"] = otds_url
|
|
78
95
|
|
|
79
96
|
avts_config["tokenUrl"] = avts_config["otdsUrl"] + "/otdsws/oauth2/token"
|
|
80
97
|
avts_config["repoUrl"] = avts_config["baseUrl"] + "/aviator-gateway/avts-api/admin/v1/repo"
|
|
98
|
+
avts_config["questionsUrl"] = avts_config["baseUrl"] + "/aviator-gateway/avts-api/search/v1/questions"
|
|
81
99
|
|
|
82
100
|
self._config = avts_config
|
|
83
101
|
self._accesstoken = None
|
|
@@ -136,7 +154,7 @@ class AVTS:
|
|
|
136
154
|
url: str,
|
|
137
155
|
method: str = "GET",
|
|
138
156
|
headers: dict | None = None,
|
|
139
|
-
data: dict | None = None,
|
|
157
|
+
data: dict | list | None = None,
|
|
140
158
|
json_data: dict | None = None,
|
|
141
159
|
files: dict | None = None,
|
|
142
160
|
timeout: int | None = REQUEST_TIMEOUT,
|
|
@@ -199,9 +217,17 @@ class AVTS:
|
|
|
199
217
|
if success_message:
|
|
200
218
|
self.logger.debug(success_message)
|
|
201
219
|
return self.parse_request_response(response)
|
|
220
|
+
elif (
|
|
221
|
+
response.status_code == 500
|
|
222
|
+
and "Cannot modify configuration" in response.text
|
|
223
|
+
and "while the Processor is running" in response.text
|
|
224
|
+
):
|
|
225
|
+
self.logger.warning("Another operation is already running. Waiting 5 seconds to retry...")
|
|
226
|
+
time.sleep(5)
|
|
227
|
+
retries += 1
|
|
202
228
|
# Check if Session has expired - then re-authenticate and try once more
|
|
203
229
|
elif response.status_code == 401 and retries == 0:
|
|
204
|
-
self.logger.
|
|
230
|
+
self.logger.info("Session has expired - try to re-authenticate...")
|
|
205
231
|
self.authenticate()
|
|
206
232
|
retries += 1
|
|
207
233
|
else:
|
|
@@ -289,7 +315,7 @@ class AVTS:
|
|
|
289
315
|
the vars() built-in method.
|
|
290
316
|
|
|
291
317
|
Args:
|
|
292
|
-
response_object (
|
|
318
|
+
response_object (requests.Response):
|
|
293
319
|
This is reponse object delivered by the request call.
|
|
294
320
|
additional_error_message (str, optional):
|
|
295
321
|
Use a more specific error message in case of an error.
|
|
@@ -349,8 +375,8 @@ class AVTS:
|
|
|
349
375
|
}
|
|
350
376
|
request_payload = {
|
|
351
377
|
"client_id": self.config()["clientId"],
|
|
352
|
-
"grant_type": "password",
|
|
353
378
|
"client_secret": self.config()["clientSecret"],
|
|
379
|
+
"grant_type": "password",
|
|
354
380
|
"username": self.config()["username"],
|
|
355
381
|
"password": self.config()["password"],
|
|
356
382
|
"scope": "otds:roles",
|
|
@@ -362,7 +388,7 @@ class AVTS:
|
|
|
362
388
|
headers=request_header,
|
|
363
389
|
data=request_payload,
|
|
364
390
|
timeout=None,
|
|
365
|
-
failure_message="Failed to authenticate to OTDS with username -> {} and client_id -> {}".format(
|
|
391
|
+
failure_message="Failed to authenticate to OTDS with username -> '{}' and client_id -> {}".format(
|
|
366
392
|
self.config()["username"],
|
|
367
393
|
self.config()["clientId"],
|
|
368
394
|
),
|
|
@@ -399,8 +425,6 @@ class AVTS:
|
|
|
399
425
|
The REST API URL of Content Server.
|
|
400
426
|
node_id (int):
|
|
401
427
|
Root Node ID for crawling
|
|
402
|
-
version (str, optional):
|
|
403
|
-
TODO: The version number of ???
|
|
404
428
|
|
|
405
429
|
Returns:
|
|
406
430
|
dict | None:
|
|
@@ -593,7 +617,7 @@ class AVTS:
|
|
|
593
617
|
)
|
|
594
618
|
|
|
595
619
|
if response is None:
|
|
596
|
-
self.logger.error("Failed to create repository -> %s (%s)", name, node_id)
|
|
620
|
+
self.logger.error("Failed to create repository -> %s (%s)!", name, node_id)
|
|
597
621
|
|
|
598
622
|
return response
|
|
599
623
|
|
|
@@ -632,9 +656,6 @@ class AVTS:
|
|
|
632
656
|
Whether or not to index / crawl message replies.
|
|
633
657
|
index_user_chats (bool, optional):
|
|
634
658
|
Whether or not to index / crawl user chats.
|
|
635
|
-
version(str, optional): default 24.3.0
|
|
636
|
-
|
|
637
|
-
# TODO: add more params
|
|
638
659
|
|
|
639
660
|
Returns:
|
|
640
661
|
dict | None:
|
|
@@ -773,7 +794,7 @@ class AVTS:
|
|
|
773
794
|
"description": "",
|
|
774
795
|
"required": False,
|
|
775
796
|
"defaultValue": "false",
|
|
776
|
-
"value": "
|
|
797
|
+
"value": "false",
|
|
777
798
|
"visible": True,
|
|
778
799
|
"editable": True,
|
|
779
800
|
},
|
|
@@ -800,7 +821,7 @@ class AVTS:
|
|
|
800
821
|
"description": "",
|
|
801
822
|
"required": False,
|
|
802
823
|
"defaultValue": "",
|
|
803
|
-
"value": "
|
|
824
|
+
"value": "",
|
|
804
825
|
"visible": True,
|
|
805
826
|
"editable": True,
|
|
806
827
|
},
|
|
@@ -811,7 +832,7 @@ class AVTS:
|
|
|
811
832
|
"description": "",
|
|
812
833
|
"required": False,
|
|
813
834
|
"defaultValue": "",
|
|
814
|
-
"value": "
|
|
835
|
+
"value": "",
|
|
815
836
|
"visible": True,
|
|
816
837
|
"editable": True,
|
|
817
838
|
},
|
|
@@ -900,7 +921,7 @@ class AVTS:
|
|
|
900
921
|
)
|
|
901
922
|
|
|
902
923
|
if response is None:
|
|
903
|
-
self.logger.error("Failed to create repository -> %s", name)
|
|
924
|
+
self.logger.error("Failed to create repository -> '%s'", name)
|
|
904
925
|
return None
|
|
905
926
|
|
|
906
927
|
self.repo_admin_consent(response["id"])
|
|
@@ -951,8 +972,6 @@ class AVTS:
|
|
|
951
972
|
TODO: _description_. Defaults to "AVTS".
|
|
952
973
|
oauth2_sites_file (str, optional):
|
|
953
974
|
TODO: _description_. Defaults to "".
|
|
954
|
-
version (str, optional):
|
|
955
|
-
TODO: _description_. Defaults to "24.3.0".
|
|
956
975
|
|
|
957
976
|
Returns:
|
|
958
977
|
dict | None:
|
|
@@ -1142,7 +1161,7 @@ class AVTS:
|
|
|
1142
1161
|
"description": "",
|
|
1143
1162
|
"required": False,
|
|
1144
1163
|
"defaultValue": "false",
|
|
1145
|
-
"value": "
|
|
1164
|
+
"value": "false",
|
|
1146
1165
|
"visible": True,
|
|
1147
1166
|
"editable": True,
|
|
1148
1167
|
},
|
|
@@ -1169,7 +1188,7 @@ class AVTS:
|
|
|
1169
1188
|
"description": "",
|
|
1170
1189
|
"required": False,
|
|
1171
1190
|
"defaultValue": "",
|
|
1172
|
-
"value": "
|
|
1191
|
+
"value": "",
|
|
1173
1192
|
"visible": True,
|
|
1174
1193
|
"editable": True,
|
|
1175
1194
|
},
|
|
@@ -1180,7 +1199,7 @@ class AVTS:
|
|
|
1180
1199
|
"description": "",
|
|
1181
1200
|
"required": False,
|
|
1182
1201
|
"defaultValue": "",
|
|
1183
|
-
"value": "
|
|
1202
|
+
"value": "",
|
|
1184
1203
|
"visible": True,
|
|
1185
1204
|
"editable": True,
|
|
1186
1205
|
},
|
|
@@ -1284,7 +1303,7 @@ class AVTS:
|
|
|
1284
1303
|
)
|
|
1285
1304
|
|
|
1286
1305
|
if response is None:
|
|
1287
|
-
self.logger.error("Failed to create repository -> %s", name)
|
|
1306
|
+
self.logger.error("Failed to create repository -> '%s'!", name)
|
|
1288
1307
|
return None
|
|
1289
1308
|
|
|
1290
1309
|
self.repo_admin_consent(response["id"])
|
|
@@ -1336,7 +1355,7 @@ class AVTS:
|
|
|
1336
1355
|
|
|
1337
1356
|
"""
|
|
1338
1357
|
|
|
1339
|
-
self.logger.info("Start crawling repository -> %s", repo_name)
|
|
1358
|
+
self.logger.info("Start crawling repository -> '%s'...", repo_name)
|
|
1340
1359
|
|
|
1341
1360
|
repo = self.get_repo_by_name(name=repo_name)
|
|
1342
1361
|
if repo is None:
|
|
@@ -1350,14 +1369,14 @@ class AVTS:
|
|
|
1350
1369
|
method="POST",
|
|
1351
1370
|
headers=request_header,
|
|
1352
1371
|
timeout=None,
|
|
1353
|
-
failure_message="Failed to start crawling repository -> '{}'".format(
|
|
1372
|
+
failure_message="Failed to start crawling repository -> '{}'!".format(
|
|
1354
1373
|
repo_name,
|
|
1355
1374
|
),
|
|
1356
1375
|
)
|
|
1357
1376
|
|
|
1358
1377
|
# end method definition
|
|
1359
1378
|
|
|
1360
|
-
def stop_crawling(self, repo_name: str) ->
|
|
1379
|
+
def stop_crawling(self, repo_name: str) -> dict | None:
|
|
1361
1380
|
"""Stop the crawling of a repository.
|
|
1362
1381
|
|
|
1363
1382
|
Args:
|
|
@@ -1365,7 +1384,7 @@ class AVTS:
|
|
|
1365
1384
|
The name of the repository.
|
|
1366
1385
|
|
|
1367
1386
|
Returns:
|
|
1368
|
-
|
|
1387
|
+
dict | None:
|
|
1369
1388
|
Parsed response object from the API or None in case of an error
|
|
1370
1389
|
|
|
1371
1390
|
"""
|
|
@@ -1382,7 +1401,7 @@ class AVTS:
|
|
|
1382
1401
|
method="POST",
|
|
1383
1402
|
headers=request_header,
|
|
1384
1403
|
timeout=None,
|
|
1385
|
-
failure_message="Failed to stop crawling repository -> '{}'".format(
|
|
1404
|
+
failure_message="Failed to stop crawling repository -> '{}'!".format(
|
|
1386
1405
|
repo_name,
|
|
1387
1406
|
),
|
|
1388
1407
|
)
|
|
@@ -1490,3 +1509,30 @@ class AVTS:
|
|
|
1490
1509
|
return bool(os.getenv("KUBERNETES_SERVICE_HOST") and os.getenv("KUBERNETES_SERVICE_PORT"))
|
|
1491
1510
|
|
|
1492
1511
|
# end method definition
|
|
1512
|
+
|
|
1513
|
+
def set_questions(self, questions: list) -> list | None:
|
|
1514
|
+
"""Get a list of all repositories.
|
|
1515
|
+
|
|
1516
|
+
Args:
|
|
1517
|
+
questions (list):
|
|
1518
|
+
List of proposed questions.
|
|
1519
|
+
|
|
1520
|
+
Returns:
|
|
1521
|
+
list | None:
|
|
1522
|
+
Parsed response object from the API listing all repositories or None in case of an error.
|
|
1523
|
+
|
|
1524
|
+
"""
|
|
1525
|
+
|
|
1526
|
+
request_header = self.request_header()
|
|
1527
|
+
request_url = self.config()["questionsUrl"]
|
|
1528
|
+
|
|
1529
|
+
return self.do_request(
|
|
1530
|
+
url=request_url,
|
|
1531
|
+
method="PUT",
|
|
1532
|
+
headers=request_header,
|
|
1533
|
+
data=json.dumps(questions),
|
|
1534
|
+
timeout=None,
|
|
1535
|
+
failure_message="Failed to set list of questions to ask",
|
|
1536
|
+
)
|
|
1537
|
+
|
|
1538
|
+
# end method definition
|