lexsi-sdk 0.1.16__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.
- lexsi_sdk/__init__.py +5 -0
- lexsi_sdk/client/__init__.py +0 -0
- lexsi_sdk/client/client.py +176 -0
- lexsi_sdk/common/__init__.py +0 -0
- lexsi_sdk/common/config/.env.prod +3 -0
- lexsi_sdk/common/constants.py +143 -0
- lexsi_sdk/common/enums.py +8 -0
- lexsi_sdk/common/environment.py +49 -0
- lexsi_sdk/common/monitoring.py +81 -0
- lexsi_sdk/common/trigger.py +75 -0
- lexsi_sdk/common/types.py +122 -0
- lexsi_sdk/common/utils.py +93 -0
- lexsi_sdk/common/validation.py +110 -0
- lexsi_sdk/common/xai_uris.py +197 -0
- lexsi_sdk/core/__init__.py +0 -0
- lexsi_sdk/core/agent.py +62 -0
- lexsi_sdk/core/alert.py +56 -0
- lexsi_sdk/core/case.py +618 -0
- lexsi_sdk/core/dashboard.py +131 -0
- lexsi_sdk/core/guardrails/__init__.py +0 -0
- lexsi_sdk/core/guardrails/guard_template.py +299 -0
- lexsi_sdk/core/guardrails/guardrail_autogen.py +554 -0
- lexsi_sdk/core/guardrails/guardrails_langgraph.py +525 -0
- lexsi_sdk/core/guardrails/guardrails_openai.py +541 -0
- lexsi_sdk/core/guardrails/openai_runner.py +1328 -0
- lexsi_sdk/core/model_summary.py +110 -0
- lexsi_sdk/core/organization.py +549 -0
- lexsi_sdk/core/project.py +5131 -0
- lexsi_sdk/core/synthetic.py +387 -0
- lexsi_sdk/core/text.py +595 -0
- lexsi_sdk/core/tracer.py +208 -0
- lexsi_sdk/core/utils.py +36 -0
- lexsi_sdk/core/workspace.py +325 -0
- lexsi_sdk/core/wrapper.py +766 -0
- lexsi_sdk/core/xai.py +306 -0
- lexsi_sdk/version.py +34 -0
- lexsi_sdk-0.1.16.dist-info/METADATA +100 -0
- lexsi_sdk-0.1.16.dist-info/RECORD +40 -0
- lexsi_sdk-0.1.16.dist-info/WHEEL +5 -0
- lexsi_sdk-0.1.16.dist-info/top_level.txt +1 -0
lexsi_sdk/core/tracer.py
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
from opentelemetry import trace as trace_api
|
|
2
|
+
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
|
|
3
|
+
from opentelemetry.sdk import trace as trace_sdk
|
|
4
|
+
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor , BatchSpanProcessor
|
|
5
|
+
from opentelemetry.sdk.resources import Resource
|
|
6
|
+
from openinference.instrumentation.langchain import LangChainInstrumentor
|
|
7
|
+
# from openinference.instrumentation.autogen_agent import AutogenInstrumentor
|
|
8
|
+
# from opentelemetry.instrumentation.openai import OpenAIInstrumentor
|
|
9
|
+
from openinference.instrumentation.autogen_agentchat import AutogenAgentChatInstrumentor
|
|
10
|
+
from openinference.instrumentation.crewai import CrewAIInstrumentor
|
|
11
|
+
from openinference.instrumentation.openai_agents import OpenAIAgentsInstrumentor
|
|
12
|
+
from openinference.instrumentation.dspy import DSPyInstrumentor
|
|
13
|
+
from openinference.instrumentation.llama_index import LlamaIndexInstrumentor
|
|
14
|
+
from openinference.instrumentation.smolagents import SmolagentsInstrumentor
|
|
15
|
+
# from pydantic import BaseModel
|
|
16
|
+
import os
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Tracer:
|
|
20
|
+
"""Helpers to instrument various agent frameworks with OpenTelemetry."""
|
|
21
|
+
|
|
22
|
+
def __init__(self):
|
|
23
|
+
"""Initialize exporter endpoint from environment."""
|
|
24
|
+
self.base_url = os.getenv("XAI_API_URL", "https://apiv1.lexsi.ai")
|
|
25
|
+
self.endpoint = f"{self.base_url}"
|
|
26
|
+
def setup_langchain_tracing(self , project: object, session_id : str = None) -> None:
|
|
27
|
+
"""
|
|
28
|
+
Sets up OpenTelemetry tracing for a given project with OTLP and console exporters.
|
|
29
|
+
|
|
30
|
+
:param project: Object containing project details; must expose project_name.
|
|
31
|
+
:param session_id: Optional session identifier to annotate spans.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
# Extract project name or use default
|
|
35
|
+
|
|
36
|
+
project_name = getattr(project, 'project_name')
|
|
37
|
+
# Create resource with service and project details
|
|
38
|
+
resource = Resource(attributes={
|
|
39
|
+
"service.name": "Langgraph",
|
|
40
|
+
"project_name": project_name,
|
|
41
|
+
"session_id": session_id if session_id else "None"
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
# Initialize tracer provider
|
|
45
|
+
tracer_provider = trace_sdk.TracerProvider(resource=resource)
|
|
46
|
+
trace_api.set_tracer_provider(tracer_provider)
|
|
47
|
+
|
|
48
|
+
# Add OTLP and console span processors
|
|
49
|
+
tracer_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter(self.endpoint)))
|
|
50
|
+
# Instrument LangChain
|
|
51
|
+
LangChainInstrumentor().instrument()
|
|
52
|
+
|
|
53
|
+
def setup_autogen_tracing(self ,project: object , session_id : str = None) -> None:
|
|
54
|
+
"""
|
|
55
|
+
Sets up OpenTelemetry tracing for a given project with OTLP and console exporters.
|
|
56
|
+
|
|
57
|
+
:param project: Object containing project details; must expose project_name.
|
|
58
|
+
:param session_id: Optional session identifier to annotate spans.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
# Extract project name or use default
|
|
62
|
+
|
|
63
|
+
project_name = getattr(project, 'project_name')
|
|
64
|
+
# Create resource with service and project details
|
|
65
|
+
resource = Resource(attributes={
|
|
66
|
+
"service.name": "Autogen",
|
|
67
|
+
"project_name": project_name,
|
|
68
|
+
"session_id": session_id if session_id else "None"
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
# Initialize tracer provider
|
|
72
|
+
tracer_provider = trace_sdk.TracerProvider(resource=resource)
|
|
73
|
+
trace_api.set_tracer_provider(tracer_provider)
|
|
74
|
+
|
|
75
|
+
# Add OTLP and console span processors
|
|
76
|
+
tracer_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter(self.endpoint)))
|
|
77
|
+
# Instrument Autogen
|
|
78
|
+
AutogenAgentChatInstrumentor().instrument()
|
|
79
|
+
|
|
80
|
+
def setup_crewai_tracing(self , project: object , session_id : str = None) -> None:
|
|
81
|
+
"""
|
|
82
|
+
Sets up OpenTelemetry tracing for a given project with OTLP and console exporters.
|
|
83
|
+
|
|
84
|
+
:param project: Object containing project details; must expose project_name.
|
|
85
|
+
:param session_id: Optional session identifier to annotate spans.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
# Extract project name or use default
|
|
89
|
+
|
|
90
|
+
project_name = getattr(project, 'project_name')
|
|
91
|
+
# Create resource with service and project details
|
|
92
|
+
resource = Resource(attributes={
|
|
93
|
+
"service.name": "Crewai",
|
|
94
|
+
"project_name": project_name,
|
|
95
|
+
"session_id": session_id if session_id else "None"
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
# Initialize tracer provider
|
|
99
|
+
tracer_provider = trace_sdk.TracerProvider(resource=resource)
|
|
100
|
+
trace_api.set_tracer_provider(tracer_provider)
|
|
101
|
+
|
|
102
|
+
# Add OTLP and console span processors
|
|
103
|
+
tracer_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter(self.endpoint)))
|
|
104
|
+
# tracer_provider.add_span_processor(ConsoleSpanExporter())
|
|
105
|
+
# Instrument CrewAI
|
|
106
|
+
CrewAIInstrumentor().instrument()
|
|
107
|
+
|
|
108
|
+
def setup_agents_tracing(self , project : object , session_id : str = None) -> None:
|
|
109
|
+
"""
|
|
110
|
+
Sets up OpenTelemetry tracing for a given project with OTLP and console exporters.
|
|
111
|
+
|
|
112
|
+
:param project: Object containing project details; must expose project_name.
|
|
113
|
+
:param session_id: Optional session identifier to annotate spans.
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
# Extract project name or use default
|
|
117
|
+
|
|
118
|
+
project_name = getattr(project, 'project_name')
|
|
119
|
+
# Create resource with service and project details
|
|
120
|
+
resource = Resource(attributes={
|
|
121
|
+
"service.name": "OpenAI-Agents",
|
|
122
|
+
"project_name": project_name,
|
|
123
|
+
"session_id": session_id if session_id else "None"
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
# Initialize tracer provider
|
|
127
|
+
tracer_provider = trace_sdk.TracerProvider(resource=resource)
|
|
128
|
+
trace_api.set_tracer_provider(tracer_provider)
|
|
129
|
+
|
|
130
|
+
# Add OTLP and console span processors
|
|
131
|
+
tracer_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter(self.endpoint)))
|
|
132
|
+
# tracer_provider.add_span_processor(ConsoleSpanExporter())
|
|
133
|
+
# Instrument OpenAI
|
|
134
|
+
OpenAIAgentsInstrumentor().instrument()
|
|
135
|
+
|
|
136
|
+
def setup_dspy_tracing(self , project : object , session_id : str = None) -> None:
|
|
137
|
+
"""
|
|
138
|
+
Sets up OpenTelemetry tracing for a given project with OTLP and console exporters.
|
|
139
|
+
|
|
140
|
+
:param project: Object containing project details; must expose project_name.
|
|
141
|
+
:param session_id: Optional session identifier to annotate spans.
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
# Extract project name or use default
|
|
145
|
+
|
|
146
|
+
project_name = getattr(project, 'project_name')
|
|
147
|
+
# Create resource with service and project details
|
|
148
|
+
resource = Resource(attributes={
|
|
149
|
+
"service.name": "DSPy",
|
|
150
|
+
"project_name": project_name,
|
|
151
|
+
"session_id": session_id if session_id else "None"
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
# Initialize tracer provider
|
|
155
|
+
tracer_provider = trace_sdk.TracerProvider(resource=resource)
|
|
156
|
+
trace_api.set_tracer_provider(tracer_provider)
|
|
157
|
+
|
|
158
|
+
# Add OTLP and console span processors
|
|
159
|
+
tracer_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter(self.endpoint)))
|
|
160
|
+
# tracer_provider.add_span_processor(ConsoleSpanExporter())
|
|
161
|
+
# Instrument DSPy
|
|
162
|
+
DSPyInstrumentor().instrument()
|
|
163
|
+
|
|
164
|
+
def setup_llamaindex_tracing(self , project : object , session_id : str = None) -> None:
|
|
165
|
+
"""Enable tracing for LlamaIndex runs."""
|
|
166
|
+
|
|
167
|
+
# Extract project name or use default
|
|
168
|
+
|
|
169
|
+
project_name = getattr(project, 'project_name')
|
|
170
|
+
# Create resource with service and project details
|
|
171
|
+
resource = Resource(attributes={
|
|
172
|
+
"service.name": "Llamaindex",
|
|
173
|
+
"project_name": project_name,
|
|
174
|
+
"session_id": session_id if session_id else "None"
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
# Initialize tracer provider
|
|
178
|
+
tracer_provider = trace_sdk.TracerProvider(resource=resource)
|
|
179
|
+
trace_api.set_tracer_provider(tracer_provider)
|
|
180
|
+
|
|
181
|
+
# Add OTLP and console span processors
|
|
182
|
+
tracer_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter(self.endpoint)))
|
|
183
|
+
# tracer_provider.add_span_processor(ConsoleSpanExporter())
|
|
184
|
+
# Instrument llama
|
|
185
|
+
LlamaIndexInstrumentor().instrument()
|
|
186
|
+
|
|
187
|
+
def setup_smolagents_tracing(self , project : object , session_id : str = None) -> None:
|
|
188
|
+
"""Enable tracing for Smolagents runs."""
|
|
189
|
+
|
|
190
|
+
# Extract project name or use default
|
|
191
|
+
|
|
192
|
+
project_name = getattr(project, 'project_name')
|
|
193
|
+
# Create resource with service and project details
|
|
194
|
+
resource = Resource(attributes={
|
|
195
|
+
"service.name": "Smolagents",
|
|
196
|
+
"project_name": project_name,
|
|
197
|
+
"session_id": session_id if session_id else "None"
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
# Initialize tracer provider
|
|
201
|
+
tracer_provider = trace_sdk.TracerProvider(resource=resource)
|
|
202
|
+
trace_api.set_tracer_provider(tracer_provider)
|
|
203
|
+
|
|
204
|
+
# Add OTLP and console span processors
|
|
205
|
+
tracer_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter(self.endpoint)))
|
|
206
|
+
# tracer_provider.add_span_processor(ConsoleSpanExporter())
|
|
207
|
+
# Instrument Smol
|
|
208
|
+
SmolagentsInstrumentor().instrument()
|
lexsi_sdk/core/utils.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from lexsi_sdk.client.client import APIClient
|
|
2
|
+
|
|
3
|
+
def build_url(base_url, data_connector_name, project_name, organization_id):
|
|
4
|
+
"""Compose a connector URL using project or organization context.
|
|
5
|
+
|
|
6
|
+
:param base_url: Base API path.
|
|
7
|
+
:param data_connector_name: Link service name.
|
|
8
|
+
:param project_name: Project identifier if available.
|
|
9
|
+
:param organization_id: Organization identifier if available.
|
|
10
|
+
:return: Fully composed URL string.
|
|
11
|
+
"""
|
|
12
|
+
url = None
|
|
13
|
+
if project_name:
|
|
14
|
+
url = f"{base_url}?project_name={project_name}&link_service_name={data_connector_name}"
|
|
15
|
+
elif organization_id:
|
|
16
|
+
url = f"{base_url}?organization_id={organization_id}&link_service_name={data_connector_name}"
|
|
17
|
+
return url
|
|
18
|
+
|
|
19
|
+
def build_list_data_connector_url(base_url, project_name, organization_id):
|
|
20
|
+
"""Build list URL for data connectors within a project or organization.
|
|
21
|
+
|
|
22
|
+
:param base_url: Base API path.
|
|
23
|
+
:param project_name: Project identifier if available.
|
|
24
|
+
:param organization_id: Organization identifier if available.
|
|
25
|
+
:return: Fully composed URL string.
|
|
26
|
+
"""
|
|
27
|
+
url = None
|
|
28
|
+
if project_name and organization_id:
|
|
29
|
+
url = f"{base_url}?project_name={project_name}&organization_id={organization_id}"
|
|
30
|
+
elif project_name:
|
|
31
|
+
url = f"{base_url}?project_name={project_name}"
|
|
32
|
+
elif organization_id:
|
|
33
|
+
url = f"{base_url}?organization_id={organization_id}"
|
|
34
|
+
else:
|
|
35
|
+
url = base_url
|
|
36
|
+
return url
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from pydantic import BaseModel
|
|
3
|
+
from typing import Optional
|
|
4
|
+
from lexsi_sdk.client.client import APIClient
|
|
5
|
+
from lexsi_sdk.common.enums import UserRole
|
|
6
|
+
from lexsi_sdk.common.validation import Validate
|
|
7
|
+
from lexsi_sdk.common.xai_uris import (
|
|
8
|
+
AVAILABLE_CUSTOM_SERVERS_URI,
|
|
9
|
+
CREATE_PROJECT_URI,
|
|
10
|
+
GET_WORKSPACES_DETAILS_URI,
|
|
11
|
+
START_CUSTOM_SERVER_URI,
|
|
12
|
+
STOP_CUSTOM_SERVER_URI,
|
|
13
|
+
UPDATE_WORKSPACE_URI,
|
|
14
|
+
GET_NOTIFICATIONS_URI,
|
|
15
|
+
CLEAR_NOTIFICATIONS_URI,
|
|
16
|
+
)
|
|
17
|
+
from lexsi_sdk.core.project import Project
|
|
18
|
+
from lexsi_sdk.core.text import TextProject
|
|
19
|
+
from lexsi_sdk.core.agent import AgentProject
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Workspace(BaseModel):
|
|
23
|
+
"""Class to work with Lexsi.ai workspaces"""
|
|
24
|
+
|
|
25
|
+
organization_id: Optional[str] = None
|
|
26
|
+
created_by: str
|
|
27
|
+
user_workspace_name: str
|
|
28
|
+
workspace_name: str
|
|
29
|
+
created_at: str
|
|
30
|
+
|
|
31
|
+
api_client: APIClient
|
|
32
|
+
|
|
33
|
+
def __init__(self, **kwargs):
|
|
34
|
+
"""Attach API client for workspace operations."""
|
|
35
|
+
super().__init__(**kwargs)
|
|
36
|
+
self.api_client = kwargs.get("api_client")
|
|
37
|
+
|
|
38
|
+
def rename_workspace(self, new_workspace_name: str) -> str:
|
|
39
|
+
"""rename the current workspace to new name
|
|
40
|
+
|
|
41
|
+
:param new_workspace_name: name for the workspace to be renamed to
|
|
42
|
+
:return: response
|
|
43
|
+
"""
|
|
44
|
+
payload = {
|
|
45
|
+
"workspace_name": self.workspace_name,
|
|
46
|
+
"modify_req": {
|
|
47
|
+
"update_workspace": {
|
|
48
|
+
"workspace_name": new_workspace_name,
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
}
|
|
52
|
+
res = self.api_client.post(UPDATE_WORKSPACE_URI, payload)
|
|
53
|
+
self.user_workspace_name = new_workspace_name
|
|
54
|
+
return res.get("details")
|
|
55
|
+
|
|
56
|
+
def delete_workspace(self) -> str:
|
|
57
|
+
"""deletes the current workspace
|
|
58
|
+
:return: response
|
|
59
|
+
"""
|
|
60
|
+
payload = {
|
|
61
|
+
"workspace_name": self.workspace_name,
|
|
62
|
+
"modify_req": {"delete_workspace": self.user_workspace_name},
|
|
63
|
+
}
|
|
64
|
+
res = self.api_client.post(UPDATE_WORKSPACE_URI, payload)
|
|
65
|
+
return res.get("details")
|
|
66
|
+
|
|
67
|
+
def add_user_to_workspace(self, email: str, role: str) -> str:
|
|
68
|
+
"""adds user to current workspace
|
|
69
|
+
|
|
70
|
+
:param email: user email
|
|
71
|
+
:param role: user role ["admin", "manager", "user"]
|
|
72
|
+
:return: response
|
|
73
|
+
"""
|
|
74
|
+
payload = {
|
|
75
|
+
"workspace_name": self.workspace_name,
|
|
76
|
+
"modify_req": {
|
|
77
|
+
"add_user_workspace": {
|
|
78
|
+
"email": email,
|
|
79
|
+
"role": role,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
}
|
|
83
|
+
res = self.api_client.post(UPDATE_WORKSPACE_URI, payload)
|
|
84
|
+
return res.get("details")
|
|
85
|
+
|
|
86
|
+
def remove_user_from_workspace(self, email: str) -> str:
|
|
87
|
+
"""removes user from the current workspace
|
|
88
|
+
|
|
89
|
+
:param email: user email
|
|
90
|
+
:return: response
|
|
91
|
+
"""
|
|
92
|
+
payload = {
|
|
93
|
+
"workspace_name": self.workspace_name,
|
|
94
|
+
"modify_req": {
|
|
95
|
+
"remove_user_workspace": email,
|
|
96
|
+
},
|
|
97
|
+
}
|
|
98
|
+
res = self.api_client.post(UPDATE_WORKSPACE_URI, payload)
|
|
99
|
+
return res.get("details")
|
|
100
|
+
|
|
101
|
+
def update_user_access_for_workspace(self, email: str, role: UserRole) -> str:
|
|
102
|
+
"""update the user access for the workspace
|
|
103
|
+
|
|
104
|
+
:param email: user email
|
|
105
|
+
:param role: new user role ["admin", "user"]
|
|
106
|
+
:return: _description_
|
|
107
|
+
"""
|
|
108
|
+
payload = {
|
|
109
|
+
"workspace_name": self.workspace_name,
|
|
110
|
+
"modify_req": {
|
|
111
|
+
"update_user_workspace": {
|
|
112
|
+
"email": email,
|
|
113
|
+
"role": role,
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
}
|
|
117
|
+
res = self.api_client.post(UPDATE_WORKSPACE_URI, payload)
|
|
118
|
+
return res.get("details")
|
|
119
|
+
|
|
120
|
+
def projects(self) -> pd.DataFrame:
|
|
121
|
+
"""get user projects for this Workspace
|
|
122
|
+
|
|
123
|
+
:return: Projects details dataframe
|
|
124
|
+
"""
|
|
125
|
+
workspace = self.api_client.get(
|
|
126
|
+
f"{GET_WORKSPACES_DETAILS_URI}?workspace_name={self.workspace_name}"
|
|
127
|
+
)
|
|
128
|
+
projects_df = pd.DataFrame(
|
|
129
|
+
workspace.get("data", {}).get("projects", []),
|
|
130
|
+
columns=[
|
|
131
|
+
"user_project_name",
|
|
132
|
+
"access_type",
|
|
133
|
+
"created_by",
|
|
134
|
+
"created_at",
|
|
135
|
+
"updated_at",
|
|
136
|
+
"instance_type",
|
|
137
|
+
"instance_status",
|
|
138
|
+
],
|
|
139
|
+
)
|
|
140
|
+
return projects_df
|
|
141
|
+
|
|
142
|
+
def project(self, project_name: str) -> Project:
|
|
143
|
+
"""Select specific project
|
|
144
|
+
|
|
145
|
+
:param project_name: Name of the project
|
|
146
|
+
:return: Project
|
|
147
|
+
"""
|
|
148
|
+
workspace = self.api_client.get(
|
|
149
|
+
f"{GET_WORKSPACES_DETAILS_URI}?workspace_name={self.workspace_name}"
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
project = next(
|
|
153
|
+
filter(lambda project: project.get("user_project_name") == project_name, workspace.get("data", {}).get("projects", [])),
|
|
154
|
+
None,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
if project is None:
|
|
158
|
+
raise Exception("Project Not Found")
|
|
159
|
+
|
|
160
|
+
if project.get("metadata",{}).get("modality") == "text": return TextProject(api_client=self.api_client, **project)
|
|
161
|
+
elif project.get("metadata",{}).get("modality") == "agent": return AgentProject(api_client=self.api_client, **project)
|
|
162
|
+
|
|
163
|
+
return Project(api_client=self.api_client, **project)
|
|
164
|
+
|
|
165
|
+
def create_project(
|
|
166
|
+
self,
|
|
167
|
+
project_name: str,
|
|
168
|
+
modality: str,
|
|
169
|
+
project_type: str,
|
|
170
|
+
project_sub_type: Optional[str] = None,
|
|
171
|
+
server_type: Optional[str] = None,
|
|
172
|
+
) -> Project:
|
|
173
|
+
"""creates new project in the current workspace
|
|
174
|
+
|
|
175
|
+
:param project_name: name for the project
|
|
176
|
+
:param modality: modality for the project
|
|
177
|
+
Eg:- tabular, image, text
|
|
178
|
+
:project_type: type for the project
|
|
179
|
+
Eg:- classification, regression
|
|
180
|
+
:return: response
|
|
181
|
+
"""
|
|
182
|
+
payload = {
|
|
183
|
+
"project_name": project_name,
|
|
184
|
+
"modality": modality,
|
|
185
|
+
"project_type": project_type,
|
|
186
|
+
"project_sub_type": project_sub_type,
|
|
187
|
+
"workspace_name": self.workspace_name,
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if self.organization_id:
|
|
191
|
+
payload["organization_id"] = self.organization_id
|
|
192
|
+
|
|
193
|
+
if server_type:
|
|
194
|
+
custom_servers = self.api_client.get(AVAILABLE_CUSTOM_SERVERS_URI)
|
|
195
|
+
Validate.value_against_list(
|
|
196
|
+
"server_type",
|
|
197
|
+
server_type,
|
|
198
|
+
[server["name"] for server in custom_servers],
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
payload["instance_type"] = server_type
|
|
202
|
+
payload["server_config"] = {}
|
|
203
|
+
|
|
204
|
+
res = self.api_client.post(CREATE_PROJECT_URI, payload)
|
|
205
|
+
|
|
206
|
+
if not res["success"]:
|
|
207
|
+
raise Exception(res["details"])
|
|
208
|
+
|
|
209
|
+
if modality == "text":
|
|
210
|
+
project = TextProject(api_client=self.api_client, **res["details"])
|
|
211
|
+
elif modality == "agent":
|
|
212
|
+
project = AgentProject(api_client=self.api_client, **res["details"])
|
|
213
|
+
else:
|
|
214
|
+
project = Project(api_client=self.api_client, **res["details"])
|
|
215
|
+
|
|
216
|
+
return project
|
|
217
|
+
|
|
218
|
+
def get_notifications(self) -> pd.DataFrame:
|
|
219
|
+
"""get user workspace notifications
|
|
220
|
+
|
|
221
|
+
:return: DataFrame
|
|
222
|
+
"""
|
|
223
|
+
url = f"{GET_NOTIFICATIONS_URI}?workspace_name={self.workspace_name}"
|
|
224
|
+
|
|
225
|
+
res = self.api_client.get(url)
|
|
226
|
+
|
|
227
|
+
if not res["success"]:
|
|
228
|
+
raise Exception("Error while getting workspace notifications.")
|
|
229
|
+
|
|
230
|
+
notifications = res["details"]
|
|
231
|
+
|
|
232
|
+
if not notifications:
|
|
233
|
+
return "No notifications found."
|
|
234
|
+
|
|
235
|
+
return pd.DataFrame(notifications).reindex(
|
|
236
|
+
columns=["project_name", "message", "time"]
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
def clear_notifications(self) -> str:
|
|
240
|
+
"""clear user workspace notifications
|
|
241
|
+
|
|
242
|
+
:raises Exception: _description_
|
|
243
|
+
:return: str
|
|
244
|
+
"""
|
|
245
|
+
url = f"{CLEAR_NOTIFICATIONS_URI}?workspace_name={self.workspace_name}"
|
|
246
|
+
|
|
247
|
+
res = self.api_client.post(url)
|
|
248
|
+
|
|
249
|
+
if not res["success"]:
|
|
250
|
+
raise Exception("Error while clearing workspace notifications.")
|
|
251
|
+
|
|
252
|
+
return res["details"]
|
|
253
|
+
|
|
254
|
+
def start_server(self) -> str:
|
|
255
|
+
"""start dedicated workspace server
|
|
256
|
+
|
|
257
|
+
:return: response
|
|
258
|
+
"""
|
|
259
|
+
|
|
260
|
+
res = self.api_client.post(
|
|
261
|
+
f"{START_CUSTOM_SERVER_URI}?workspace_name={self.workspace_name}"
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
if not res["success"]:
|
|
265
|
+
raise Exception(res.get("message"))
|
|
266
|
+
|
|
267
|
+
return res["message"]
|
|
268
|
+
|
|
269
|
+
def stop_server(self) -> str:
|
|
270
|
+
"""stop dedicated workspace server
|
|
271
|
+
|
|
272
|
+
:return: response
|
|
273
|
+
"""
|
|
274
|
+
res = self.api_client.post(
|
|
275
|
+
f"{STOP_CUSTOM_SERVER_URI}?workspace_name={self.workspace_name}"
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
if not res["success"]:
|
|
279
|
+
raise Exception(res.get("message"))
|
|
280
|
+
|
|
281
|
+
return res["message"]
|
|
282
|
+
|
|
283
|
+
def update_server(self, server_type: str) -> str:
|
|
284
|
+
"""update dedicated workspace server
|
|
285
|
+
:param server_type: dedicated instance to run workloads
|
|
286
|
+
for all available instances check xai.available_custom_servers()
|
|
287
|
+
|
|
288
|
+
:return: response
|
|
289
|
+
"""
|
|
290
|
+
custom_servers = self.api_client.get(AVAILABLE_CUSTOM_SERVERS_URI)
|
|
291
|
+
Validate.value_against_list(
|
|
292
|
+
"server_type",
|
|
293
|
+
server_type,
|
|
294
|
+
[server["name"] for server in custom_servers],
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
payload = {
|
|
298
|
+
"workspace_name": self.workspace_name,
|
|
299
|
+
"modify_req": {
|
|
300
|
+
"update_workspace": {
|
|
301
|
+
"workspace_name": self.user_workspace_name,
|
|
302
|
+
"instance_type": server_type,
|
|
303
|
+
},
|
|
304
|
+
"update_operational_hours": {},
|
|
305
|
+
},
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
res = self.api_client.post(UPDATE_WORKSPACE_URI, payload)
|
|
309
|
+
|
|
310
|
+
if not res["success"]:
|
|
311
|
+
raise Exception(res.get("details"))
|
|
312
|
+
|
|
313
|
+
return "Server Updated"
|
|
314
|
+
|
|
315
|
+
def __print__(self) -> str:
|
|
316
|
+
"""User-friendly string representation."""
|
|
317
|
+
return f"Workspace(user_workspace_name='{self.user_workspace_name}', created_by='{self.created_by}', created_at='{self.created_at}')"
|
|
318
|
+
|
|
319
|
+
def __str__(self) -> str:
|
|
320
|
+
"""Return printable representation."""
|
|
321
|
+
return self.__print__()
|
|
322
|
+
|
|
323
|
+
def __repr__(self) -> str:
|
|
324
|
+
"""Return developer-friendly representation."""
|
|
325
|
+
return self.__print__()
|