pyxecm 3.0.1__py3-none-any.whl → 3.1.1__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.

Files changed (52) hide show
  1. pyxecm/avts.py +4 -4
  2. pyxecm/coreshare.py +14 -15
  3. pyxecm/helper/data.py +2 -1
  4. pyxecm/helper/web.py +11 -11
  5. pyxecm/helper/xml.py +41 -10
  6. pyxecm/otac.py +1 -1
  7. pyxecm/otawp.py +19 -19
  8. pyxecm/otca.py +878 -70
  9. pyxecm/otcs.py +1716 -349
  10. pyxecm/otds.py +332 -153
  11. pyxecm/otkd.py +4 -4
  12. pyxecm/otmm.py +1 -1
  13. pyxecm/otpd.py +246 -30
  14. {pyxecm-3.0.1.dist-info → pyxecm-3.1.1.dist-info}/METADATA +2 -1
  15. pyxecm-3.1.1.dist-info/RECORD +82 -0
  16. pyxecm_api/app.py +45 -35
  17. pyxecm_api/auth/functions.py +2 -2
  18. pyxecm_api/auth/router.py +2 -3
  19. pyxecm_api/common/functions.py +67 -12
  20. pyxecm_api/settings.py +0 -8
  21. pyxecm_api/terminal/router.py +1 -1
  22. pyxecm_api/v1_csai/router.py +33 -18
  23. pyxecm_customizer/browser_automation.py +161 -79
  24. pyxecm_customizer/customizer.py +43 -25
  25. pyxecm_customizer/guidewire.py +422 -8
  26. pyxecm_customizer/k8s.py +23 -27
  27. pyxecm_customizer/knowledge_graph.py +498 -20
  28. pyxecm_customizer/m365.py +45 -44
  29. pyxecm_customizer/payload.py +1723 -1188
  30. pyxecm_customizer/payload_list.py +3 -0
  31. pyxecm_customizer/salesforce.py +122 -79
  32. pyxecm_customizer/servicenow.py +27 -7
  33. pyxecm_customizer/settings.py +3 -1
  34. pyxecm_customizer/successfactors.py +2 -2
  35. pyxecm_customizer/translate.py +1 -1
  36. pyxecm-3.0.1.dist-info/RECORD +0 -96
  37. pyxecm_api/agents/__init__.py +0 -7
  38. pyxecm_api/agents/app.py +0 -13
  39. pyxecm_api/agents/functions.py +0 -119
  40. pyxecm_api/agents/models.py +0 -10
  41. pyxecm_api/agents/otcm_knowledgegraph/__init__.py +0 -1
  42. pyxecm_api/agents/otcm_knowledgegraph/functions.py +0 -85
  43. pyxecm_api/agents/otcm_knowledgegraph/models.py +0 -61
  44. pyxecm_api/agents/otcm_knowledgegraph/router.py +0 -74
  45. pyxecm_api/agents/otcm_user_agent/__init__.py +0 -1
  46. pyxecm_api/agents/otcm_user_agent/models.py +0 -20
  47. pyxecm_api/agents/otcm_user_agent/router.py +0 -65
  48. pyxecm_api/agents/otcm_workspace_agent/__init__.py +0 -1
  49. pyxecm_api/agents/otcm_workspace_agent/models.py +0 -40
  50. pyxecm_api/agents/otcm_workspace_agent/router.py +0 -200
  51. {pyxecm-3.0.1.dist-info → pyxecm-3.1.1.dist-info}/WHEEL +0 -0
  52. {pyxecm-3.0.1.dist-info → pyxecm-3.1.1.dist-info}/entry_points.txt +0 -0
@@ -5,6 +5,7 @@ import os
5
5
  from typing import Annotated
6
6
 
7
7
  from fastapi import Depends
8
+ from pyxecm.otca import OTCA
8
9
  from pyxecm.otcs import OTCS
9
10
  from pyxecm_customizer import K8s, PayloadList, Settings
10
11
 
@@ -31,12 +32,14 @@ def get_k8s_object() -> K8s:
31
32
 
32
33
 
33
34
  def get_otcs_object() -> OTCS:
34
- """Get an instance of a K8s object.
35
+ """Get an instance of a Content Server (OTCS) object.
35
36
 
36
37
  Returns:
37
- K8s: Return a K8s object
38
+ OTCS:
39
+ Return a new OTCS object.
38
40
 
39
41
  """
42
+
40
43
  settings = Settings()
41
44
 
42
45
  otcs = OTCS(
@@ -52,27 +55,34 @@ def get_otcs_object() -> OTCS:
52
55
  support_path=settings.otcs.support_path,
53
56
  download_dir=settings.otcs.download_dir,
54
57
  feme_uri=settings.otcs.feme_uri,
55
- logger=logger.getChild("otcs"),
58
+ logger=logger,
56
59
  )
57
60
 
61
+ # Authenticate at Content Server:
58
62
  otcs.authenticate()
59
63
 
60
64
  return otcs
61
65
 
62
66
 
63
- def get_otcs_object_from_otcsticket(otcsticket: Annotated[str, Depends(get_otcsticket)]) -> OTCS:
64
- """Get an instance of a K8s object.
67
+ def get_otcs_object_from_otcsticket(otcs_ticket: Annotated[str, Depends(get_otcsticket)]) -> OTCS:
68
+ """Get an instance of a Content Server (OTCS) object.
65
69
 
66
70
  Returns:
67
- K8s: Return a K8s object
71
+ OTCS:
72
+ Return an OTCS object.
68
73
 
69
74
  """
75
+
70
76
  settings = Settings()
71
77
 
78
+ # Create an OTCS object without defining the username and password:
72
79
  otcs = OTCS(
73
- protocol=settings.otcs.url_backend.scheme,
74
- hostname=settings.otcs.url_backend.host,
75
- port=settings.otcs.url_backend.port,
80
+ # protocol=settings.otcs.url_backend.scheme,
81
+ # hostname=settings.otcs.url_backend.host,
82
+ # port=settings.otcs.url_backend.port,
83
+ protocol=settings.otcs.url_frontend.scheme,
84
+ hostname=settings.otcs.url_frontend.host,
85
+ port=settings.otcs.url_frontend.port,
76
86
  public_url=str(settings.otcs.url),
77
87
  user_partition=settings.otcs.partition,
78
88
  resource_name=settings.otcs.resource_name,
@@ -80,19 +90,62 @@ def get_otcs_object_from_otcsticket(otcsticket: Annotated[str, Depends(get_otcst
80
90
  support_path=settings.otcs.support_path,
81
91
  download_dir=settings.otcs.download_dir,
82
92
  feme_uri=settings.otcs.feme_uri,
83
- logger=logger.getChild("otcs"),
93
+ logger=logger,
84
94
  )
85
95
 
86
- otcs._otcs_ticket = otcsticket # noqa: SLF001
96
+ # Instead set the OTCS authentication ticket directly:
97
+ otcs._otcs_ticket = otcs_ticket # noqa: SLF001
87
98
 
88
99
  return otcs
89
100
 
90
101
 
102
+ def get_otca_object(otcs_object: OTCS | None = None) -> OTCA:
103
+ """Get the Content Aviator (OTCA) object.
104
+
105
+ Args:
106
+ otcs_object (OTCS | None, optional):
107
+ The Content Server (OTCS) object. Defaults to None.
108
+
109
+ Returns:
110
+ OTCA:
111
+ The new Content Aviator object.
112
+
113
+ """
114
+
115
+ settings = Settings()
116
+
117
+ # Get the Kubernetes object:
118
+ k8s_object = get_k8s_object()
119
+ content_system = {}
120
+ # Read the content system (e.g. OTCM) from the Kubernetes Config Map:
121
+ for service in ["chat", "embed"]:
122
+ cm = k8s_object.get_config_map(f"csai-{service}-svc")
123
+ if cm:
124
+ content_system[service] = cm.data.get("CONTENT_SYSTEM", "none")
125
+ logger.info("Set content system for '%s' to -> '%s'.", service, content_system[service])
126
+
127
+ # Create the Content Aviator object (OTCA class):
128
+ otca = OTCA(
129
+ chat_url=str(settings.aviator.chat_svc_url),
130
+ embed_url=str(settings.aviator.embed_svc_url),
131
+ studio_url=str(settings.aviator.studio_url),
132
+ otds_url=str(settings.otds.url_internal),
133
+ client_id=settings.aviator.oauth_client,
134
+ client_secret=settings.aviator.oauth_secret,
135
+ otcs_object=otcs_object,
136
+ content_system=content_system,
137
+ logger=logger.getChild("otca"),
138
+ )
139
+
140
+ return otca
141
+
142
+
91
143
  def get_settings() -> CustomizerAPISettings:
92
144
  """Get the API Settings object.
93
145
 
94
146
  Returns:
95
- CustomizerPISettings: Returns the API Settings
147
+ CustomizerPISettings:
148
+ Returns the API Settings.
96
149
 
97
150
  """
98
151
 
@@ -112,6 +165,7 @@ def get_otcs_logs_lock() -> dict:
112
165
 
113
166
  def list_files_in_directory(directory: str) -> dict:
114
167
  """Recursively list files in a directory and return a nested JSON structure with URLs."""
168
+
115
169
  result = {}
116
170
  for root, dirs, files in os.walk(directory):
117
171
  # Sort directories and files alphabetically
@@ -128,4 +182,5 @@ def list_files_in_directory(directory: str) -> dict:
128
182
  for file in files:
129
183
  file_path = os.path.join(relative_path, file)
130
184
  current_level[file] = file_path
185
+
131
186
  return result
pyxecm_api/settings.py CHANGED
@@ -56,9 +56,6 @@ class CustomizerAPISettings(BaseSettings):
56
56
  )
57
57
 
58
58
  loglevel: Literal["INFO", "DEBUG", "WARNING", "ERROR"] = "INFO"
59
- log_payload_processing: bool = Field(
60
- default=False, description="Print the customizer payload processing log messages to stdout"
61
- )
62
59
  logfolder: str = Field(
63
60
  default=os.path.join(tempfile.gettempdir(), "customizer"),
64
61
  description="Logfolder for Customizer logfiles",
@@ -122,11 +119,6 @@ class CustomizerAPISettings(BaseSettings):
122
119
  description="Prefix for the CSAI",
123
120
  )
124
121
 
125
- csai_studio_integration: bool = Field(
126
- default=False,
127
- description="Enable the CSAI Studio Integration",
128
- )
129
-
130
122
  upload_folder: str = Field(default=os.path.join(tempfile.gettempdir(), "upload"), description="Folder for uploads")
131
123
 
132
124
  upload_key: str = Field(default=str(uuid.uuid4()), description="Upload key for the Logs")
@@ -93,7 +93,7 @@ async def ws_terminal(
93
93
  read_task = asyncio.create_task(read_from_pty())
94
94
  write_task = asyncio.create_task(write_to_pty())
95
95
 
96
- done, pending = await asyncio.wait([read_task, write_task], return_when=asyncio.FIRST_COMPLETED)
96
+ _done, pending = await asyncio.wait([read_task, write_task], return_when=asyncio.FIRST_COMPLETED)
97
97
 
98
98
  # Cancel other task
99
99
  for task in pending:
@@ -4,15 +4,14 @@ import logging
4
4
  from http import HTTPStatus
5
5
  from typing import Annotated
6
6
 
7
- from fastapi import APIRouter, Body, Depends, Query
7
+ from fastapi import APIRouter, Body, Depends, HTTPException, Query
8
8
  from fastapi.responses import HTMLResponse, JSONResponse
9
9
  from pyxecm.otcs import OTCS
10
10
  from pyxecm_customizer.k8s import K8s
11
11
 
12
- from pyxecm_api.agents.functions import get_otca_object
13
12
  from pyxecm_api.auth.functions import get_authorized_user
14
13
  from pyxecm_api.auth.models import User
15
- from pyxecm_api.common.functions import get_k8s_object, get_otcs_object, get_settings
14
+ from pyxecm_api.common.functions import get_k8s_object, get_otca_object, get_otcs_object, get_settings
16
15
  from pyxecm_api.settings import CustomizerAPISettings
17
16
 
18
17
  from .models import CSAIEmbedMetadata
@@ -31,12 +30,16 @@ def embed_metadata(
31
30
  """Embed the Metadata of the given objects.
32
31
 
33
32
  Args:
34
- user (Annotated[User, Depends): User required for authentication
35
- otcs_object (Annotated[OTCS, Depends(get_otcs_object)]): OTCS object to interact with OTCS
36
- body (Annotated[CSAIEmbedMetadata, Body): Request body
33
+ user (Annotated[User, Depends):
34
+ User required for authentication.
35
+ otcs_object (Annotated[OTCS, Depends(get_otcs_object)]):
36
+ The OTCS object to interact with OTCM (Content Server).
37
+ body (Annotated[CSAIEmbedMetadata, Body):
38
+ The request body.
37
39
 
38
40
  Returns:
39
- JSONResponse: JSONResponse with success=true/false
41
+ JSONResponse:
42
+ JSONResponse with success=true/false
40
43
 
41
44
  """
42
45
 
@@ -53,7 +56,7 @@ def get_csai_config_data(
53
56
  ) -> JSONResponse:
54
57
  """Get the csai config data."""
55
58
 
56
- logger.info("READ csai config data by user -> %s", user.id)
59
+ logger.info("Read CSAI config data by user -> %s", user.id)
57
60
 
58
61
  config_data = {}
59
62
 
@@ -79,9 +82,9 @@ def set_csai_config_data(
79
82
  k8s_object: Annotated[K8s, Depends(get_k8s_object)],
80
83
  config: Annotated[dict, Body()],
81
84
  ) -> JSONResponse:
82
- """Get the csai config data."""
85
+ """Set the CSAI config data."""
83
86
 
84
- logger.info("READ csai config data by user -> %s", user.id)
87
+ logger.info("Write CSAI config data by user -> %s", user.id)
85
88
 
86
89
  for config_map in config:
87
90
  if not config_map.startswith(settings.csai_prefix):
@@ -115,27 +118,39 @@ def set_csai_config_data(
115
118
 
116
119
 
117
120
  @router.get("/graph")
118
- def get_csai_graph(name: Annotated[str, Query(..., description="Name of the Graph")]) -> HTMLResponse:
121
+ def get_csai_graph(name: Annotated[str, Query(..., description="Name of the graph")]) -> HTMLResponse:
119
122
  """Display the graph of the given name.
120
123
 
121
124
  Args:
122
- otca (Annotated[OTCA, Depends): Generic OTCA Objec
123
- name (str): name of the graph
125
+ name (str):
126
+ The name of the CSAI graph.
124
127
 
125
128
  Returns:
126
- HTMLResponse: _description_
129
+ HTMLResponse: Visualization of the CSAI graph
127
130
 
128
131
  """
132
+
133
+ # Get the Content Aviator object:
129
134
  otca = get_otca_object(otcs_object=None)
130
135
 
136
+ # Get all graphs configured in Content Aviator:
131
137
  graphs = otca.get_graphs()
138
+ # Find the graph (LangGraph) with the given name:
132
139
  graph = [g for g in graphs if g["name"] == name]
133
140
 
134
- if graph:
141
+ if not graph:
142
+ logger.error("Couldn't find graph -> '%s' for visualization!", name)
143
+ raise HTTPException(status_code=404, detail="Graph -> '{}' not found!".format(name))
144
+
145
+ try:
135
146
  filename = otca.visualize_graph(graph[0]["id"])
136
147
 
137
- with open(filename) as f:
138
- file_content = f.read()
148
+ with open(filename) as f:
149
+ file_content = f.read()
150
+ except Exception as e:
151
+ logger.error("Error visualizing graph -> '%s': %s", name, str(e))
152
+ raise HTTPException(status_code=500, detail="Failed to visualize graph -> '{}'!".format(name)) from e
153
+
154
+ logger.info("Successfully visualized graph -> '%s'", name)
139
155
 
140
- logger.info("name: %s", name)
141
156
  return HTMLResponse(status_code=200, content=file_content)