pyxecm 1.6__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyxecm might be problematic. Click here for more details.
- pyxecm/__init__.py +6 -4
- pyxecm/avts.py +673 -246
- pyxecm/coreshare.py +686 -467
- pyxecm/customizer/__init__.py +16 -4
- pyxecm/customizer/__main__.py +58 -0
- pyxecm/customizer/api/__init__.py +5 -0
- pyxecm/customizer/api/__main__.py +6 -0
- pyxecm/customizer/api/app.py +914 -0
- pyxecm/customizer/api/auth.py +154 -0
- pyxecm/customizer/api/metrics.py +92 -0
- pyxecm/customizer/api/models.py +13 -0
- pyxecm/customizer/api/payload_list.py +865 -0
- pyxecm/customizer/api/settings.py +103 -0
- pyxecm/customizer/browser_automation.py +332 -139
- pyxecm/customizer/customizer.py +1007 -1130
- pyxecm/customizer/exceptions.py +35 -0
- pyxecm/customizer/guidewire.py +322 -0
- pyxecm/customizer/k8s.py +713 -378
- pyxecm/customizer/log.py +107 -0
- pyxecm/customizer/m365.py +2867 -909
- pyxecm/customizer/nhc.py +1169 -0
- pyxecm/customizer/openapi.py +258 -0
- pyxecm/customizer/payload.py +16817 -7467
- pyxecm/customizer/pht.py +699 -285
- pyxecm/customizer/salesforce.py +516 -342
- pyxecm/customizer/sap.py +58 -41
- pyxecm/customizer/servicenow.py +593 -371
- pyxecm/customizer/settings.py +442 -0
- pyxecm/customizer/successfactors.py +408 -346
- pyxecm/customizer/translate.py +83 -48
- pyxecm/helper/__init__.py +5 -2
- pyxecm/helper/assoc.py +83 -43
- pyxecm/helper/data.py +2406 -870
- pyxecm/helper/logadapter.py +27 -0
- pyxecm/helper/web.py +229 -101
- pyxecm/helper/xml.py +527 -171
- pyxecm/maintenance_page/__init__.py +5 -0
- pyxecm/maintenance_page/__main__.py +6 -0
- pyxecm/maintenance_page/app.py +51 -0
- pyxecm/maintenance_page/settings.py +28 -0
- pyxecm/maintenance_page/static/favicon.avif +0 -0
- pyxecm/maintenance_page/templates/maintenance.html +165 -0
- pyxecm/otac.py +234 -140
- pyxecm/otawp.py +1436 -557
- pyxecm/otcs.py +7716 -3161
- pyxecm/otds.py +2150 -919
- pyxecm/otiv.py +36 -21
- pyxecm/otmm.py +1272 -325
- pyxecm/otpd.py +231 -127
- pyxecm-2.0.0.dist-info/METADATA +145 -0
- pyxecm-2.0.0.dist-info/RECORD +54 -0
- {pyxecm-1.6.dist-info → pyxecm-2.0.0.dist-info}/WHEEL +1 -1
- pyxecm-1.6.dist-info/METADATA +0 -53
- pyxecm-1.6.dist-info/RECORD +0 -32
- {pyxecm-1.6.dist-info → pyxecm-2.0.0.dist-info/licenses}/LICENSE +0 -0
- {pyxecm-1.6.dist-info → pyxecm-2.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Definition for all custom exception."""
|
|
2
|
+
|
|
3
|
+
__author__ = "Dr. Marc Diefenbruch"
|
|
4
|
+
__copyright__ = "Copyright (C) 2024-2025, OpenText"
|
|
5
|
+
__credits__ = ["Kai-Philip Gatzweiler"]
|
|
6
|
+
__maintainer__ = "Dr. Marc Diefenbruch"
|
|
7
|
+
__email__ = "mdiefenb@opentext.com"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class StopOnError(Exception):
|
|
11
|
+
"""Custom exception to stop customizer on error."""
|
|
12
|
+
|
|
13
|
+
def __init__(self, message: str) -> None:
|
|
14
|
+
"""Initialize the StopOnErrorException with a message.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
message (str):
|
|
18
|
+
The error message.
|
|
19
|
+
|
|
20
|
+
"""
|
|
21
|
+
super().__init__(message)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class PayloadImportError(Exception):
|
|
25
|
+
"""Custom exception if the import of the payload failed."""
|
|
26
|
+
|
|
27
|
+
def __init__(self, message: str) -> None:
|
|
28
|
+
"""Initialize the PayloadImportException with a message.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
message (str):
|
|
32
|
+
The error message.
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
super().__init__(message)
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
"""Guidewire Module to interact with the Guidewire REST API ("Cloud API").
|
|
2
|
+
|
|
3
|
+
See: https://www.guidewire.com/de/developers/apis/cloud-apis
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
__author__ = "Dr. Marc Diefenbruch"
|
|
7
|
+
__copyright__ = "Copyright (C) 2024-2025, OpenText"
|
|
8
|
+
__credits__ = ["Kai-Philip Gatzweiler"]
|
|
9
|
+
__maintainer__ = "Dr. Marc Diefenbruch"
|
|
10
|
+
__email__ = "mdiefenb@opentext.com"
|
|
11
|
+
|
|
12
|
+
import logging
|
|
13
|
+
|
|
14
|
+
import requests
|
|
15
|
+
|
|
16
|
+
default_logger = logging.getLogger("pyxecm.customizer.guidewire")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Guidewire:
|
|
20
|
+
"""Class Guidewire is used to retrieve and automate stettings and objects in Guidewire."""
|
|
21
|
+
|
|
22
|
+
logger: logging.Logger = default_logger
|
|
23
|
+
_config: dict
|
|
24
|
+
_scope = None
|
|
25
|
+
_token = None
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
base_url: str,
|
|
30
|
+
client_id: str = "",
|
|
31
|
+
client_secret: str = "",
|
|
32
|
+
username: str = "",
|
|
33
|
+
password: str = "",
|
|
34
|
+
scope: str = "",
|
|
35
|
+
) -> None:
|
|
36
|
+
"""Initialize the Guidewire API client.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
base_url (str):
|
|
40
|
+
The base URL of the Guidewire Cloud API.
|
|
41
|
+
client_id (str):
|
|
42
|
+
The Client ID for authentication (optional, required for client credential flow).
|
|
43
|
+
client_secret (str):
|
|
44
|
+
The Client Secret for authentication (optional, required for client credential flow).
|
|
45
|
+
username (str):
|
|
46
|
+
The username for authentication (optional, required for password-based authentication).
|
|
47
|
+
password (str):
|
|
48
|
+
The password for authentication (optional, required for password-based authentication).
|
|
49
|
+
scope (str):
|
|
50
|
+
The OAuth2 scope (optional).
|
|
51
|
+
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
self._scope = scope
|
|
55
|
+
self._token = None
|
|
56
|
+
|
|
57
|
+
guidewire_config = {}
|
|
58
|
+
# Store the credentials and parameters in a config dictionary:
|
|
59
|
+
guidewire_config["clientId"] = client_id
|
|
60
|
+
guidewire_config["clientSecret"] = client_secret
|
|
61
|
+
guidewire_config["username"] = username
|
|
62
|
+
guidewire_config["password"] = password
|
|
63
|
+
guidewire_config["baseUrl"] = base_url.rstrip("/")
|
|
64
|
+
guidewire_config["cloudAPIUrl"] = guidewire_config["baseUrl"] + "/api/v1"
|
|
65
|
+
guidewire_config["tokenUrl"] = guidewire_config["cloudAPIUrl"] + "/oauth2/token"
|
|
66
|
+
|
|
67
|
+
self._config = guidewire_config
|
|
68
|
+
|
|
69
|
+
# end method definition
|
|
70
|
+
|
|
71
|
+
def config(self) -> dict:
|
|
72
|
+
"""Return the configuration dictionary.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
dict:
|
|
76
|
+
The configuration dictionary with all settings.
|
|
77
|
+
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
return self._config
|
|
81
|
+
|
|
82
|
+
# end method definition
|
|
83
|
+
|
|
84
|
+
def authenticate(self) -> bool:
|
|
85
|
+
"""Authenticate with the Guidewire API using either client credentials or username/password.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
bool:
|
|
89
|
+
True if authentication is successful, False otherwise.
|
|
90
|
+
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
request_url = self.config()["tokenUrl"]
|
|
94
|
+
|
|
95
|
+
if self.config()["clientId"] and self.config()["clientSecret"]:
|
|
96
|
+
auth_data = {
|
|
97
|
+
"grant_type": "client_credentials",
|
|
98
|
+
"client_id": self.config()["clientId"],
|
|
99
|
+
"client_secret": self.config()["clientSecret"],
|
|
100
|
+
}
|
|
101
|
+
elif self.config()["username"] and self.config()["password"]:
|
|
102
|
+
auth_data = {
|
|
103
|
+
"grant_type": "password",
|
|
104
|
+
"username": self.config()["username"],
|
|
105
|
+
"password": self.config()["password"],
|
|
106
|
+
"client_id": self.config()["clientId"], # Required for some OAuth2 flows
|
|
107
|
+
"client_secret": self.config()["clientSecret"], # Required for some OAuth2 flows
|
|
108
|
+
}
|
|
109
|
+
else:
|
|
110
|
+
self.logger.error("Authentication requires either client credentials or username/password.")
|
|
111
|
+
return False
|
|
112
|
+
|
|
113
|
+
if self._scope:
|
|
114
|
+
auth_data["scope"] = self._scope
|
|
115
|
+
|
|
116
|
+
response = requests.post(request_url, data=auth_data)
|
|
117
|
+
if response.status_code == 200:
|
|
118
|
+
self.token = response.json().get("access_token")
|
|
119
|
+
return True
|
|
120
|
+
|
|
121
|
+
return False
|
|
122
|
+
|
|
123
|
+
# end method definition
|
|
124
|
+
|
|
125
|
+
def request_headers(self) -> dict:
|
|
126
|
+
"""Generate request headers including authentication token.
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
dict:
|
|
130
|
+
A dictionary containing authorization headers.
|
|
131
|
+
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
if not self._token:
|
|
135
|
+
self.logger.error("Authentication required. Call authenticate() first.")
|
|
136
|
+
return None
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
"Authorization": "Bearer {}".format(self._token),
|
|
140
|
+
"Content-Type": "application/json",
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
# end method definition
|
|
144
|
+
|
|
145
|
+
def do_request(self, method: str, endpoint: str, data: dict | None = None, params: dict | None = None) -> dict:
|
|
146
|
+
"""Send a request to the Guidewire REST API.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
method (str):
|
|
150
|
+
The HTTP method to use (GET, POST, PUT, DELETE).
|
|
151
|
+
endpoint (str):
|
|
152
|
+
The API endpoint to call.
|
|
153
|
+
data (dict):
|
|
154
|
+
The request payload (if applicable).
|
|
155
|
+
params (dict):
|
|
156
|
+
The URL parameters (if applicable).
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
dict:
|
|
160
|
+
Response as a dictionary.
|
|
161
|
+
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
request_url = "{}{}".format(self.base_url, endpoint)
|
|
165
|
+
response = requests.request(method, request_url, headers=self._headers(), json=data, params=params)
|
|
166
|
+
|
|
167
|
+
return response.json() if response.content else {}
|
|
168
|
+
|
|
169
|
+
# end method definition
|
|
170
|
+
|
|
171
|
+
def get_accounts(self) -> dict:
|
|
172
|
+
"""Retrieve a list of accounts.
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
dict: JSON response containing account data.
|
|
176
|
+
|
|
177
|
+
"""
|
|
178
|
+
|
|
179
|
+
return self.do_request("GET", "/accounts")
|
|
180
|
+
|
|
181
|
+
# end method definition
|
|
182
|
+
|
|
183
|
+
def get_account(self, account_id: str) -> dict:
|
|
184
|
+
"""Retrieve details of a specific account.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
account_id: The unique identifier of the account.
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
dict: JSON response containing account details.
|
|
191
|
+
|
|
192
|
+
"""
|
|
193
|
+
|
|
194
|
+
return self.do_request("GET", "/accounts/{}".format(account_id))
|
|
195
|
+
|
|
196
|
+
# end method definition
|
|
197
|
+
|
|
198
|
+
def add_account(self, account_data: dict) -> dict:
|
|
199
|
+
"""Create a new account.
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
account_data: Dictionary containing account information.
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
dict: JSON response with created account details.
|
|
206
|
+
|
|
207
|
+
"""
|
|
208
|
+
|
|
209
|
+
return self.do_request("POST", "/accounts", data=account_data)
|
|
210
|
+
|
|
211
|
+
# end method definition
|
|
212
|
+
|
|
213
|
+
def update_account(self, account_id: str, account_data: dict) -> dict:
|
|
214
|
+
"""Update an existing account.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
account_id: The unique identifier of the account.
|
|
218
|
+
account_data: Dictionary containing updated account information.
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
dict: JSON response with updated account details.
|
|
222
|
+
|
|
223
|
+
"""
|
|
224
|
+
|
|
225
|
+
return self.do_request("PUT", "/accounts/{}".format(account_id), data=account_data)
|
|
226
|
+
|
|
227
|
+
# end method definition
|
|
228
|
+
|
|
229
|
+
def delete_account(self, account_id: str) -> dict:
|
|
230
|
+
"""Delete an account.
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
account_id: The unique identifier of the account to delete.
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
dict: JSON response indicating deletion success.
|
|
237
|
+
|
|
238
|
+
"""
|
|
239
|
+
|
|
240
|
+
return self.do_request("DELETE", "/accounts/{}".format(account_id))
|
|
241
|
+
|
|
242
|
+
# end method definition
|
|
243
|
+
|
|
244
|
+
def get_claims(self) -> dict:
|
|
245
|
+
"""Retrieve a list of claims.
|
|
246
|
+
|
|
247
|
+
Returns:
|
|
248
|
+
dict: JSON response containing claim data.
|
|
249
|
+
|
|
250
|
+
"""
|
|
251
|
+
|
|
252
|
+
return self.do_request("GET", "/claims")
|
|
253
|
+
|
|
254
|
+
# end method definition
|
|
255
|
+
|
|
256
|
+
def get_claim(self, claim_id: str) -> dict:
|
|
257
|
+
"""Retrieve details of a specific claim.
|
|
258
|
+
|
|
259
|
+
Args:
|
|
260
|
+
claim_id: The unique identifier of the claim.
|
|
261
|
+
|
|
262
|
+
Returns:
|
|
263
|
+
dict: JSON response containing claim details.
|
|
264
|
+
|
|
265
|
+
"""
|
|
266
|
+
|
|
267
|
+
return self.do_request("GET", "/claims/{}".format(claim_id))
|
|
268
|
+
|
|
269
|
+
# end method definition
|
|
270
|
+
|
|
271
|
+
def add_claim(self, claim_data: dict) -> dict:
|
|
272
|
+
"""Create a new claim.
|
|
273
|
+
|
|
274
|
+
Args:
|
|
275
|
+
claim_data (dict):
|
|
276
|
+
Dictionary containing claim information.
|
|
277
|
+
|
|
278
|
+
Returns:
|
|
279
|
+
dict:
|
|
280
|
+
JSON response with created claim details.
|
|
281
|
+
|
|
282
|
+
"""
|
|
283
|
+
|
|
284
|
+
return self.do_request("POST", "/claims", data=claim_data)
|
|
285
|
+
|
|
286
|
+
# end method definition
|
|
287
|
+
|
|
288
|
+
def update_claim(self, claim_id: str, claim_data: dict) -> dict:
|
|
289
|
+
"""Update an existing claim.
|
|
290
|
+
|
|
291
|
+
Args:
|
|
292
|
+
claim_id:
|
|
293
|
+
The unique identifier of the claim.
|
|
294
|
+
claim_data:
|
|
295
|
+
Dictionary containing updated claim information.
|
|
296
|
+
|
|
297
|
+
Returns:
|
|
298
|
+
dict:
|
|
299
|
+
Response with updated claim details.
|
|
300
|
+
|
|
301
|
+
"""
|
|
302
|
+
|
|
303
|
+
return self.do_request("PUT", "/claims/{}".format(claim_id), data=claim_data)
|
|
304
|
+
|
|
305
|
+
# end method definition
|
|
306
|
+
|
|
307
|
+
def delete_claim(self, claim_id: str) -> dict:
|
|
308
|
+
"""Delete a claim.
|
|
309
|
+
|
|
310
|
+
Args:
|
|
311
|
+
claim_id (str):
|
|
312
|
+
The unique identifier of the claim to delete.
|
|
313
|
+
|
|
314
|
+
Returns:
|
|
315
|
+
dict:
|
|
316
|
+
Response indicating deletion success.
|
|
317
|
+
|
|
318
|
+
"""
|
|
319
|
+
|
|
320
|
+
return self.do_request("DELETE", "/claims/{}".format(claim_id))
|
|
321
|
+
|
|
322
|
+
# end method definition
|