pyxecm 3.4.4__tar.gz → 3.4.6__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.
Files changed (72) hide show
  1. {pyxecm-3.4.4 → pyxecm-3.4.6}/PKG-INFO +1 -1
  2. {pyxecm-3.4.4 → pyxecm-3.4.6}/pyproject.toml +1 -1
  3. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/otcs.py +98 -6
  4. {pyxecm-3.4.4 → pyxecm-3.4.6}/.gitignore +0 -0
  5. {pyxecm-3.4.4 → pyxecm-3.4.6}/README.md +0 -0
  6. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/__init__.py +0 -0
  7. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/avts.py +0 -0
  8. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/coreshare.py +0 -0
  9. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/helper/__init__.py +0 -0
  10. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/helper/assoc.py +0 -0
  11. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/helper/data.py +0 -0
  12. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/helper/logadapter.py +0 -0
  13. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/helper/web.py +0 -0
  14. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/helper/xml.py +0 -0
  15. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/otac.py +0 -0
  16. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/otawp.py +0 -0
  17. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/otca.py +0 -0
  18. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/otds.py +0 -0
  19. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/otiv.py +0 -0
  20. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/otkd.py +0 -0
  21. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/otmm.py +0 -0
  22. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/otpd.py +0 -0
  23. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm/py.typed +0 -0
  24. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/__init__.py +0 -0
  25. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/__main__.py +0 -0
  26. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/app.py +0 -0
  27. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/auth/__init__.py +0 -0
  28. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/auth/functions.py +0 -0
  29. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/auth/models.py +0 -0
  30. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/auth/router.py +0 -0
  31. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/common/__init__.py +0 -0
  32. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/common/functions.py +0 -0
  33. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/common/metrics.py +0 -0
  34. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/common/models.py +0 -0
  35. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/common/router.py +0 -0
  36. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/settings.py +0 -0
  37. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/terminal/__init__.py +0 -0
  38. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/terminal/router.py +0 -0
  39. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/v1_maintenance/__init__.py +0 -0
  40. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/v1_maintenance/functions.py +0 -0
  41. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/v1_maintenance/models.py +0 -0
  42. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/v1_maintenance/router.py +0 -0
  43. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/v1_otcs/__init__.py +0 -0
  44. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/v1_otcs/functions.py +0 -0
  45. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/v1_otcs/router.py +0 -0
  46. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/v1_payload/__init__.py +0 -0
  47. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/v1_payload/functions.py +0 -0
  48. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/v1_payload/models.py +0 -0
  49. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_api/v1_payload/router.py +0 -0
  50. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/__init__.py +0 -0
  51. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/__main__.py +0 -0
  52. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/browser_automation.py +0 -0
  53. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/customizer.py +0 -0
  54. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/exceptions.py +0 -0
  55. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/guidewire.py +0 -0
  56. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/k8s.py +0 -0
  57. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/log.py +0 -0
  58. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/m365.py +0 -0
  59. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/payload.py +0 -0
  60. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/payload_list.py +0 -0
  61. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/salesforce.py +0 -0
  62. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/sap.py +0 -0
  63. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/servicenow.py +0 -0
  64. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/settings.py +0 -0
  65. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/successfactors.py +0 -0
  66. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_customizer/translate.py +0 -0
  67. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_maintenance_page/__init__.py +0 -0
  68. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_maintenance_page/__main__.py +0 -0
  69. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_maintenance_page/app.py +0 -0
  70. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_maintenance_page/settings.py +0 -0
  71. {pyxecm-3.4.4 → pyxecm-3.4.6}/src/pyxecm_maintenance_page/static/favicon.avif +0 -0
  72. {pyxecm-3.4.4 → pyxecm-3.4.6}/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.4
3
+ Version: 3.4.6
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>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pyxecm"
3
- version = "3.4.4"
3
+ version = "3.4.6"
4
4
  description = 'A Python library to interact with Opentext Content Management Rest API'
5
5
  keywords = [
6
6
  'opentext',
@@ -8528,6 +8528,9 @@ class OTCS:
8528
8528
  str(volume_type),
8529
8529
  )
8530
8530
 
8531
+ if not mime_type:
8532
+ mime_type = "application/octet-stream" # Default to binary stream if mime type cannot be determined
8533
+
8531
8534
  upload_post_files = [("file", (f"{file_name}", file_content, mime_type))]
8532
8535
 
8533
8536
  request_url = self.config()["nodesUrlv2"]
@@ -8819,6 +8822,9 @@ class OTCS:
8819
8822
  parent_id,
8820
8823
  )
8821
8824
 
8825
+ if not mime_type:
8826
+ mime_type = "application/octet-stream" # Default to binary stream if mime type cannot be determined
8827
+
8822
8828
  upload_post_files = [("file", (f"{file_name}", file_content, mime_type))]
8823
8829
 
8824
8830
  request_url = self.config()["nodesUrlv2"]
@@ -9187,6 +9193,9 @@ class OTCS:
9187
9193
  node_id,
9188
9194
  )
9189
9195
 
9196
+ if not mime_type:
9197
+ mime_type = "application/octet-stream" # Default to binary stream if mime type cannot be determined
9198
+
9190
9199
  upload_post_files = [("file", (f"{file_name}", file_content, mime_type))]
9191
9200
 
9192
9201
  request_url = self.config()["nodesUrlv2"] + "/" + str(node_id) + "/versions"
@@ -13538,16 +13547,22 @@ class OTCS:
13538
13547
  # end method definition
13539
13548
 
13540
13549
  @tracer.start_as_current_span(attributes=OTEL_TRACING_ATTRIBUTES, name="get_workspace_type_name")
13541
- def get_workspace_type_name(self, type_id: int) -> str | None:
13550
+ def get_workspace_type_name(self, type_id: int, renew: bool = False) -> str | None:
13542
13551
  """Get the name of a workspace type based on the provided workspace type ID.
13543
13552
 
13544
13553
  The name is taken from a OTCS object variable self._workspace_type_lookup if recorded there.
13545
- If not yet derived it is determined via the REST API and then stored
13546
- in self._workspace_type_lookup (as a lookup cache).
13554
+ If not yet derived - or if renew is requested - it is determined via the REST API and
13555
+ then stored in self._workspace_type_lookup (as a lookup cache).
13547
13556
 
13548
13557
  Args:
13549
13558
  type_id (int):
13550
13559
  The workspace type ID.
13560
+ renew (bool, optional):
13561
+ Whether to bypass the cache and force a fresh lookup via the REST API,
13562
+ updating the cache entry. Useful for callers that cannot tolerate a
13563
+ workspace type having been renamed/reconfigured since it was last cached
13564
+ (self._workspace_type_lookup has no expiry and is shared across calls
13565
+ for the lifetime of this OTCS instance).
13551
13566
 
13552
13567
  Returns:
13553
13568
  str | None:
@@ -13561,7 +13576,7 @@ class OTCS:
13561
13576
  """
13562
13577
 
13563
13578
  workspace_type = self._workspace_type_lookup.get(type_id)
13564
- if workspace_type:
13579
+ if workspace_type and not renew:
13565
13580
  return workspace_type.get("name")
13566
13581
 
13567
13582
  workspace_type = self.get_workspace_type(type_id=type_id)
@@ -14654,6 +14669,71 @@ class OTCS:
14654
14669
 
14655
14670
  # end method definition
14656
14671
 
14672
+ @tracer.start_as_current_span(attributes=OTEL_TRACING_ATTRIBUTES, name="get_workspace_by_child_node")
14673
+ def get_workspace_by_child_node(
14674
+ self,
14675
+ node_id: int,
14676
+ timeout: float = REQUEST_TIMEOUT,
14677
+ show_error: bool = False,
14678
+ ) -> dict | None:
14679
+ """Get the business workspace a given node is located in.
14680
+
14681
+ The node can be a direct or indirect child of the workspace.
14682
+ If the given node is a business workspace itself, then this
14683
+ workspace is returned.
14684
+
14685
+ The REST API endpoint of this method is /v1/nodes/{id}/businessworkspace
14686
+
14687
+ Args:
14688
+ node_id (int):
14689
+ The ID of the node to determine the enclosing workspace for.
14690
+ timeout (float, optional):
14691
+ Specific timeout for the request in seconds. The default is the standard
14692
+ timeout value REQUEST_TIMEOUT used by the OTCS module.
14693
+ show_error (bool, optional):
14694
+ Treat it as an error if no enclosing workspace is found.
14695
+ Default is False (just a warning is logged).
14696
+
14697
+ Returns:
14698
+ dict | None:
14699
+ Workspace information or None if the node is not inside a workspace.
14700
+
14701
+ Example:
14702
+ {
14703
+ 'id': 346184,
14704
+ 'isLinked': False,
14705
+ 'type': 848,
14706
+ 'workspace_type_id': 5
14707
+ }
14708
+
14709
+ """
14710
+
14711
+ request_url = self.config()["nodesUrl"] + "/" + str(node_id) + "/businessworkspace"
14712
+
14713
+ request_header = self.request_form_header()
14714
+
14715
+ self.logger.debug(
14716
+ "Get business workspace for node with ID -> %d; calling -> %s",
14717
+ node_id,
14718
+ request_url,
14719
+ )
14720
+
14721
+ return self.do_request(
14722
+ url=request_url,
14723
+ method="GET",
14724
+ headers=request_header,
14725
+ timeout=timeout,
14726
+ warning_message="Cannot get business workspace for node with ID -> {}. The node may not be inside a workspace.".format(
14727
+ node_id,
14728
+ ),
14729
+ failure_message="Failed to get business workspace for node with ID -> {}".format(
14730
+ node_id,
14731
+ ),
14732
+ show_error=show_error,
14733
+ )
14734
+
14735
+ # end method definition
14736
+
14657
14737
  @tracer.start_as_current_span(attributes=OTEL_TRACING_ATTRIBUTES, name="lookup_workspace")
14658
14738
  def lookup_workspaces(
14659
14739
  self,
@@ -23986,6 +24066,12 @@ class OTCS:
23986
24066
  for workspace_type in workspace_types:
23987
24067
  wksp_type_id = self.get_result_value(response=workspace_type, key="wksp_type_id")
23988
24068
  wksp_type_name = self.get_result_value(response=workspace_type, key="wksp_type_name")
24069
+ # Refresh the shared lookup cache with the current name (see the equivalent
24070
+ # refresh in traverse_workspaces_parallel's init_traversal_queue for why this
24071
+ # must overwrite rather than only fill in missing entries): this keeps
24072
+ # get_workspace_type_name() calls made later in this traversal (e.g. from
24073
+ # traverse_workspace()) from resolving a stale, previously-cached name.
24074
+ self._workspace_type_lookup[wksp_type_id] = {"location": None, "name": wksp_type_name}
23989
24075
  if not self._check_filter(
23990
24076
  workspace_type_name=wksp_type_name,
23991
24077
  workspace_type_id=wksp_type_id,
@@ -24335,8 +24421,14 @@ class OTCS:
24335
24421
  for workspace_type in workspace_types:
24336
24422
  wksp_type_id = self.get_result_value(response=workspace_type, key="wksp_type_id")
24337
24423
  wksp_type_name = self.get_result_value(response=workspace_type, key="wksp_type_name")
24338
- if wksp_type_id not in self._workspace_type_lookup:
24339
- self._workspace_type_lookup[wksp_type_id] = {"location": None, "name": wksp_type_name}
24424
+ # Refresh (not just fill-if-missing): this is a fresh, current listing of
24425
+ # workspace types, fetched on every traversal run. self._workspace_type_lookup
24426
+ # is a long-lived cache on this OTCS instance (spans many traversal runs over the
24427
+ # life of the process), so if we only filled in missing entries, a renamed
24428
+ # workspace type would keep resolving to its stale old name here - and via
24429
+ # get_workspace_type_name() - forever. Overwriting is free since we already have
24430
+ # the current name from this iteration; no extra API call is needed.
24431
+ self._workspace_type_lookup[wksp_type_id] = {"location": None, "name": wksp_type_name}
24340
24432
  if not self._check_filter(
24341
24433
  workspace_type_name=wksp_type_name,
24342
24434
  workspace_type_id=wksp_type_id,
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