pyxecm 3.8.2__tar.gz → 3.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.
- {pyxecm-3.8.2 → pyxecm-3.9.0}/PKG-INFO +4 -1
- {pyxecm-3.8.2 → pyxecm-3.9.0}/pyproject.toml +3 -1
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/otcs.py +32 -7
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/app.py +20 -5
- pyxecm-3.9.0/src/pyxecm_api/config/__init__.py +7 -0
- pyxecm-3.9.0/src/pyxecm_api/config/functions.py +834 -0
- pyxecm-3.9.0/src/pyxecm_api/config/models.py +206 -0
- pyxecm-3.9.0/src/pyxecm_api/config/router.py +274 -0
- pyxecm-3.9.0/src/pyxecm_api/pods/__init__.py +7 -0
- pyxecm-3.9.0/src/pyxecm_api/pods/functions.py +675 -0
- pyxecm-3.9.0/src/pyxecm_api/pods/log_spool.py +251 -0
- pyxecm-3.9.0/src/pyxecm_api/pods/models.py +124 -0
- pyxecm-3.9.0/src/pyxecm_api/pods/router.py +341 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/settings.py +39 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/terminal/router.py +67 -6
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/v1_payload/functions.py +75 -2
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/v1_payload/log_reader.py +29 -12
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/v1_payload/models.py +3 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/v1_payload/router.py +12 -83
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/__main__.py +3 -2
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/guidewire.py +1 -3
- pyxecm-3.9.0/src/pyxecm_customizer/log.py +153 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/payload_list.py +3 -3
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/sap.py +4806 -738
- pyxecm-3.9.0/src/pyxecm_customizer/sap_forms.py +1471 -0
- pyxecm-3.9.0/src/pyxecm_customizer/sap_models.py +14079 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/settings.py +4 -2
- pyxecm-3.8.2/src/pyxecm_customizer/log.py +0 -45
- pyxecm-3.8.2/src/pyxecm_customizer/sap_models.py +0 -7266
- {pyxecm-3.8.2 → pyxecm-3.9.0}/.gitignore +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/README.md +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/__init__.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/avts.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/coreshare.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/helper/__init__.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/helper/assoc.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/helper/data.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/helper/logadapter.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/helper/web.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/helper/xml.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/otac.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/otawp.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/otca.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/otds.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/otiv.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/otkd.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/otmm.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/otpd.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm/py.typed +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/__init__.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/__main__.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/auth/__init__.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/auth/functions.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/auth/models.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/auth/router.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/common/__init__.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/common/functions.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/common/metrics.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/common/models.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/common/router.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/terminal/__init__.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/v1_maintenance/__init__.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/v1_maintenance/functions.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/v1_maintenance/models.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/v1_maintenance/router.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/v1_otcs/__init__.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/v1_otcs/functions.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/v1_otcs/router.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_api/v1_payload/__init__.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/__init__.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/browser_automation.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/customizer.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/exceptions.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/k8s.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/m365.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/manager_push.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/payload.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/salesforce.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/servicenow.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/successfactors.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/translate.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_customizer/version.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_maintenance_page/__init__.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_maintenance_page/__main__.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_maintenance_page/app.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_maintenance_page/settings.py +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_maintenance_page/static/favicon.avif +0 -0
- {pyxecm-3.8.2 → pyxecm-3.9.0}/src/pyxecm_maintenance_page/templates/maintenance.html +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pyxecm
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.9.0
|
|
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>
|
|
@@ -27,6 +27,7 @@ Requires-Dist: xmltodict>=0.14.2
|
|
|
27
27
|
Requires-Dist: zeep>=4.2.0
|
|
28
28
|
Provides-Extra: api
|
|
29
29
|
Requires-Dist: asyncio>=3.4.3; extra == 'api'
|
|
30
|
+
Requires-Dist: cryptography>=44.0.0; extra == 'api'
|
|
30
31
|
Requires-Dist: fastapi>=0.116.0; extra == 'api'
|
|
31
32
|
Requires-Dist: jinja2>=3.1.6; extra == 'api'
|
|
32
33
|
Requires-Dist: opentelemetry-api>=1.34.1; extra == 'api'
|
|
@@ -42,6 +43,8 @@ Requires-Dist: openpyxl>=3.1.5; extra == 'customizer'
|
|
|
42
43
|
Requires-Dist: playwright>=1.53.0; extra == 'customizer'
|
|
43
44
|
Requires-Dist: pydantic>=2.12.0; extra == 'customizer'
|
|
44
45
|
Requires-Dist: python-hcl2==7.3.1; extra == 'customizer'
|
|
46
|
+
Provides-Extra: forms
|
|
47
|
+
Requires-Dist: reportlab>=4.0; extra == 'forms'
|
|
45
48
|
Provides-Extra: magic
|
|
46
49
|
Requires-Dist: python-magic; extra == 'magic'
|
|
47
50
|
Provides-Extra: saml
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pyxecm"
|
|
3
|
-
version = "3.
|
|
3
|
+
version = "3.9.0"
|
|
4
4
|
description = 'A Python library to interact with Opentext Content Management Rest API'
|
|
5
5
|
keywords = [
|
|
6
6
|
'opentext',
|
|
@@ -44,6 +44,7 @@ classifiers = [
|
|
|
44
44
|
magic = ['python-magic']
|
|
45
45
|
sap = ['pyrfc==3.3.1']
|
|
46
46
|
saml = ['signxml>=5.1.0']
|
|
47
|
+
forms = ['reportlab>=4.0']
|
|
47
48
|
customizer = [
|
|
48
49
|
"kubernetes>=33.1.0",
|
|
49
50
|
"playwright>=1.53.0",
|
|
@@ -53,6 +54,7 @@ customizer = [
|
|
|
53
54
|
]
|
|
54
55
|
api = [
|
|
55
56
|
"asyncio>=3.4.3",
|
|
57
|
+
"cryptography>=44.0.0",
|
|
56
58
|
"fastapi>=0.116.0",
|
|
57
59
|
"jinja2>=3.1.6",
|
|
58
60
|
"opentelemetry-api>=1.34.1",
|
|
@@ -9333,7 +9333,8 @@ class OTCS:
|
|
|
9333
9333
|
|
|
9334
9334
|
elif os.path.exists(path_or_url):
|
|
9335
9335
|
self.logger.debug("Uploading local file -> '%s'", path_or_url)
|
|
9336
|
-
|
|
9336
|
+
with open(file=path_or_url, mode="rb") as local_file:
|
|
9337
|
+
file_content = local_file.read()
|
|
9337
9338
|
|
|
9338
9339
|
else:
|
|
9339
9340
|
self.logger.warning("Cannot access file -> '%s'", path_or_url)
|
|
@@ -9502,14 +9503,15 @@ class OTCS:
|
|
|
9502
9503
|
If True, automatically extract ZIP files and upload extracted directory. If False,
|
|
9503
9504
|
upload the unchanged Zip file.
|
|
9504
9505
|
replace_existing (bool, optional):
|
|
9505
|
-
If True,
|
|
9506
|
-
the upload will fail if a file with the same name already exists.
|
|
9506
|
+
If True, an existing document with the same name in the target folder gets the file
|
|
9507
|
+
as a new version. If False, the upload will fail if a file with the same name already exists.
|
|
9507
9508
|
show_error (bool, optional):
|
|
9508
9509
|
If True, treats the upload failure as an error. If False, no error is shown (useful if the file already exists).
|
|
9509
9510
|
|
|
9510
9511
|
Returns:
|
|
9511
9512
|
dict | None:
|
|
9512
|
-
The response from the upload operation or
|
|
9513
|
+
The response from the upload operation (or from add_document_version() if a new
|
|
9514
|
+
version of an existing document has been added) or None if the upload fails.
|
|
9513
9515
|
|
|
9514
9516
|
"""
|
|
9515
9517
|
|
|
@@ -9604,7 +9606,8 @@ class OTCS:
|
|
|
9604
9606
|
|
|
9605
9607
|
elif os.path.exists(file_url):
|
|
9606
9608
|
self.logger.debug("Uploading local file -> %s", file_url)
|
|
9607
|
-
|
|
9609
|
+
with open(file=file_url, mode="rb") as local_file:
|
|
9610
|
+
file_content = local_file.read()
|
|
9608
9611
|
|
|
9609
9612
|
else:
|
|
9610
9613
|
self.logger.warning("Cannot access file -> '%s'", file_url)
|
|
@@ -9652,6 +9655,27 @@ class OTCS:
|
|
|
9652
9655
|
if not mime_type:
|
|
9653
9656
|
mime_type = "application/octet-stream" # Default to binary stream if mime type cannot be determined
|
|
9654
9657
|
|
|
9658
|
+
# If a document with the same name exists already we add a new version instead
|
|
9659
|
+
# (categories, classifications and external dates only apply to new documents):
|
|
9660
|
+
if replace_existing:
|
|
9661
|
+
response = self.get_node_by_parent_and_name(
|
|
9662
|
+
parent_id=parent_id, name=file_name, fields="properties{id,name}"
|
|
9663
|
+
)
|
|
9664
|
+
existing_document_id = self.get_result_value(response=response, key="id")
|
|
9665
|
+
if existing_document_id:
|
|
9666
|
+
self.logger.debug(
|
|
9667
|
+
"Document -> '%s' does already exist in parent with ID -> %d. Adding a new version...",
|
|
9668
|
+
file_name,
|
|
9669
|
+
parent_id,
|
|
9670
|
+
)
|
|
9671
|
+
return self.add_document_version(
|
|
9672
|
+
node_id=int(existing_document_id),
|
|
9673
|
+
file_name=file_name,
|
|
9674
|
+
mime_type=mime_type,
|
|
9675
|
+
file_content=file_content if isinstance(file_content, bytes) else file_content.read(),
|
|
9676
|
+
description=description,
|
|
9677
|
+
)
|
|
9678
|
+
|
|
9655
9679
|
upload_post_files = [("file", (f"{file_name}", file_content, mime_type))]
|
|
9656
9680
|
|
|
9657
9681
|
request_url = self.config()["nodesUrlv2"]
|
|
@@ -9997,7 +10021,8 @@ class OTCS:
|
|
|
9997
10021
|
|
|
9998
10022
|
elif os.path.exists(file_url):
|
|
9999
10023
|
self.logger.debug("Upload local file -> '%s' as new version.", file_url)
|
|
10000
|
-
|
|
10024
|
+
with open(file=file_url, mode="rb") as local_file:
|
|
10025
|
+
file_content = local_file.read()
|
|
10001
10026
|
|
|
10002
10027
|
else:
|
|
10003
10028
|
self.logger.warning("Cannot access file -> '%s'", file_url)
|
|
@@ -10007,7 +10032,7 @@ class OTCS:
|
|
|
10007
10032
|
upload_post_data = {"description": description}
|
|
10008
10033
|
|
|
10009
10034
|
if not mime_type:
|
|
10010
|
-
mime_type, _ = mimetypes.guess_type(
|
|
10035
|
+
mime_type, _ = mimetypes.guess_type(file_name)
|
|
10011
10036
|
|
|
10012
10037
|
if not mime_type and magic_installed and file_url:
|
|
10013
10038
|
try:
|
|
@@ -24,6 +24,7 @@ from opentelemetry.sdk.resources import Resource
|
|
|
24
24
|
from opentelemetry.sdk.trace import TracerProvider
|
|
25
25
|
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
|
26
26
|
from prometheus_fastapi_instrumentator import Instrumentator
|
|
27
|
+
from pyxecm_customizer.log import LOG_DATE_FORMAT, LOG_FORMAT
|
|
27
28
|
from pyxecm_customizer.version import customizer_version
|
|
28
29
|
from pyxecm_maintenance_page import run_maintenance_page
|
|
29
30
|
|
|
@@ -31,6 +32,9 @@ from .auth.router import router as auth_router
|
|
|
31
32
|
from .common.functions import PAYLOAD_LIST
|
|
32
33
|
from .common.metrics import payload_logs_by_payload, payload_logs_total
|
|
33
34
|
from .common.router import router as common_router
|
|
35
|
+
from .config.router import router as config_router
|
|
36
|
+
from .pods.router import LOG_SPOOL
|
|
37
|
+
from .pods.router import router as pods_router
|
|
34
38
|
from .settings import api_settings
|
|
35
39
|
from .terminal.router import router as terminal_router
|
|
36
40
|
from .v1_maintenance.router import router as v1_maintenance_router
|
|
@@ -95,6 +99,7 @@ async def lifespan(
|
|
|
95
99
|
|
|
96
100
|
logger.info("Shutdown")
|
|
97
101
|
PAYLOAD_LIST.stop_payload_processing()
|
|
102
|
+
LOG_SPOOL.close()
|
|
98
103
|
|
|
99
104
|
|
|
100
105
|
# end function lifespan
|
|
@@ -124,6 +129,11 @@ app = FastAPI(
|
|
|
124
129
|
"name": "maintenance",
|
|
125
130
|
"description": "Enable, disable or alter the maintenance mode.",
|
|
126
131
|
},
|
|
132
|
+
{
|
|
133
|
+
"name": "pods",
|
|
134
|
+
"description": "List the pods of the namespace, browse, download and upload their files and read their "
|
|
135
|
+
"logs. Only available when pod_access is on (it follows ws_terminal).",
|
|
136
|
+
},
|
|
127
137
|
],
|
|
128
138
|
)
|
|
129
139
|
|
|
@@ -152,6 +162,10 @@ app.include_router(router=v1_payload_router)
|
|
|
152
162
|
if api_settings.ws_terminal:
|
|
153
163
|
app.include_router(router=terminal_router)
|
|
154
164
|
|
|
165
|
+
if api_settings.pod_access:
|
|
166
|
+
app.include_router(router=pods_router)
|
|
167
|
+
app.include_router(router=config_router)
|
|
168
|
+
|
|
155
169
|
## Add Prometheus Instrumentator for /metrics,
|
|
156
170
|
if api_settings.metrics:
|
|
157
171
|
# Add Prometheus Instrumentator for /metricsf
|
|
@@ -183,15 +197,16 @@ def run_api() -> None:
|
|
|
183
197
|
# Stdout
|
|
184
198
|
log_config["formatters"]["standard"] = {
|
|
185
199
|
"()": "uvicorn.logging.DefaultFormatter",
|
|
186
|
-
|
|
187
|
-
"
|
|
200
|
+
# The log format with uvicorn's colored level name.
|
|
201
|
+
"fmt": LOG_FORMAT.replace("%(levelname)s", "%(levelprefix)s"),
|
|
202
|
+
"datefmt": LOG_DATE_FORMAT,
|
|
188
203
|
"use_colors": True,
|
|
189
204
|
}
|
|
190
205
|
|
|
191
206
|
log_config["formatters"]["logfile"] = {
|
|
192
207
|
"()": "uvicorn.logging.DefaultFormatter",
|
|
193
|
-
"fmt":
|
|
194
|
-
"datefmt":
|
|
208
|
+
"fmt": LOG_FORMAT,
|
|
209
|
+
"datefmt": LOG_DATE_FORMAT,
|
|
195
210
|
"use_colors": True,
|
|
196
211
|
}
|
|
197
212
|
|
|
@@ -205,7 +220,7 @@ def run_api() -> None:
|
|
|
205
220
|
log_config["formatters"]["default"] = {
|
|
206
221
|
"()": "uvicorn.logging.DefaultFormatter",
|
|
207
222
|
"fmt": "%(asctime)s %(levelprefix)s %(message)s",
|
|
208
|
-
"datefmt":
|
|
223
|
+
"datefmt": LOG_DATE_FORMAT,
|
|
209
224
|
"use_colors": False,
|
|
210
225
|
}
|
|
211
226
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"""ConfigMaps and Secrets of the namespace: show and change them, and restart what uses them."""
|
|
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"
|