pyxecm 2.0.3__tar.gz → 3.0.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.
Potentially problematic release.
This version of pyxecm might be problematic. Click here for more details.
- pyxecm-3.0.0/.gitignore +25 -0
- pyxecm-3.0.0/PKG-INFO +48 -0
- pyxecm-3.0.0/README.md +0 -0
- pyxecm-3.0.0/pyproject.toml +88 -0
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/coreshare.py +76 -8
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/helper/data.py +16 -24
- pyxecm-3.0.0/src/pyxecm/helper/otel_config.py +26 -0
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/helper/web.py +1 -2
- pyxecm-3.0.0/src/pyxecm/otca.py +2075 -0
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/otcs.py +4238 -758
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/otds.py +4 -12
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/otmm.py +4 -5
- pyxecm-3.0.0/src/pyxecm/py.typed +0 -0
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/__main__.py +1 -1
- pyxecm-3.0.0/src/pyxecm_api/agents/__init__.py +7 -0
- pyxecm-3.0.0/src/pyxecm_api/agents/app.py +13 -0
- pyxecm-3.0.0/src/pyxecm_api/agents/functions.py +119 -0
- pyxecm-3.0.0/src/pyxecm_api/agents/models.py +10 -0
- pyxecm-3.0.0/src/pyxecm_api/agents/otcm_knowledgegraph/functions.py +85 -0
- pyxecm-3.0.0/src/pyxecm_api/agents/otcm_knowledgegraph/models.py +61 -0
- pyxecm-3.0.0/src/pyxecm_api/agents/otcm_knowledgegraph/router.py +74 -0
- pyxecm-3.0.0/src/pyxecm_api/agents/otcm_user_agent/models.py +20 -0
- pyxecm-3.0.0/src/pyxecm_api/agents/otcm_user_agent/router.py +65 -0
- pyxecm-3.0.0/src/pyxecm_api/agents/otcm_workspace_agent/models.py +40 -0
- pyxecm-3.0.0/src/pyxecm_api/agents/otcm_workspace_agent/router.py +200 -0
- pyxecm-3.0.0/src/pyxecm_api/app.py +221 -0
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/auth/functions.py +10 -2
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/auth/router.py +4 -3
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/common/functions.py +39 -9
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/common/metrics.py +1 -2
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/common/router.py +12 -11
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/settings.py +30 -6
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/terminal/router.py +1 -1
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/v1_csai/router.py +39 -10
- pyxecm-3.0.0/src/pyxecm_api/v1_csai/statics/bindings/utils.js +189 -0
- pyxecm-3.0.0/src/pyxecm_api/v1_csai/statics/tom-select/tom-select.complete.min.js +356 -0
- pyxecm-3.0.0/src/pyxecm_api/v1_csai/statics/tom-select/tom-select.css +334 -0
- pyxecm-3.0.0/src/pyxecm_api/v1_csai/statics/vis-9.1.2/vis-network.css +1 -0
- pyxecm-3.0.0/src/pyxecm_api/v1_csai/statics/vis-9.1.2/vis-network.min.js +27 -0
- pyxecm-3.0.0/src/pyxecm_api/v1_maintenance/__init__.py +1 -0
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/v1_maintenance/functions.py +3 -3
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/v1_maintenance/router.py +8 -8
- pyxecm-3.0.0/src/pyxecm_api/v1_otcs/__init__.py +1 -0
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/v1_otcs/functions.py +7 -5
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/v1_otcs/router.py +24 -13
- pyxecm-3.0.0/src/pyxecm_api/v1_payload/__init__.py +1 -0
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/v1_payload/functions.py +10 -7
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/v1_payload/router.py +11 -10
- {pyxecm-2.0.3/pyxecm/customizer → pyxecm-3.0.0/src/pyxecm_customizer}/__init__.py +8 -0
- {pyxecm-2.0.3/pyxecm/customizer → pyxecm-3.0.0/src/pyxecm_customizer}/__main__.py +15 -21
- {pyxecm-2.0.3/pyxecm/customizer → pyxecm-3.0.0/src/pyxecm_customizer}/browser_automation.py +414 -103
- {pyxecm-2.0.3/pyxecm/customizer → pyxecm-3.0.0/src/pyxecm_customizer}/customizer.py +178 -116
- {pyxecm-2.0.3/pyxecm/customizer → pyxecm-3.0.0/src/pyxecm_customizer}/guidewire.py +60 -20
- {pyxecm-2.0.3/pyxecm/customizer → pyxecm-3.0.0/src/pyxecm_customizer}/k8s.py +4 -4
- pyxecm-3.0.0/src/pyxecm_customizer/knowledge_graph.py +719 -0
- pyxecm-3.0.0/src/pyxecm_customizer/log.py +35 -0
- {pyxecm-2.0.3/pyxecm/customizer → pyxecm-3.0.0/src/pyxecm_customizer}/m365.py +41 -33
- {pyxecm-2.0.3/pyxecm/customizer → pyxecm-3.0.0/src/pyxecm_customizer}/payload.py +2359 -1991
- {pyxecm-2.0.3/pyxecm/customizer/api/common → pyxecm-3.0.0/src/pyxecm_customizer}/payload_list.py +57 -65
- {pyxecm-2.0.3/pyxecm/customizer → pyxecm-3.0.0/src/pyxecm_customizer}/salesforce.py +1 -1
- {pyxecm-2.0.3/pyxecm/customizer → pyxecm-3.0.0/src/pyxecm_customizer}/sap.py +6 -2
- {pyxecm-2.0.3/pyxecm/customizer → pyxecm-3.0.0/src/pyxecm_customizer}/servicenow.py +2 -4
- {pyxecm-2.0.3/pyxecm/customizer → pyxecm-3.0.0/src/pyxecm_customizer}/settings.py +7 -6
- {pyxecm-2.0.3/pyxecm/customizer → pyxecm-3.0.0/src/pyxecm_customizer}/successfactors.py +40 -28
- {pyxecm-2.0.3/pyxecm/customizer → pyxecm-3.0.0/src/pyxecm_customizer}/translate.py +14 -10
- {pyxecm-2.0.3/pyxecm/maintenance_page → pyxecm-3.0.0/src/pyxecm_maintenance_page}/__main__.py +1 -1
- {pyxecm-2.0.3/pyxecm/maintenance_page → pyxecm-3.0.0/src/pyxecm_maintenance_page}/app.py +16 -6
- pyxecm-2.0.3/LICENSE +0 -202
- pyxecm-2.0.3/PKG-INFO +0 -119
- pyxecm-2.0.3/README.md +0 -66
- pyxecm-2.0.3/pyproject.toml +0 -202
- pyxecm-2.0.3/pyxecm/customizer/api/app.py +0 -163
- pyxecm-2.0.3/pyxecm/customizer/log.py +0 -107
- pyxecm-2.0.3/pyxecm/customizer/nhc.py +0 -1169
- pyxecm-2.0.3/pyxecm/customizer/openapi.py +0 -258
- pyxecm-2.0.3/pyxecm/customizer/pht.py +0 -1357
- pyxecm-2.0.3/pyxecm/otca.py +0 -735
- pyxecm-2.0.3/pyxecm.egg-info/PKG-INFO +0 -119
- pyxecm-2.0.3/pyxecm.egg-info/SOURCES.txt +0 -82
- pyxecm-2.0.3/pyxecm.egg-info/dependency_links.txt +0 -1
- pyxecm-2.0.3/pyxecm.egg-info/requires.txt +0 -38
- pyxecm-2.0.3/pyxecm.egg-info/top_level.txt +0 -1
- pyxecm-2.0.3/setup.cfg +0 -4
- pyxecm-2.0.3/setup.py +0 -3
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/__init__.py +0 -0
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/avts.py +0 -0
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/helper/__init__.py +0 -0
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/helper/assoc.py +0 -0
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/helper/logadapter.py +0 -0
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/helper/xml.py +0 -0
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/otac.py +0 -0
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/otawp.py +0 -0
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/otiv.py +0 -0
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/otkd.py +0 -0
- {pyxecm-2.0.3 → pyxecm-3.0.0/src}/pyxecm/otpd.py +0 -0
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/__init__.py +0 -0
- {pyxecm-2.0.3/pyxecm/customizer/api/auth → pyxecm-3.0.0/src/pyxecm_api/agents/otcm_knowledgegraph}/__init__.py +0 -0
- {pyxecm-2.0.3/pyxecm/customizer/api/common → pyxecm-3.0.0/src/pyxecm_api/agents/otcm_user_agent}/__init__.py +0 -0
- {pyxecm-2.0.3/pyxecm/customizer/api/v1_csai → pyxecm-3.0.0/src/pyxecm_api/agents/otcm_workspace_agent}/__init__.py +0 -0
- {pyxecm-2.0.3/pyxecm/customizer/api/v1_maintenance → pyxecm-3.0.0/src/pyxecm_api/auth}/__init__.py +0 -0
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/auth/models.py +0 -0
- {pyxecm-2.0.3/pyxecm/customizer/api/v1_otcs → pyxecm-3.0.0/src/pyxecm_api/common}/__init__.py +0 -0
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/common/models.py +0 -0
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/terminal/__init__.py +0 -0
- {pyxecm-2.0.3/pyxecm/customizer/api/v1_payload → pyxecm-3.0.0/src/pyxecm_api/v1_csai}/__init__.py +0 -0
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/v1_csai/models.py +0 -0
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/v1_maintenance/models.py +0 -0
- {pyxecm-2.0.3/pyxecm/customizer/api → pyxecm-3.0.0/src/pyxecm_api}/v1_payload/models.py +0 -0
- {pyxecm-2.0.3/pyxecm/customizer → pyxecm-3.0.0/src/pyxecm_customizer}/exceptions.py +0 -0
- {pyxecm-2.0.3/pyxecm/maintenance_page → pyxecm-3.0.0/src/pyxecm_maintenance_page}/__init__.py +0 -0
- {pyxecm-2.0.3/pyxecm/maintenance_page → pyxecm-3.0.0/src/pyxecm_maintenance_page}/settings.py +0 -0
- {pyxecm-2.0.3/pyxecm/maintenance_page → pyxecm-3.0.0/src/pyxecm_maintenance_page}/static/favicon.avif +0 -0
- {pyxecm-2.0.3/pyxecm/maintenance_page → pyxecm-3.0.0/src/pyxecm_maintenance_page}/templates/maintenance.html +0 -0
pyxecm-3.0.0/.gitignore
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
public/
|
|
2
|
+
dist/
|
|
3
|
+
pyxecm.egg-info/
|
|
4
|
+
pyxecm/__pycache__/
|
|
5
|
+
.venv/
|
|
6
|
+
.debug/
|
|
7
|
+
pyxecm/helper/__pycache__/
|
|
8
|
+
__pycache__
|
|
9
|
+
build/
|
|
10
|
+
.env
|
|
11
|
+
~$*
|
|
12
|
+
debug/logs/
|
|
13
|
+
.env.*
|
|
14
|
+
.ruff_cache
|
|
15
|
+
uv.lock
|
|
16
|
+
customizerapisettings_doc.md
|
|
17
|
+
customizerapisettings.env
|
|
18
|
+
customizerapisettings.md
|
|
19
|
+
customizersettings_doc.md
|
|
20
|
+
customizersettings.env
|
|
21
|
+
coverage.xml
|
|
22
|
+
junit.xml
|
|
23
|
+
.coverage
|
|
24
|
+
lib/
|
|
25
|
+
/root.html
|
pyxecm-3.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyxecm
|
|
3
|
+
Version: 3.0.0
|
|
4
|
+
Summary: A Python library to interact with Opentext Content Management Rest API
|
|
5
|
+
Project-URL: Homepage, https://github.com/opentext/pyxecm
|
|
6
|
+
Author-email: Kai Gatzweiler <kgatzweiler@opentext.com>, "Dr. Marc Diefenbruch" <mdiefenb@opentext.com>
|
|
7
|
+
Keywords: appworks,archivecenter,contentserver,extendedecm,opentext,otds
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Content Management System
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Requires-Dist: lxml>=6.0.0
|
|
16
|
+
Requires-Dist: opentelemetry-api>=1.34.1
|
|
17
|
+
Requires-Dist: opentelemetry-exporter-otlp>=1.34.1
|
|
18
|
+
Requires-Dist: opentelemetry-instrumentation-requests>=0.55b1
|
|
19
|
+
Requires-Dist: opentelemetry-instrumentation-threading>=0.55b1
|
|
20
|
+
Requires-Dist: opentelemetry-sdk>=1.34.1
|
|
21
|
+
Requires-Dist: pandas>=2.3.1
|
|
22
|
+
Requires-Dist: requests-toolbelt>=1.0.0
|
|
23
|
+
Requires-Dist: requests>=2.32.4
|
|
24
|
+
Requires-Dist: suds>=1.2.0
|
|
25
|
+
Requires-Dist: websockets>=15.0.1
|
|
26
|
+
Requires-Dist: xmltodict>=0.14.2
|
|
27
|
+
Provides-Extra: api
|
|
28
|
+
Requires-Dist: asyncio>=3.4.3; extra == 'api'
|
|
29
|
+
Requires-Dist: fastapi>=0.116.0; extra == 'api'
|
|
30
|
+
Requires-Dist: jinja2>=3.1.6; extra == 'api'
|
|
31
|
+
Requires-Dist: opentelemetry-api>=1.34.1; extra == 'api'
|
|
32
|
+
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.55b1; extra == 'api'
|
|
33
|
+
Requires-Dist: opentelemetry-sdk>=1.34.1; extra == 'api'
|
|
34
|
+
Requires-Dist: prometheus-fastapi-instrumentator>=7.1.0; extra == 'api'
|
|
35
|
+
Requires-Dist: pydantic-settings>=2.10.1; extra == 'api'
|
|
36
|
+
Requires-Dist: python-multipart>=0.0.20; extra == 'api'
|
|
37
|
+
Requires-Dist: uvicorn>=0.35.0; extra == 'api'
|
|
38
|
+
Provides-Extra: customizer
|
|
39
|
+
Requires-Dist: kubernetes>=33.1.0; extra == 'customizer'
|
|
40
|
+
Requires-Dist: playwright>=1.53.0; extra == 'customizer'
|
|
41
|
+
Requires-Dist: pydantic>=2.11.7; extra == 'customizer'
|
|
42
|
+
Requires-Dist: python-hcl2>=7.2.1; extra == 'customizer'
|
|
43
|
+
Provides-Extra: magic
|
|
44
|
+
Requires-Dist: python-magic; extra == 'magic'
|
|
45
|
+
Provides-Extra: pyvis
|
|
46
|
+
Requires-Dist: pyvis>=0.3.2; extra == 'pyvis'
|
|
47
|
+
Provides-Extra: sap
|
|
48
|
+
Requires-Dist: pyrfc==3.3.1; extra == 'sap'
|
pyxecm-3.0.0/README.md
ADDED
|
File without changes
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "pyxecm"
|
|
3
|
+
version = "3.0.0"
|
|
4
|
+
description = 'A Python library to interact with Opentext Content Management Rest API'
|
|
5
|
+
keywords = [
|
|
6
|
+
'opentext',
|
|
7
|
+
'extendedecm',
|
|
8
|
+
'contentserver',
|
|
9
|
+
'otds',
|
|
10
|
+
'appworks',
|
|
11
|
+
'archivecenter',
|
|
12
|
+
]
|
|
13
|
+
readme = "README.md"
|
|
14
|
+
authors = [
|
|
15
|
+
{ name = "Kai Gatzweiler", email = "kgatzweiler@opentext.com" },
|
|
16
|
+
{ name = "Dr. Marc Diefenbruch", email = "mdiefenb@opentext.com" },
|
|
17
|
+
]
|
|
18
|
+
requires-python = '>=3.10'
|
|
19
|
+
dependencies = [
|
|
20
|
+
"lxml>=6.0.0",
|
|
21
|
+
"opentelemetry-api>=1.34.1",
|
|
22
|
+
"opentelemetry-exporter-otlp>=1.34.1",
|
|
23
|
+
"opentelemetry-instrumentation-requests>=0.55b1",
|
|
24
|
+
"opentelemetry-instrumentation-threading>=0.55b1",
|
|
25
|
+
"opentelemetry-sdk>=1.34.1",
|
|
26
|
+
"pandas>=2.3.1",
|
|
27
|
+
"requests>=2.32.4",
|
|
28
|
+
"requests-toolbelt>=1.0.0",
|
|
29
|
+
"suds>=1.2.0",
|
|
30
|
+
"websockets>=15.0.1",
|
|
31
|
+
"xmltodict>=0.14.2",
|
|
32
|
+
]
|
|
33
|
+
classifiers = [
|
|
34
|
+
'Development Status :: 4 - Beta',
|
|
35
|
+
'Programming Language :: Python :: 3',
|
|
36
|
+
'License :: OSI Approved :: Apache Software License',
|
|
37
|
+
'Operating System :: OS Independent',
|
|
38
|
+
'Intended Audience :: Developers',
|
|
39
|
+
'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Content Management System',
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.optional-dependencies]
|
|
43
|
+
magic = ['python-magic']
|
|
44
|
+
sap = ['pyrfc==3.3.1']
|
|
45
|
+
pyvis = ["pyvis>=0.3.2"]
|
|
46
|
+
customizer = [
|
|
47
|
+
"kubernetes>=33.1.0",
|
|
48
|
+
"playwright>=1.53.0",
|
|
49
|
+
"pydantic>=2.11.7",
|
|
50
|
+
"python-hcl2>=7.2.1",
|
|
51
|
+
]
|
|
52
|
+
api = [
|
|
53
|
+
"asyncio>=3.4.3",
|
|
54
|
+
"fastapi>=0.116.0",
|
|
55
|
+
"jinja2>=3.1.6",
|
|
56
|
+
"opentelemetry-api>=1.34.1",
|
|
57
|
+
"opentelemetry-instrumentation-fastapi>=0.55b1",
|
|
58
|
+
"opentelemetry-sdk>=1.34.1",
|
|
59
|
+
"prometheus-fastapi-instrumentator>=7.1.0",
|
|
60
|
+
"pydantic-settings>=2.10.1",
|
|
61
|
+
"python-multipart>=0.0.20",
|
|
62
|
+
"uvicorn>=0.35.0",
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
[project.urls]
|
|
66
|
+
Homepage = 'https://github.com/opentext/pyxecm'
|
|
67
|
+
|
|
68
|
+
[build-system]
|
|
69
|
+
requires = ["hatchling"]
|
|
70
|
+
build-backend = "hatchling.build"
|
|
71
|
+
|
|
72
|
+
[tool.hatch.build.targets.wheel]
|
|
73
|
+
packages = [
|
|
74
|
+
"src/pyxecm",
|
|
75
|
+
"src/pyxecm_api",
|
|
76
|
+
"src/pyxecm_customizer",
|
|
77
|
+
"src/pyxecm_maintenance_page",
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
[tool.hatch.build.targets.sdist]
|
|
81
|
+
exclude = [
|
|
82
|
+
"tests/**"
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
[project.scripts]
|
|
86
|
+
pyxecm-api = "pyxecm_api:run_api"
|
|
87
|
+
pyxecm-customizer = "pyxecm_customizer:main"
|
|
88
|
+
pyxecm-maintenance-page = "pyxecm_maintenance_page:run_api"
|
|
@@ -27,6 +27,7 @@ import time
|
|
|
27
27
|
import urllib.parse
|
|
28
28
|
from http import HTTPStatus
|
|
29
29
|
from importlib.metadata import version
|
|
30
|
+
from urllib.parse import parse_qs, urlparse
|
|
30
31
|
|
|
31
32
|
import requests
|
|
32
33
|
|
|
@@ -522,7 +523,7 @@ class CoreShare:
|
|
|
522
523
|
Can be used to provide a more specific error message
|
|
523
524
|
in case an error occurs.
|
|
524
525
|
show_error (bool, optional):
|
|
525
|
-
True: write an error to the log file
|
|
526
|
+
True: write an error to the log file (this is the default)
|
|
526
527
|
False: write a warning to the log file
|
|
527
528
|
|
|
528
529
|
Returns:
|
|
@@ -933,6 +934,71 @@ class CoreShare:
|
|
|
933
934
|
|
|
934
935
|
# end method definition
|
|
935
936
|
|
|
937
|
+
def get_groups_iterator(
|
|
938
|
+
self,
|
|
939
|
+
count: int | None = None,
|
|
940
|
+
) -> iter:
|
|
941
|
+
"""Get an iterator object that can be used to traverse all Core Share groups.
|
|
942
|
+
|
|
943
|
+
Returning a generator avoids loading a large number of items into memory at once. Instead you
|
|
944
|
+
can iterate over the potential large list of Core Share groups.
|
|
945
|
+
|
|
946
|
+
Example usage:
|
|
947
|
+
groups = core_share_object.get_groups_iterator(page_size=10)
|
|
948
|
+
for group in groups:
|
|
949
|
+
logger.info("Traversing Core Share group -> %s", group["name"])
|
|
950
|
+
|
|
951
|
+
Args:
|
|
952
|
+
count (int | None, optional):
|
|
953
|
+
The chunk size for the number of groups returned by one
|
|
954
|
+
REST API call. If None, then a default of 250 is used.
|
|
955
|
+
|
|
956
|
+
Returns:
|
|
957
|
+
iter:
|
|
958
|
+
A generator yielding one OTDS group per iteration.
|
|
959
|
+
If the REST API fails, returns no value.
|
|
960
|
+
|
|
961
|
+
"""
|
|
962
|
+
|
|
963
|
+
offset = 0
|
|
964
|
+
|
|
965
|
+
while True:
|
|
966
|
+
response = self.get_groups(
|
|
967
|
+
offset=offset,
|
|
968
|
+
count=count,
|
|
969
|
+
)
|
|
970
|
+
if not response or not response.get("results", []):
|
|
971
|
+
# Don't return None! Plain return is what we need for iterators.
|
|
972
|
+
# Natural Termination: If the generator does not yield, it behaves
|
|
973
|
+
# like an empty iterable when used in a loop or converted to a list:
|
|
974
|
+
return
|
|
975
|
+
|
|
976
|
+
# Yield users one at a time:
|
|
977
|
+
yield from response["results"]
|
|
978
|
+
|
|
979
|
+
# See if we have an additional result page.
|
|
980
|
+
# If not terminate the iterator and return
|
|
981
|
+
# no value.
|
|
982
|
+
|
|
983
|
+
next_page_url = response["_links"].get("next")
|
|
984
|
+
if not next_page_url:
|
|
985
|
+
# Don't return None! Plain return is what we need for iterators.
|
|
986
|
+
# Natural Termination: If the generator does not yield, it behaves
|
|
987
|
+
# like an empty iterable when used in a loop or converted to a list:
|
|
988
|
+
return
|
|
989
|
+
next_page_url = next_page_url.get("href")
|
|
990
|
+
|
|
991
|
+
# Extract the query string from the URL
|
|
992
|
+
query = urlparse(next_page_url).query
|
|
993
|
+
|
|
994
|
+
# Parse the query parameters into a dictionary
|
|
995
|
+
params = parse_qs(query)
|
|
996
|
+
|
|
997
|
+
# Get the 'offset' value as an integer (it's a list by default)
|
|
998
|
+
offset = int(params.get("offset", [0])[0])
|
|
999
|
+
|
|
1000
|
+
# end method definition
|
|
1001
|
+
|
|
936
1002
|
def add_group(
|
|
937
1003
|
self,
|
|
938
1004
|
group_name: str,
|
|
@@ -1276,7 +1342,7 @@ class CoreShare:
|
|
|
1276
1342
|
dict | None:
|
|
1277
1343
|
Dictionary with the Core Share group data or None if the request fails.
|
|
1278
1344
|
|
|
1279
|
-
Example
|
|
1345
|
+
Example Response:
|
|
1280
1346
|
{
|
|
1281
1347
|
'results': [
|
|
1282
1348
|
{
|
|
@@ -1343,15 +1409,15 @@ class CoreShare:
|
|
|
1343
1409
|
|
|
1344
1410
|
# end method definition
|
|
1345
1411
|
|
|
1346
|
-
def get_users(self) ->
|
|
1412
|
+
def get_users(self) -> list | None:
|
|
1347
1413
|
"""Get Core Share users.
|
|
1348
1414
|
|
|
1349
1415
|
Args:
|
|
1350
1416
|
None
|
|
1351
1417
|
|
|
1352
1418
|
Returns:
|
|
1353
|
-
|
|
1354
|
-
|
|
1419
|
+
list | None:
|
|
1420
|
+
List with the Core Share user data or None if the request fails.
|
|
1355
1421
|
|
|
1356
1422
|
Example response (it is a list!):
|
|
1357
1423
|
[
|
|
@@ -2524,7 +2590,8 @@ class CoreShare:
|
|
|
2524
2590
|
is_confirmed = self.get_result_value(response=user, key="isConfirmed")
|
|
2525
2591
|
if not is_confirmed:
|
|
2526
2592
|
self.logger.info(
|
|
2527
|
-
"User -> %s is not yet confirmed - so it cannot have files to cleanup.",
|
|
2593
|
+
"User -> %s (%s) is not yet confirmed - so it cannot have files to cleanup.",
|
|
2594
|
+
user_login,
|
|
2528
2595
|
user_id,
|
|
2529
2596
|
)
|
|
2530
2597
|
return True
|
|
@@ -2546,14 +2613,15 @@ class CoreShare:
|
|
|
2546
2613
|
# Get all folders of the user:
|
|
2547
2614
|
response = self.get_folders(parent_id=user_root_folder_id)
|
|
2548
2615
|
if not response or not response["results"]:
|
|
2549
|
-
self.logger.info("User -> %s has no items to cleanup!", user_id)
|
|
2616
|
+
self.logger.info("User -> %s (%s) has no items to cleanup!", user_login, user_id)
|
|
2550
2617
|
else:
|
|
2551
2618
|
items = response["results"]
|
|
2552
2619
|
for item in items:
|
|
2553
2620
|
if item["isShared"]:
|
|
2554
2621
|
if item["owner"]["id"] == user_id:
|
|
2555
2622
|
self.logger.info(
|
|
2556
|
-
"User -> %s stops sharing item -> %s (%s)...",
|
|
2623
|
+
"User -> %s (%s) stops sharing item -> %s (%s)...",
|
|
2624
|
+
user_login,
|
|
2557
2625
|
user_id,
|
|
2558
2626
|
item["name"],
|
|
2559
2627
|
item["id"],
|
|
@@ -857,6 +857,10 @@ class Data:
|
|
|
857
857
|
columns = existing_columns
|
|
858
858
|
|
|
859
859
|
# Attempt to save the data frame to Excel:
|
|
860
|
+
if self._df is None:
|
|
861
|
+
self.logger.error(
|
|
862
|
+
"Cannot write Excel file -> '%s' from empty / non-initialized data frame!", excel_path
|
|
863
|
+
)
|
|
860
864
|
self._df.to_excel(
|
|
861
865
|
excel_path,
|
|
862
866
|
sheet_name=sheet_name,
|
|
@@ -868,29 +872,17 @@ class Data:
|
|
|
868
872
|
excel_path,
|
|
869
873
|
)
|
|
870
874
|
|
|
871
|
-
except FileNotFoundError:
|
|
872
|
-
self.logger.error(
|
|
873
|
-
"Cannot write data frame to Excel file -> '%s'",
|
|
874
|
-
excel_path,
|
|
875
|
-
)
|
|
875
|
+
except FileNotFoundError as fnf_error:
|
|
876
|
+
self.logger.error("Cannot write data frame to Excel file -> '%s'; error -> %s", excel_path, str(fnf_error))
|
|
876
877
|
return False
|
|
877
|
-
except PermissionError:
|
|
878
|
-
self.logger.error(
|
|
879
|
-
"Cannot write data frame to Excel file -> '%s'",
|
|
880
|
-
excel_path,
|
|
881
|
-
)
|
|
878
|
+
except PermissionError as pe:
|
|
879
|
+
self.logger.error("Cannot write data frame to Excel file -> '%s'; error -> %s", excel_path, str(pe))
|
|
882
880
|
return False
|
|
883
|
-
except ValueError:
|
|
884
|
-
self.logger.error(
|
|
885
|
-
"Cannot write data frame to Excel file -> '%s'",
|
|
886
|
-
excel_path,
|
|
887
|
-
)
|
|
881
|
+
except ValueError as ve:
|
|
882
|
+
self.logger.error("Cannot write data frame to Excel file -> '%s'; error -> %s", excel_path, str(ve))
|
|
888
883
|
return False
|
|
889
|
-
except OSError:
|
|
890
|
-
self.logger.error(
|
|
891
|
-
"Cannot write data frame to Excel file -> '%s'",
|
|
892
|
-
excel_path,
|
|
893
|
-
)
|
|
884
|
+
except OSError as ose:
|
|
885
|
+
self.logger.error("Cannot write data frame to Excel file -> '%s'; error -> %s", excel_path, str(ose))
|
|
894
886
|
return False
|
|
895
887
|
|
|
896
888
|
return True
|
|
@@ -1418,7 +1410,7 @@ class Data:
|
|
|
1418
1410
|
for value in values:
|
|
1419
1411
|
# Do we want a special treatment for this value (e.g. the current year)
|
|
1420
1412
|
if value in special_values:
|
|
1421
|
-
self.logger.
|
|
1413
|
+
self.logger.debug("Processing special value -> '%s'...", value)
|
|
1422
1414
|
if value not in special_url_templates and str(value) not in special_url_templates:
|
|
1423
1415
|
self.logger.error(
|
|
1424
1416
|
"Cannot find key -> '%s' in special URL templates dictionary -> %s! Skipping...",
|
|
@@ -2135,7 +2127,7 @@ class Data:
|
|
|
2135
2127
|
)
|
|
2136
2128
|
continue
|
|
2137
2129
|
# Apply cleansing to dictionary values in the main column
|
|
2138
|
-
self.logger.
|
|
2130
|
+
self.logger.debug(
|
|
2139
2131
|
"Cleansing for column -> '%s' has a subfield -> '%s' configured. Do cleansing for dictionary items with key -> '%s'...",
|
|
2140
2132
|
column,
|
|
2141
2133
|
dict_key,
|
|
@@ -2173,7 +2165,7 @@ class Data:
|
|
|
2173
2165
|
# Handle string columns:
|
|
2174
2166
|
if self.is_string_column(self._df[column]):
|
|
2175
2167
|
# Apply cleansing operations on string column
|
|
2176
|
-
self.logger.
|
|
2168
|
+
self.logger.debug(
|
|
2177
2169
|
"Column -> '%s' has string values. Do cleansing for string values...",
|
|
2178
2170
|
column,
|
|
2179
2171
|
)
|
|
@@ -2203,7 +2195,7 @@ class Data:
|
|
|
2203
2195
|
elif self.is_list_column(self._df[column]):
|
|
2204
2196
|
# Handle list-like columns for this we iterate over each list item
|
|
2205
2197
|
# and apply the cleansing by calling _apply_string_cleansing() for item:
|
|
2206
|
-
self.logger.
|
|
2198
|
+
self.logger.debug(
|
|
2207
2199
|
"Column -> '%s' has list values. Do cleansing for each list item...",
|
|
2208
2200
|
column,
|
|
2209
2201
|
)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Define OpenTelemtry configuration."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
from opentelemetry import trace
|
|
6
|
+
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
|
|
7
|
+
from opentelemetry.instrumentation.requests import RequestsInstrumentor
|
|
8
|
+
from opentelemetry.instrumentation.threading import ThreadingInstrumentor
|
|
9
|
+
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
|
|
10
|
+
from opentelemetry.sdk.trace import TracerProvider
|
|
11
|
+
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
|
12
|
+
|
|
13
|
+
resource = Resource.create(attributes={SERVICE_NAME: "pyxecm"})
|
|
14
|
+
|
|
15
|
+
trace.set_tracer_provider(TracerProvider(resource=resource))
|
|
16
|
+
|
|
17
|
+
if os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT"):
|
|
18
|
+
trace.get_tracer_provider().add_span_processor(
|
|
19
|
+
BatchSpanProcessor(OTLPSpanExporter()),
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# Auto-instrument requests
|
|
23
|
+
RequestsInstrumentor().instrument()
|
|
24
|
+
ThreadingInstrumentor().instrument()
|
|
25
|
+
|
|
26
|
+
tracer = trace.get_tracer("pyxecm")
|
|
@@ -326,8 +326,7 @@ class HTTP:
|
|
|
326
326
|
)
|
|
327
327
|
os.makedirs(directory)
|
|
328
328
|
with open(filename, "wb") as download_file:
|
|
329
|
-
|
|
330
|
-
download_file.write(chunk)
|
|
329
|
+
download_file.writelines(response.iter_content(chunk_size=chunk_size))
|
|
331
330
|
self.logger.debug(
|
|
332
331
|
"File downloaded successfully as -> '%s' (size -> %s).",
|
|
333
332
|
filename,
|