pyxecm 3.4.6__tar.gz → 3.4.8__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.
- {pyxecm-3.4.6 → pyxecm-3.4.8}/PKG-INFO +1 -1
- {pyxecm-3.4.6 → pyxecm-3.4.8}/pyproject.toml +1 -1
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/otcs.py +23 -4
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/otds.py +94 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/.gitignore +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/README.md +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/__init__.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/avts.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/coreshare.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/helper/__init__.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/helper/assoc.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/helper/data.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/helper/logadapter.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/helper/web.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/helper/xml.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/otac.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/otawp.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/otca.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/otiv.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/otkd.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/otmm.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/otpd.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm/py.typed +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/__init__.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/__main__.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/app.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/auth/__init__.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/auth/functions.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/auth/models.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/auth/router.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/common/__init__.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/common/functions.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/common/metrics.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/common/models.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/common/router.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/settings.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/terminal/__init__.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/terminal/router.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/v1_maintenance/__init__.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/v1_maintenance/functions.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/v1_maintenance/models.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/v1_maintenance/router.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/v1_otcs/__init__.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/v1_otcs/functions.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/v1_otcs/router.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/v1_payload/__init__.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/v1_payload/functions.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/v1_payload/models.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_api/v1_payload/router.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/__init__.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/__main__.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/browser_automation.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/customizer.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/exceptions.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/guidewire.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/k8s.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/log.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/m365.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/payload.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/payload_list.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/salesforce.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/sap.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/servicenow.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/settings.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/successfactors.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_customizer/translate.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_maintenance_page/__init__.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_maintenance_page/__main__.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_maintenance_page/app.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_maintenance_page/settings.py +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_maintenance_page/static/favicon.avif +0 -0
- {pyxecm-3.4.6 → pyxecm-3.4.8}/src/pyxecm_maintenance_page/templates/maintenance.html +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyxecm
|
|
3
|
-
Version: 3.4.
|
|
3
|
+
Version: 3.4.8
|
|
4
4
|
Summary: A Python library to interact with Opentext Content Management Rest API
|
|
5
5
|
Project-URL: Homepage, https://github.com/opentext/pyxecm
|
|
6
6
|
Author-email: Kai Gatzweiler <kgatzweiler@opentext.com>, "Dr. Marc Diefenbruch" <mdiefenb@opentext.com>
|
|
@@ -1892,7 +1892,13 @@ class OTCS:
|
|
|
1892
1892
|
|
|
1893
1893
|
# First do some sanity checks:
|
|
1894
1894
|
if not response:
|
|
1895
|
-
self.logger.debug("Empty response
|
|
1895
|
+
self.logger.debug("Empty REST response. Cannot get result value! Returning None.")
|
|
1896
|
+
return None
|
|
1897
|
+
if "error" in response:
|
|
1898
|
+
self.logger.error(
|
|
1899
|
+
"REST response contains an error -> %s. Cannot get result value! Returning None.",
|
|
1900
|
+
str(response["error"]),
|
|
1901
|
+
)
|
|
1896
1902
|
return None
|
|
1897
1903
|
|
|
1898
1904
|
# To support also iterators that yield from results,
|
|
@@ -1903,7 +1909,7 @@ class OTCS:
|
|
|
1903
1909
|
|
|
1904
1910
|
if "results" not in response:
|
|
1905
1911
|
if show_error:
|
|
1906
|
-
self.logger.error("No 'results' key in REST response
|
|
1912
|
+
self.logger.error("No 'results' key in REST response. Cannot get result value! Returning None.")
|
|
1907
1913
|
return None
|
|
1908
1914
|
|
|
1909
1915
|
results = response["results"]
|
|
@@ -2034,10 +2040,16 @@ class OTCS:
|
|
|
2034
2040
|
|
|
2035
2041
|
# First do some sanity checks:
|
|
2036
2042
|
if not response:
|
|
2037
|
-
self.logger.debug("Empty REST response
|
|
2043
|
+
self.logger.debug("Empty REST response. Cannot get result values! Returning None.")
|
|
2044
|
+
return None
|
|
2045
|
+
if "error" in response:
|
|
2046
|
+
self.logger.error(
|
|
2047
|
+
"REST response contains an error -> %s. Cannot get result values! Returning None.",
|
|
2048
|
+
str(response["error"]),
|
|
2049
|
+
)
|
|
2038
2050
|
return None
|
|
2039
2051
|
if "results" not in response:
|
|
2040
|
-
self.logger.error("No 'results' key in REST response
|
|
2052
|
+
self.logger.error("No 'results' key in REST response. Cannot get result values! Returning None.")
|
|
2041
2053
|
return None
|
|
2042
2054
|
|
|
2043
2055
|
results = response["results"]
|
|
@@ -15032,6 +15044,7 @@ class OTCS:
|
|
|
15032
15044
|
external_modify_date: str | None = None,
|
|
15033
15045
|
external_create_date: str | None = None,
|
|
15034
15046
|
show_error: bool = True,
|
|
15047
|
+
parse_error_response: bool = False,
|
|
15035
15048
|
) -> dict | None:
|
|
15036
15049
|
"""Create a new business workspace.
|
|
15037
15050
|
|
|
@@ -15076,6 +15089,8 @@ class OTCS:
|
|
|
15076
15089
|
If True, log an error if workspace creation fails.
|
|
15077
15090
|
If False, log a warning instead.
|
|
15078
15091
|
True is the default.
|
|
15092
|
+
parse_error_response (bool, optional):
|
|
15093
|
+
Whether to parse the request response or not. Defaults to False.
|
|
15079
15094
|
|
|
15080
15095
|
Returns:
|
|
15081
15096
|
dict | None:
|
|
@@ -15202,8 +15217,12 @@ class OTCS:
|
|
|
15202
15217
|
),
|
|
15203
15218
|
show_error=show_error,
|
|
15204
15219
|
show_warning=(not show_error),
|
|
15220
|
+
parse_error_response=parse_error_response,
|
|
15205
15221
|
)
|
|
15206
15222
|
|
|
15223
|
+
if "error" in response:
|
|
15224
|
+
return response
|
|
15225
|
+
|
|
15207
15226
|
node_id = self.get_result_value(response=response, key="id")
|
|
15208
15227
|
if node_id:
|
|
15209
15228
|
trace.get_current_span().set_attribute("workspace.id", node_id)
|
|
@@ -957,6 +957,100 @@ class OTDS:
|
|
|
957
957
|
|
|
958
958
|
# end method definition
|
|
959
959
|
|
|
960
|
+
@tracer.start_as_current_span(attributes=OTEL_TRACING_ATTRIBUTES, name="authenticate_user_token")
|
|
961
|
+
def authenticate_user_token(
|
|
962
|
+
self,
|
|
963
|
+
username: str,
|
|
964
|
+
password: str,
|
|
965
|
+
scope: str = "otds:roles",
|
|
966
|
+
) -> str | None:
|
|
967
|
+
"""Authenticate a user via the OAuth2 password grant and return a JWT access token.
|
|
968
|
+
|
|
969
|
+
Unlike :meth:`authenticate` with ``grant_type="password"`` (which hits the
|
|
970
|
+
legacy credential endpoint and returns an OTDS SSO ticket), this method posts
|
|
971
|
+
``grant_type=password`` together with the configured OAuth client credentials to
|
|
972
|
+
the OAuth2 token endpoint (``/otdsws/oauth2/token``). This produces a signed
|
|
973
|
+
JWT access token that can be used as a standard ``Authorization: Bearer`` token.
|
|
974
|
+
|
|
975
|
+
The ``client_id`` and ``client_secret`` must be configured on the OTDS object
|
|
976
|
+
(passed to the constructor) before calling this method.
|
|
977
|
+
|
|
978
|
+
Args:
|
|
979
|
+
username (str):
|
|
980
|
+
The OTDS login name of the user to authenticate.
|
|
981
|
+
password (str):
|
|
982
|
+
The password for the OTDS user.
|
|
983
|
+
scope (str, optional):
|
|
984
|
+
OAuth2 scope string to request. Defaults to ``"otds:roles"``.
|
|
985
|
+
|
|
986
|
+
Returns:
|
|
987
|
+
str | None:
|
|
988
|
+
The JWT access token, or ``None`` if authentication fails.
|
|
989
|
+
The token is also stored in ``self._token``.
|
|
990
|
+
|
|
991
|
+
Example:
|
|
992
|
+
'eyJraWQiOiJvdGRzLXNpZ25pbmcta2V5IiwiYWxnIjoiUlMyNTYifQ...'
|
|
993
|
+
|
|
994
|
+
"""
|
|
995
|
+
|
|
996
|
+
request_url = self.token_url()
|
|
997
|
+
|
|
998
|
+
request_data = {
|
|
999
|
+
"grant_type": "password",
|
|
1000
|
+
"client_id": self.config()["clientId"],
|
|
1001
|
+
"client_secret": self.config()["clientSecret"],
|
|
1002
|
+
"username": username,
|
|
1003
|
+
"password": password,
|
|
1004
|
+
"scope": scope,
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
self.logger.debug(
|
|
1008
|
+
"Requesting OTDS user access token for -> '%s'; calling -> %s",
|
|
1009
|
+
username,
|
|
1010
|
+
request_url,
|
|
1011
|
+
)
|
|
1012
|
+
|
|
1013
|
+
try:
|
|
1014
|
+
response = requests.post(
|
|
1015
|
+
url=request_url,
|
|
1016
|
+
headers=REQUEST_FORM_HEADERS,
|
|
1017
|
+
data=request_data,
|
|
1018
|
+
timeout=REQUEST_TIMEOUT,
|
|
1019
|
+
)
|
|
1020
|
+
except requests.exceptions.RequestException as exception:
|
|
1021
|
+
self.logger.warning(
|
|
1022
|
+
"Unable to connect to OTDS token endpoint -> %s; error -> %s",
|
|
1023
|
+
request_url,
|
|
1024
|
+
str(exception),
|
|
1025
|
+
)
|
|
1026
|
+
return None
|
|
1027
|
+
|
|
1028
|
+
if not response.ok:
|
|
1029
|
+
self.logger.error(
|
|
1030
|
+
"Failed to request user access token for -> '%s'; error -> %s",
|
|
1031
|
+
username,
|
|
1032
|
+
response.text,
|
|
1033
|
+
)
|
|
1034
|
+
return None
|
|
1035
|
+
|
|
1036
|
+
token_dict = self.parse_request_response(response)
|
|
1037
|
+
if not token_dict:
|
|
1038
|
+
return None
|
|
1039
|
+
|
|
1040
|
+
access_token = token_dict.get("access_token")
|
|
1041
|
+
if not access_token:
|
|
1042
|
+
self.logger.error(
|
|
1043
|
+
"OTDS token response for user -> '%s' did not contain an access_token",
|
|
1044
|
+
username,
|
|
1045
|
+
)
|
|
1046
|
+
return None
|
|
1047
|
+
|
|
1048
|
+
self._token = access_token
|
|
1049
|
+
self._cookie = None
|
|
1050
|
+
return self._token
|
|
1051
|
+
|
|
1052
|
+
# end method definition
|
|
1053
|
+
|
|
960
1054
|
@tracer.start_as_current_span(attributes=OTEL_TRACING_ATTRIBUTES, name="impersonate_user")
|
|
961
1055
|
def impersonate_user(
|
|
962
1056
|
self,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|