codemie-sdk-python 0.1.275__py3-none-any.whl → 0.1.289__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.
- codemie_sdk/__init__.py +42 -0
- codemie_sdk/client/client.py +19 -0
- codemie_sdk/models/admin.py +28 -0
- codemie_sdk/models/analytics.py +148 -0
- codemie_sdk/models/assistant.py +87 -0
- codemie_sdk/models/guardrails.py +62 -0
- codemie_sdk/services/admin.py +60 -0
- codemie_sdk/services/analytics.py +463 -0
- codemie_sdk/services/assistant.py +14 -7
- codemie_sdk/services/codemie_guardrails.py +76 -0
- {codemie_sdk_python-0.1.275.dist-info → codemie_sdk_python-0.1.289.dist-info}/METADATA +1 -1
- {codemie_sdk_python-0.1.275.dist-info → codemie_sdk_python-0.1.289.dist-info}/RECORD +13 -7
- {codemie_sdk_python-0.1.275.dist-info → codemie_sdk_python-0.1.289.dist-info}/WHEEL +0 -0
codemie_sdk/__init__.py
CHANGED
|
@@ -73,10 +73,33 @@ from .models.vendor_guardrail import (
|
|
|
73
73
|
VendorGuardrailInstallResponse,
|
|
74
74
|
VendorGuardrailUninstallResponse,
|
|
75
75
|
)
|
|
76
|
+
from .models.guardrails import (
|
|
77
|
+
GuardrailAssignmentSetting,
|
|
78
|
+
GuardrailAssignmentEntity,
|
|
79
|
+
GuardrailAssignmentRequest,
|
|
80
|
+
GuardrailAssignmentResponse,
|
|
81
|
+
)
|
|
82
|
+
from .models.analytics import (
|
|
83
|
+
ResponseMetadata,
|
|
84
|
+
PaginationMetadata,
|
|
85
|
+
ColumnDefinition,
|
|
86
|
+
Metric,
|
|
87
|
+
SummariesData,
|
|
88
|
+
TabularData,
|
|
89
|
+
UserListItem,
|
|
90
|
+
UsersListData,
|
|
91
|
+
SummariesResponse,
|
|
92
|
+
TabularResponse,
|
|
93
|
+
UsersListResponse,
|
|
94
|
+
AnalyticsQueryParams,
|
|
95
|
+
PaginatedAnalyticsQueryParams,
|
|
96
|
+
)
|
|
76
97
|
from .services.vendor_assistant import VendorAssistantService
|
|
77
98
|
from .services.vendor_workflow import VendorWorkflowService
|
|
78
99
|
from .services.vendor_knowledgebase import VendorKnowledgeBaseService
|
|
79
100
|
from .services.vendor_guardrail import VendorGuardrailService
|
|
101
|
+
from .services.codemie_guardrails import CodemieGuardrailService
|
|
102
|
+
from .services.analytics import AnalyticsService
|
|
80
103
|
|
|
81
104
|
__version__ = "0.2.12"
|
|
82
105
|
__all__ = [
|
|
@@ -132,4 +155,23 @@ __all__ = [
|
|
|
132
155
|
"VendorGuardrailInstallResponse",
|
|
133
156
|
"VendorGuardrailUninstallResponse",
|
|
134
157
|
"VendorGuardrailService",
|
|
158
|
+
"GuardrailAssignmentSetting",
|
|
159
|
+
"GuardrailAssignmentEntity",
|
|
160
|
+
"GuardrailAssignmentRequest",
|
|
161
|
+
"GuardrailAssignmentResponse",
|
|
162
|
+
"CodemieGuardrailService",
|
|
163
|
+
"ResponseMetadata",
|
|
164
|
+
"PaginationMetadata",
|
|
165
|
+
"ColumnDefinition",
|
|
166
|
+
"Metric",
|
|
167
|
+
"SummariesData",
|
|
168
|
+
"TabularData",
|
|
169
|
+
"UserListItem",
|
|
170
|
+
"UsersListData",
|
|
171
|
+
"SummariesResponse",
|
|
172
|
+
"TabularResponse",
|
|
173
|
+
"UsersListResponse",
|
|
174
|
+
"AnalyticsQueryParams",
|
|
175
|
+
"PaginatedAnalyticsQueryParams",
|
|
176
|
+
"AnalyticsService",
|
|
135
177
|
]
|
codemie_sdk/client/client.py
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
from typing import Optional
|
|
4
4
|
|
|
5
5
|
from ..auth.credentials import KeycloakCredentials
|
|
6
|
+
from ..services.admin import AdminService
|
|
7
|
+
from ..services.analytics import AnalyticsService
|
|
6
8
|
from ..services.assistant import AssistantService
|
|
7
9
|
from ..services.conversation import ConversationService
|
|
8
10
|
from ..services.datasource import DatasourceService
|
|
@@ -17,6 +19,7 @@ from ..services.vendor_assistant import VendorAssistantService
|
|
|
17
19
|
from ..services.vendor_workflow import VendorWorkflowService
|
|
18
20
|
from ..services.vendor_knowledgebase import VendorKnowledgeBaseService
|
|
19
21
|
from ..services.vendor_guardrail import VendorGuardrailService
|
|
22
|
+
from ..services.codemie_guardrails import CodemieGuardrailService
|
|
20
23
|
|
|
21
24
|
|
|
22
25
|
class CodeMieClient:
|
|
@@ -69,6 +72,10 @@ class CodeMieClient:
|
|
|
69
72
|
self._token = "" if self._is_localhost else self.auth.get_token()
|
|
70
73
|
|
|
71
74
|
# Initialize services with verify_ssl parameter and token
|
|
75
|
+
self.admin = AdminService(self._api_domain, self._token, verify_ssl=verify_ssl)
|
|
76
|
+
self.analytics = AnalyticsService(
|
|
77
|
+
self._api_domain, self._token, verify_ssl=verify_ssl
|
|
78
|
+
)
|
|
72
79
|
self.assistants = AssistantService(
|
|
73
80
|
self._api_domain, self._token, verify_ssl=verify_ssl
|
|
74
81
|
)
|
|
@@ -105,6 +112,9 @@ class CodeMieClient:
|
|
|
105
112
|
self.vendor_guardrails = VendorGuardrailService(
|
|
106
113
|
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
107
114
|
)
|
|
115
|
+
self.codemie_guardrails = CodemieGuardrailService(
|
|
116
|
+
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
117
|
+
)
|
|
108
118
|
|
|
109
119
|
@property
|
|
110
120
|
def token(self) -> str:
|
|
@@ -128,6 +138,12 @@ class CodeMieClient:
|
|
|
128
138
|
"""Force token refresh."""
|
|
129
139
|
self._token = "" if self._is_localhost else self.auth.get_token()
|
|
130
140
|
# Update token in services
|
|
141
|
+
self.admin = AdminService(
|
|
142
|
+
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
143
|
+
)
|
|
144
|
+
self.analytics = AnalyticsService(
|
|
145
|
+
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
146
|
+
)
|
|
131
147
|
self.assistants = AssistantService(
|
|
132
148
|
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
133
149
|
)
|
|
@@ -170,4 +186,7 @@ class CodeMieClient:
|
|
|
170
186
|
self.vendor_guardrails = VendorGuardrailService(
|
|
171
187
|
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
172
188
|
)
|
|
189
|
+
self.codemie_guardrails = CodemieGuardrailService(
|
|
190
|
+
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
191
|
+
)
|
|
173
192
|
return self._token
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Admin models for managing applications/projects."""
|
|
2
|
+
|
|
3
|
+
from typing import List
|
|
4
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ApplicationsListResponse(BaseModel):
|
|
8
|
+
"""Response model for list applications endpoint."""
|
|
9
|
+
|
|
10
|
+
model_config = ConfigDict(extra="ignore")
|
|
11
|
+
|
|
12
|
+
applications: List[str] = Field(..., description="List of application names")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ApplicationCreateRequest(BaseModel):
|
|
16
|
+
"""Request model for creating an application/project."""
|
|
17
|
+
|
|
18
|
+
model_config = ConfigDict(extra="ignore")
|
|
19
|
+
|
|
20
|
+
name: str = Field(..., description="Application/project name")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ApplicationCreateResponse(BaseModel):
|
|
24
|
+
"""Response model for create application endpoint."""
|
|
25
|
+
|
|
26
|
+
model_config = ConfigDict(extra="ignore")
|
|
27
|
+
|
|
28
|
+
message: str = Field(..., description="Created application name")
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"""Models for analytics-related data structures."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List, Optional
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ResponseMetadata(BaseModel):
|
|
9
|
+
"""Metadata for analytics responses."""
|
|
10
|
+
|
|
11
|
+
model_config = ConfigDict(extra="ignore")
|
|
12
|
+
|
|
13
|
+
timestamp: str = Field(description="ISO 8601 timestamp when response generated")
|
|
14
|
+
data_as_of: str = Field(description="ISO 8601 timestamp of data freshness")
|
|
15
|
+
filters_applied: Dict[str, Any] = Field(description="Applied filters")
|
|
16
|
+
execution_time_ms: float = Field(description="Query execution time in milliseconds")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class PaginationMetadata(BaseModel):
|
|
20
|
+
"""Pagination metadata for tabular responses."""
|
|
21
|
+
|
|
22
|
+
model_config = ConfigDict(extra="ignore")
|
|
23
|
+
|
|
24
|
+
page: int = Field(description="Zero-indexed page number")
|
|
25
|
+
per_page: int = Field(description="Items per page")
|
|
26
|
+
total_count: int = Field(description="Total items available")
|
|
27
|
+
has_more: bool = Field(description="Whether more pages exist")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ColumnDefinition(BaseModel):
|
|
31
|
+
"""Column metadata for tabular data."""
|
|
32
|
+
|
|
33
|
+
model_config = ConfigDict(extra="ignore")
|
|
34
|
+
|
|
35
|
+
id: str = Field(description="Column identifier")
|
|
36
|
+
label: str = Field(description="Human-readable label")
|
|
37
|
+
type: str = Field(description='Data type: "string", "number", "date"')
|
|
38
|
+
format: Optional[str] = Field(
|
|
39
|
+
None, description='Format hint: "currency", "percentage", "timestamp"'
|
|
40
|
+
)
|
|
41
|
+
description: Optional[str] = Field(None, description="Column description")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class Metric(BaseModel):
|
|
45
|
+
"""Individual metric in summary responses."""
|
|
46
|
+
|
|
47
|
+
model_config = ConfigDict(extra="ignore")
|
|
48
|
+
|
|
49
|
+
id: str = Field(description="Metric identifier")
|
|
50
|
+
label: str = Field(description="Human-readable label")
|
|
51
|
+
type: str = Field(description="Data type")
|
|
52
|
+
value: Any = Field(description="Metric value (int, float, str, etc.)")
|
|
53
|
+
format: Optional[str] = Field(
|
|
54
|
+
None, description='Format hint: "currency", "percentage", "number"'
|
|
55
|
+
)
|
|
56
|
+
description: Optional[str] = Field(None, description="Metric description")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class SummariesData(BaseModel):
|
|
60
|
+
"""Container for summary metrics."""
|
|
61
|
+
|
|
62
|
+
model_config = ConfigDict(extra="ignore")
|
|
63
|
+
|
|
64
|
+
metrics: List[Metric] = Field(description="Array of metrics")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class TabularData(BaseModel):
|
|
68
|
+
"""Container for tabular data with dynamic columns."""
|
|
69
|
+
|
|
70
|
+
model_config = ConfigDict(extra="ignore")
|
|
71
|
+
|
|
72
|
+
columns: List[ColumnDefinition] = Field(description="Column definitions")
|
|
73
|
+
rows: List[Dict[str, Any]] = Field(description="Data rows (dict per row)")
|
|
74
|
+
totals: Optional[Dict[str, Any]] = Field(None, description="Optional totals row")
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class UserListItem(BaseModel):
|
|
78
|
+
"""Individual user item."""
|
|
79
|
+
|
|
80
|
+
model_config = ConfigDict(extra="ignore")
|
|
81
|
+
|
|
82
|
+
id: str = Field(description="User ID")
|
|
83
|
+
name: str = Field(description="User name")
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class UsersListData(BaseModel):
|
|
87
|
+
"""Container for users list."""
|
|
88
|
+
|
|
89
|
+
model_config = ConfigDict(extra="ignore")
|
|
90
|
+
|
|
91
|
+
users: List[UserListItem] = Field(description="List of users")
|
|
92
|
+
total_count: int = Field(description="Total number of users")
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class SummariesResponse(BaseModel):
|
|
96
|
+
"""Response for summary endpoints (summaries, cli-summary)."""
|
|
97
|
+
|
|
98
|
+
model_config = ConfigDict(extra="ignore")
|
|
99
|
+
|
|
100
|
+
data: SummariesData = Field(description="Summary data")
|
|
101
|
+
metadata: ResponseMetadata = Field(description="Response metadata")
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class TabularResponse(BaseModel):
|
|
105
|
+
"""Response for tabular endpoints (19 endpoints)."""
|
|
106
|
+
|
|
107
|
+
model_config = ConfigDict(extra="ignore")
|
|
108
|
+
|
|
109
|
+
data: TabularData = Field(description="Tabular data")
|
|
110
|
+
metadata: ResponseMetadata = Field(description="Response metadata")
|
|
111
|
+
pagination: Optional[PaginationMetadata] = Field(
|
|
112
|
+
None, description="Optional pagination metadata"
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class UsersListResponse(BaseModel):
|
|
117
|
+
"""Response for users list endpoint."""
|
|
118
|
+
|
|
119
|
+
model_config = ConfigDict(extra="ignore")
|
|
120
|
+
|
|
121
|
+
data: UsersListData = Field(description="Users list data")
|
|
122
|
+
metadata: ResponseMetadata = Field(description="Response metadata")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class AnalyticsQueryParams(BaseModel):
|
|
126
|
+
"""Query parameters for analytics endpoints."""
|
|
127
|
+
|
|
128
|
+
model_config = ConfigDict(extra="ignore")
|
|
129
|
+
|
|
130
|
+
time_period: Optional[str] = Field(
|
|
131
|
+
None,
|
|
132
|
+
description='Time period: "last_hour", "last_6_hours", "last_24_hours", "last_7_days", "last_30_days", "last_90_days", "last_year"',
|
|
133
|
+
)
|
|
134
|
+
start_date: Optional[str] = Field(
|
|
135
|
+
None, description="ISO 8601 format start date (use with end_date)"
|
|
136
|
+
)
|
|
137
|
+
end_date: Optional[str] = Field(
|
|
138
|
+
None, description="ISO 8601 format end date (use with start_date)"
|
|
139
|
+
)
|
|
140
|
+
users: Optional[str] = Field(None, description="Comma-separated user IDs")
|
|
141
|
+
projects: Optional[str] = Field(None, description="Comma-separated project names")
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class PaginatedAnalyticsQueryParams(AnalyticsQueryParams):
|
|
145
|
+
"""Query parameters with pagination."""
|
|
146
|
+
|
|
147
|
+
page: int = Field(0, description="Zero-indexed page number")
|
|
148
|
+
per_page: int = Field(20, description="Items per page")
|
codemie_sdk/models/assistant.py
CHANGED
|
@@ -216,6 +216,7 @@ class AssistantRequestBase(AssistantBase):
|
|
|
216
216
|
mcp_servers: List[MCPServerDetails] = Field(default_factory=list)
|
|
217
217
|
assistant_ids: List[str] = Field(default_factory=list)
|
|
218
218
|
prompt_variables: List[PromptVariable] = Field(default_factory=list)
|
|
219
|
+
skip_integration_validation: Optional[bool] = Field(default=False)
|
|
219
220
|
|
|
220
221
|
|
|
221
222
|
class AssistantCreateRequest(AssistantRequestBase):
|
|
@@ -230,6 +231,92 @@ class AssistantUpdateRequest(AssistantRequestBase):
|
|
|
230
231
|
pass
|
|
231
232
|
|
|
232
233
|
|
|
234
|
+
class MissingIntegration(BaseModel):
|
|
235
|
+
"""Model representing a single missing tool credential."""
|
|
236
|
+
|
|
237
|
+
model_config = ConfigDict(extra="ignore")
|
|
238
|
+
|
|
239
|
+
toolkit: str = Field(..., description="Toolkit name (e.g., 'Data Management')")
|
|
240
|
+
tool: str = Field(..., description="Tool name (e.g., 'sql')")
|
|
241
|
+
label: str = Field(..., description="Display label for the tool (e.g., 'SQL')")
|
|
242
|
+
credential_type: Optional[str] = Field(
|
|
243
|
+
None, description="Credential type required (e.g., 'AWS', 'Jira')"
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
class MissingIntegrationsByCredentialType(BaseModel):
|
|
248
|
+
"""Model representing missing tools grouped by credential type."""
|
|
249
|
+
|
|
250
|
+
model_config = ConfigDict(extra="ignore")
|
|
251
|
+
|
|
252
|
+
credential_type: str = Field(
|
|
253
|
+
..., description="Credential type (e.g., 'AWS', 'Jira', 'Confluence')"
|
|
254
|
+
)
|
|
255
|
+
missing_tools: List[MissingIntegration] = Field(
|
|
256
|
+
..., description="List of missing tools requiring this credential type"
|
|
257
|
+
)
|
|
258
|
+
# Optional sub-assistant context
|
|
259
|
+
assistant_id: Optional[str] = Field(
|
|
260
|
+
None, description="Sub-assistant ID (if from sub-assistant)"
|
|
261
|
+
)
|
|
262
|
+
assistant_name: Optional[str] = Field(
|
|
263
|
+
None, description="Sub-assistant name (if from sub-assistant)"
|
|
264
|
+
)
|
|
265
|
+
icon_url: Optional[str] = Field(
|
|
266
|
+
None, description="Sub-assistant icon URL (if from sub-assistant)"
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
class IntegrationValidationResult(BaseModel):
|
|
271
|
+
"""Complete validation result for assistant integrations."""
|
|
272
|
+
|
|
273
|
+
model_config = ConfigDict(extra="ignore")
|
|
274
|
+
|
|
275
|
+
has_missing_integrations: bool = Field(
|
|
276
|
+
..., description="Whether any integrations are missing"
|
|
277
|
+
)
|
|
278
|
+
missing_by_credential_type: List[MissingIntegrationsByCredentialType] = Field(
|
|
279
|
+
default_factory=list,
|
|
280
|
+
description="Missing tools in main assistant grouped by credential type",
|
|
281
|
+
)
|
|
282
|
+
sub_assistants_missing: List[MissingIntegrationsByCredentialType] = Field(
|
|
283
|
+
default_factory=list,
|
|
284
|
+
description="Missing tools in sub-assistants grouped by credential type",
|
|
285
|
+
)
|
|
286
|
+
message: Optional[str] = Field(
|
|
287
|
+
None, description="User-friendly message about missing integrations"
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
class AssistantCreateResponse(BaseModel):
|
|
292
|
+
"""Response model for assistant creation with validation."""
|
|
293
|
+
|
|
294
|
+
model_config = ConfigDict(extra="ignore", populate_by_name=True)
|
|
295
|
+
|
|
296
|
+
message: str = Field(..., description="Response message")
|
|
297
|
+
assistant_id: Optional[str] = Field(
|
|
298
|
+
None,
|
|
299
|
+
alias="assistantId",
|
|
300
|
+
description="Created assistant ID (None if validation failed)",
|
|
301
|
+
)
|
|
302
|
+
validation: Optional[IntegrationValidationResult] = Field(
|
|
303
|
+
None,
|
|
304
|
+
description="Validation result (populated if validation found missing integrations)",
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
class AssistantUpdateResponse(BaseModel):
|
|
309
|
+
"""Response model for assistant update with validation."""
|
|
310
|
+
|
|
311
|
+
model_config = ConfigDict(extra="ignore")
|
|
312
|
+
|
|
313
|
+
message: str = Field(..., description="Response message")
|
|
314
|
+
validation: Optional[IntegrationValidationResult] = Field(
|
|
315
|
+
None,
|
|
316
|
+
description="Validation result (populated if validation found missing integrations)",
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
|
|
233
320
|
class AssistantVersion(BaseModel):
|
|
234
321
|
"""Immutable snapshot of assistant configuration for a specific version."""
|
|
235
322
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Models for guardrail assignments."""
|
|
2
|
+
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class GuardrailAssignmentSetting(BaseModel):
|
|
9
|
+
"""Model for guardrail assignment settings."""
|
|
10
|
+
|
|
11
|
+
model_config = ConfigDict(extra="ignore")
|
|
12
|
+
|
|
13
|
+
mode: str = Field(..., description="Assignment mode (e.g., 'all', 'specific')")
|
|
14
|
+
source: str = Field(..., description="Source type (e.g., 'input', 'output')")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class GuardrailAssignmentEntity(BaseModel):
|
|
18
|
+
"""Model for guardrail assignment to specific entities."""
|
|
19
|
+
|
|
20
|
+
model_config = ConfigDict(extra="ignore")
|
|
21
|
+
|
|
22
|
+
settings: List[GuardrailAssignmentSetting] = Field(
|
|
23
|
+
default_factory=list, description="List of assignment settings"
|
|
24
|
+
)
|
|
25
|
+
items: List[str] = Field(
|
|
26
|
+
default_factory=list, description="List of specific entity IDs"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class GuardrailAssignmentRequest(BaseModel):
|
|
31
|
+
"""Request model for assigning guardrails to entities."""
|
|
32
|
+
|
|
33
|
+
model_config = ConfigDict(extra="ignore")
|
|
34
|
+
|
|
35
|
+
project: GuardrailAssignmentEntity = Field(
|
|
36
|
+
default_factory=lambda: GuardrailAssignmentEntity(settings=[], items=[]),
|
|
37
|
+
description="Project-level assignments",
|
|
38
|
+
)
|
|
39
|
+
assistants: GuardrailAssignmentEntity = Field(
|
|
40
|
+
default_factory=lambda: GuardrailAssignmentEntity(settings=[], items=[]),
|
|
41
|
+
description="Assistant-level assignments",
|
|
42
|
+
)
|
|
43
|
+
workflows: GuardrailAssignmentEntity = Field(
|
|
44
|
+
default_factory=lambda: GuardrailAssignmentEntity(settings=[], items=[]),
|
|
45
|
+
description="Workflow-level assignments",
|
|
46
|
+
)
|
|
47
|
+
datasources: GuardrailAssignmentEntity = Field(
|
|
48
|
+
default_factory=lambda: GuardrailAssignmentEntity(settings=[], items=[]),
|
|
49
|
+
description="Datasource-level assignments",
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class GuardrailAssignmentResponse(BaseModel):
|
|
54
|
+
"""Response model for guardrail assignment."""
|
|
55
|
+
|
|
56
|
+
model_config = ConfigDict(extra="ignore")
|
|
57
|
+
|
|
58
|
+
success: int = Field(..., description="Count of successful assignments")
|
|
59
|
+
failed: int = Field(..., description="Count of failed assignments")
|
|
60
|
+
errors: List[str] = Field(
|
|
61
|
+
default_factory=list, description="List of error messages"
|
|
62
|
+
)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""Admin service implementation."""
|
|
2
|
+
|
|
3
|
+
from typing import List, Optional
|
|
4
|
+
|
|
5
|
+
from ..models.admin import (
|
|
6
|
+
ApplicationsListResponse,
|
|
7
|
+
ApplicationCreateRequest,
|
|
8
|
+
ApplicationCreateResponse,
|
|
9
|
+
)
|
|
10
|
+
from ..utils import ApiRequestHandler
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AdminService:
|
|
14
|
+
"""Service for managing CodeMie applications/projects."""
|
|
15
|
+
|
|
16
|
+
def __init__(self, api_domain: str, token: str, verify_ssl: bool = True):
|
|
17
|
+
"""Initialize the admin service.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
api_domain: Base URL for the CodeMie API
|
|
21
|
+
token: Authentication token
|
|
22
|
+
verify_ssl: Whether to verify SSL certificates
|
|
23
|
+
"""
|
|
24
|
+
self._api = ApiRequestHandler(api_domain, token, verify_ssl)
|
|
25
|
+
|
|
26
|
+
def list_applications(self, project_name: Optional[str] = None) -> List[str]:
|
|
27
|
+
"""Get list of all applications/projects.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
project_name: Optional project name to filter by
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
List of application names
|
|
34
|
+
"""
|
|
35
|
+
params = {}
|
|
36
|
+
if project_name:
|
|
37
|
+
params["search"] = project_name
|
|
38
|
+
|
|
39
|
+
response = self._api.get(
|
|
40
|
+
"/v1/admin/applications",
|
|
41
|
+
ApplicationsListResponse,
|
|
42
|
+
params=params if params else None,
|
|
43
|
+
)
|
|
44
|
+
return response.applications
|
|
45
|
+
|
|
46
|
+
def create_application(self, request: ApplicationCreateRequest) -> str:
|
|
47
|
+
"""Create a new application/project.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
request: Application creation request
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
Created application name
|
|
54
|
+
"""
|
|
55
|
+
response = self._api.post(
|
|
56
|
+
"/v1/admin/application",
|
|
57
|
+
ApplicationCreateResponse,
|
|
58
|
+
json_data=request.model_dump(exclude_none=True),
|
|
59
|
+
)
|
|
60
|
+
return response.message
|
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
"""Analytics service implementation."""
|
|
2
|
+
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from ..models.analytics import (
|
|
6
|
+
AnalyticsQueryParams,
|
|
7
|
+
PaginatedAnalyticsQueryParams,
|
|
8
|
+
SummariesResponse,
|
|
9
|
+
TabularResponse,
|
|
10
|
+
UsersListResponse,
|
|
11
|
+
)
|
|
12
|
+
from ..utils import ApiRequestHandler
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class AnalyticsService:
|
|
16
|
+
"""Service for managing CodeMie analytics."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, api_domain: str, token: str, verify_ssl: bool = True):
|
|
19
|
+
"""Initialize the analytics service.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
api_domain: Base URL for the CodeMie API
|
|
23
|
+
token: Authentication token
|
|
24
|
+
verify_ssl: Whether to verify SSL certificates
|
|
25
|
+
"""
|
|
26
|
+
self._api = ApiRequestHandler(api_domain, token, verify_ssl)
|
|
27
|
+
|
|
28
|
+
def get_summaries(
|
|
29
|
+
self, params: Optional[AnalyticsQueryParams] = None
|
|
30
|
+
) -> SummariesResponse:
|
|
31
|
+
"""Get overall platform summary metrics.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
params: Query parameters (time filters, user/project filters)
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
SummariesResponse with metrics array including total input tokens,
|
|
38
|
+
cached input tokens, output tokens, and money spent
|
|
39
|
+
"""
|
|
40
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
41
|
+
return self._api.get(
|
|
42
|
+
"/v1/analytics/summaries",
|
|
43
|
+
SummariesResponse,
|
|
44
|
+
params=query_params,
|
|
45
|
+
wrap_response=False,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
def get_cli_summary(
|
|
49
|
+
self, params: Optional[AnalyticsQueryParams] = None
|
|
50
|
+
) -> SummariesResponse:
|
|
51
|
+
"""Get CLI-specific summary metrics.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
params: Query parameters (time filters, user/project filters)
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
SummariesResponse with CLI metrics including unique users, repos,
|
|
58
|
+
sessions, file operations, and code statistics
|
|
59
|
+
"""
|
|
60
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
61
|
+
return self._api.get(
|
|
62
|
+
"/v1/analytics/cli-summary",
|
|
63
|
+
SummariesResponse,
|
|
64
|
+
params=query_params,
|
|
65
|
+
wrap_response=False,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
def get_assistants_chats(
|
|
69
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
70
|
+
) -> TabularResponse:
|
|
71
|
+
"""Get assistants chats analytics.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
params: Query parameters (filters + pagination)
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
TabularResponse with assistant performance metrics including chat statistics,
|
|
78
|
+
error rates, token consumption, and costs
|
|
79
|
+
"""
|
|
80
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
81
|
+
return self._api.get(
|
|
82
|
+
"/v1/analytics/assistants-chats",
|
|
83
|
+
TabularResponse,
|
|
84
|
+
params=query_params,
|
|
85
|
+
wrap_response=False,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
def get_workflows(
|
|
89
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
90
|
+
) -> TabularResponse:
|
|
91
|
+
"""Get workflows analytics.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
params: Query parameters (filters + pagination)
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
TabularResponse with workflow execution metrics including total runs,
|
|
98
|
+
success/failure rates, costs, and performance statistics
|
|
99
|
+
"""
|
|
100
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
101
|
+
return self._api.get(
|
|
102
|
+
"/v1/analytics/workflows",
|
|
103
|
+
TabularResponse,
|
|
104
|
+
params=query_params,
|
|
105
|
+
wrap_response=False,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
def get_tools_usage(
|
|
109
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
110
|
+
) -> TabularResponse:
|
|
111
|
+
"""Get tool usage analytics.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
params: Query parameters (filters + pagination)
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
TabularResponse with tool usage metrics including invocation counts,
|
|
118
|
+
user adoption, agent usage, and error tracking
|
|
119
|
+
"""
|
|
120
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
121
|
+
return self._api.get(
|
|
122
|
+
"/v1/analytics/tools-usage",
|
|
123
|
+
TabularResponse,
|
|
124
|
+
params=query_params,
|
|
125
|
+
wrap_response=False,
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
def get_webhooks_invocation(
|
|
129
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
130
|
+
) -> TabularResponse:
|
|
131
|
+
"""Get webhooks invocation statistics.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
params: Query parameters (filters + pagination)
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
TabularResponse with webhook usage patterns showing invocation counts
|
|
138
|
+
per user and webhook alias
|
|
139
|
+
"""
|
|
140
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
141
|
+
return self._api.get(
|
|
142
|
+
"/v1/analytics/webhooks-invocation",
|
|
143
|
+
TabularResponse,
|
|
144
|
+
params=query_params,
|
|
145
|
+
wrap_response=False,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
def get_mcp_servers(
|
|
149
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
150
|
+
) -> TabularResponse:
|
|
151
|
+
"""Get top MCP servers analytics.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
params: Query parameters (filters + pagination)
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
TabularResponse with MCP server usage distribution showing
|
|
158
|
+
percentage share of each server
|
|
159
|
+
"""
|
|
160
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
161
|
+
return self._api.get(
|
|
162
|
+
"/v1/analytics/mcp-servers",
|
|
163
|
+
TabularResponse,
|
|
164
|
+
params=query_params,
|
|
165
|
+
wrap_response=False,
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
def get_mcp_servers_by_users(
|
|
169
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
170
|
+
) -> TabularResponse:
|
|
171
|
+
"""Get MCP servers usage by users.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
params: Query parameters (filters + pagination)
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
TabularResponse with individual user adoption and usage of MCP servers
|
|
178
|
+
showing which users are utilizing which servers
|
|
179
|
+
"""
|
|
180
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
181
|
+
return self._api.get(
|
|
182
|
+
"/v1/analytics/mcp-servers-by-users",
|
|
183
|
+
TabularResponse,
|
|
184
|
+
params=query_params,
|
|
185
|
+
wrap_response=False,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
def get_projects_spending(
|
|
189
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
190
|
+
) -> TabularResponse:
|
|
191
|
+
"""Get money spent by projects.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
params: Query parameters (filters + pagination)
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
TabularResponse with project-level spending ranked by amount
|
|
198
|
+
"""
|
|
199
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
200
|
+
return self._api.get(
|
|
201
|
+
"/v1/analytics/projects-spending",
|
|
202
|
+
TabularResponse,
|
|
203
|
+
params=query_params,
|
|
204
|
+
wrap_response=False,
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
def get_llms_usage(
|
|
208
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
209
|
+
) -> TabularResponse:
|
|
210
|
+
"""Get top LLMs usage analytics.
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
params: Query parameters (filters + pagination)
|
|
214
|
+
|
|
215
|
+
Returns:
|
|
216
|
+
TabularResponse with LLM model usage distribution showing
|
|
217
|
+
preference patterns across different models
|
|
218
|
+
"""
|
|
219
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
220
|
+
return self._api.get(
|
|
221
|
+
"/v1/analytics/llms-usage",
|
|
222
|
+
TabularResponse,
|
|
223
|
+
params=query_params,
|
|
224
|
+
wrap_response=False,
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
def get_users_spending(
|
|
228
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
229
|
+
) -> TabularResponse:
|
|
230
|
+
"""Get money spent by users.
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
params: Query parameters (filters + pagination)
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
TabularResponse with individual user spending ranked by amount
|
|
237
|
+
"""
|
|
238
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
239
|
+
return self._api.get(
|
|
240
|
+
"/v1/analytics/users-spending",
|
|
241
|
+
TabularResponse,
|
|
242
|
+
params=query_params,
|
|
243
|
+
wrap_response=False,
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
def get_budget_soft_limit(
|
|
247
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
248
|
+
) -> TabularResponse:
|
|
249
|
+
"""Get soft budget limit violations.
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
params: Query parameters (filters + pagination)
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
TabularResponse with users who have exceeded soft budget limits
|
|
256
|
+
(warning threshold)
|
|
257
|
+
"""
|
|
258
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
259
|
+
return self._api.get(
|
|
260
|
+
"/v1/analytics/budget-soft-limit",
|
|
261
|
+
TabularResponse,
|
|
262
|
+
params=query_params,
|
|
263
|
+
wrap_response=False,
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
def get_budget_hard_limit(
|
|
267
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
268
|
+
) -> TabularResponse:
|
|
269
|
+
"""Get hard budget limit violations.
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
params: Query parameters (filters + pagination)
|
|
273
|
+
|
|
274
|
+
Returns:
|
|
275
|
+
TabularResponse with users who have reached or exceeded hard budget
|
|
276
|
+
limits (enforcement threshold)
|
|
277
|
+
"""
|
|
278
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
279
|
+
return self._api.get(
|
|
280
|
+
"/v1/analytics/budget-hard-limit",
|
|
281
|
+
TabularResponse,
|
|
282
|
+
params=query_params,
|
|
283
|
+
wrap_response=False,
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
def get_users_activity(
|
|
287
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
288
|
+
) -> TabularResponse:
|
|
289
|
+
"""Get most active users analytics.
|
|
290
|
+
|
|
291
|
+
Args:
|
|
292
|
+
params: Query parameters (filters + pagination)
|
|
293
|
+
|
|
294
|
+
Returns:
|
|
295
|
+
TabularResponse with comprehensive user activity metrics including
|
|
296
|
+
spending, recent projects, and token consumption
|
|
297
|
+
"""
|
|
298
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
299
|
+
return self._api.get(
|
|
300
|
+
"/v1/analytics/users-activity",
|
|
301
|
+
TabularResponse,
|
|
302
|
+
params=query_params,
|
|
303
|
+
wrap_response=False,
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
def get_projects_activity(
|
|
307
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
308
|
+
) -> TabularResponse:
|
|
309
|
+
"""Get most active projects analytics.
|
|
310
|
+
|
|
311
|
+
Args:
|
|
312
|
+
params: Query parameters (filters + pagination)
|
|
313
|
+
|
|
314
|
+
Returns:
|
|
315
|
+
TabularResponse with project activity metrics including spending,
|
|
316
|
+
active user counts, and token consumption
|
|
317
|
+
"""
|
|
318
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
319
|
+
return self._api.get(
|
|
320
|
+
"/v1/analytics/projects-activity",
|
|
321
|
+
TabularResponse,
|
|
322
|
+
params=query_params,
|
|
323
|
+
wrap_response=False,
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
def get_agents_usage(
|
|
327
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
328
|
+
) -> TabularResponse:
|
|
329
|
+
"""Get top agents usage analytics.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
params: Query parameters (filters + pagination)
|
|
333
|
+
|
|
334
|
+
Returns:
|
|
335
|
+
TabularResponse with agent usage analytics including invocations,
|
|
336
|
+
spending, user adoption, tool usage, and error tracking
|
|
337
|
+
"""
|
|
338
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
339
|
+
return self._api.get(
|
|
340
|
+
"/v1/analytics/agents-usage",
|
|
341
|
+
TabularResponse,
|
|
342
|
+
params=query_params,
|
|
343
|
+
wrap_response=False,
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
def get_cli_agents(
|
|
347
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
348
|
+
) -> TabularResponse:
|
|
349
|
+
"""Get top CLI agents analytics.
|
|
350
|
+
|
|
351
|
+
Args:
|
|
352
|
+
params: Query parameters (filters + pagination)
|
|
353
|
+
|
|
354
|
+
Returns:
|
|
355
|
+
TabularResponse with CLI agent usage distribution showing
|
|
356
|
+
percentage share of each agent
|
|
357
|
+
"""
|
|
358
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
359
|
+
return self._api.get(
|
|
360
|
+
"/v1/analytics/cli-agents",
|
|
361
|
+
TabularResponse,
|
|
362
|
+
params=query_params,
|
|
363
|
+
wrap_response=False,
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
def get_cli_llms(
|
|
367
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
368
|
+
) -> TabularResponse:
|
|
369
|
+
"""Get top CLI LLMs analytics.
|
|
370
|
+
|
|
371
|
+
Args:
|
|
372
|
+
params: Query parameters (filters + pagination)
|
|
373
|
+
|
|
374
|
+
Returns:
|
|
375
|
+
TabularResponse with LLM model usage distribution in CLI context
|
|
376
|
+
showing percentage share
|
|
377
|
+
"""
|
|
378
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
379
|
+
return self._api.get(
|
|
380
|
+
"/v1/analytics/cli-llms",
|
|
381
|
+
TabularResponse,
|
|
382
|
+
params=query_params,
|
|
383
|
+
wrap_response=False,
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
def get_cli_users(
|
|
387
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
388
|
+
) -> TabularResponse:
|
|
389
|
+
"""Get most active CLI users analytics.
|
|
390
|
+
|
|
391
|
+
Args:
|
|
392
|
+
params: Query parameters (filters + pagination)
|
|
393
|
+
|
|
394
|
+
Returns:
|
|
395
|
+
TabularResponse with CLI user activity showing total invocation
|
|
396
|
+
counts per user
|
|
397
|
+
"""
|
|
398
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
399
|
+
return self._api.get(
|
|
400
|
+
"/v1/analytics/cli-users",
|
|
401
|
+
TabularResponse,
|
|
402
|
+
params=query_params,
|
|
403
|
+
wrap_response=False,
|
|
404
|
+
)
|
|
405
|
+
|
|
406
|
+
def get_cli_errors(
|
|
407
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
408
|
+
) -> TabularResponse:
|
|
409
|
+
"""Get top error codes for CLI.
|
|
410
|
+
|
|
411
|
+
Args:
|
|
412
|
+
params: Query parameters (filters + pagination)
|
|
413
|
+
|
|
414
|
+
Returns:
|
|
415
|
+
TabularResponse with most common CLI error codes with occurrence
|
|
416
|
+
counts for troubleshooting
|
|
417
|
+
"""
|
|
418
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
419
|
+
return self._api.get(
|
|
420
|
+
"/v1/analytics/cli-errors",
|
|
421
|
+
TabularResponse,
|
|
422
|
+
params=query_params,
|
|
423
|
+
wrap_response=False,
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
def get_cli_repositories(
|
|
427
|
+
self, params: Optional[PaginatedAnalyticsQueryParams] = None
|
|
428
|
+
) -> TabularResponse:
|
|
429
|
+
"""Get repository statistics.
|
|
430
|
+
|
|
431
|
+
Args:
|
|
432
|
+
params: Query parameters (filters + pagination)
|
|
433
|
+
|
|
434
|
+
Returns:
|
|
435
|
+
TabularResponse with repository-level metrics including code changes,
|
|
436
|
+
token consumption, and branch activity
|
|
437
|
+
"""
|
|
438
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
439
|
+
return self._api.get(
|
|
440
|
+
"/v1/analytics/cli-repositories",
|
|
441
|
+
TabularResponse,
|
|
442
|
+
params=query_params,
|
|
443
|
+
wrap_response=False,
|
|
444
|
+
)
|
|
445
|
+
|
|
446
|
+
def get_users(
|
|
447
|
+
self, params: Optional[AnalyticsQueryParams] = None
|
|
448
|
+
) -> UsersListResponse:
|
|
449
|
+
"""Get users list.
|
|
450
|
+
|
|
451
|
+
Args:
|
|
452
|
+
params: Query parameters (time filters, user/project filters)
|
|
453
|
+
|
|
454
|
+
Returns:
|
|
455
|
+
UsersListResponse with list of unique users
|
|
456
|
+
"""
|
|
457
|
+
query_params = params.model_dump(exclude_none=True) if params else {}
|
|
458
|
+
return self._api.get(
|
|
459
|
+
"/v1/analytics/users",
|
|
460
|
+
UsersListResponse,
|
|
461
|
+
params=query_params,
|
|
462
|
+
wrap_response=False,
|
|
463
|
+
)
|
|
@@ -14,6 +14,8 @@ from ..models.assistant import (
|
|
|
14
14
|
Assistant,
|
|
15
15
|
AssistantCreateRequest,
|
|
16
16
|
AssistantUpdateRequest,
|
|
17
|
+
AssistantCreateResponse,
|
|
18
|
+
AssistantUpdateResponse,
|
|
17
19
|
ToolKitDetails,
|
|
18
20
|
AssistantChatRequest,
|
|
19
21
|
BaseModelResponse,
|
|
@@ -90,20 +92,24 @@ class AssistantService:
|
|
|
90
92
|
"""
|
|
91
93
|
return self._api.get(f"/v1/assistants/slug/{slug}", Assistant)
|
|
92
94
|
|
|
93
|
-
def create(self, request: AssistantCreateRequest) ->
|
|
95
|
+
def create(self, request: AssistantCreateRequest) -> AssistantCreateResponse:
|
|
94
96
|
"""Create a new assistant.
|
|
95
97
|
|
|
96
98
|
Args:
|
|
97
99
|
request: Assistant creation request
|
|
98
100
|
|
|
99
101
|
Returns:
|
|
100
|
-
|
|
102
|
+
AssistantCreateResponse with assistant_id and optional validation results
|
|
101
103
|
"""
|
|
102
104
|
return self._api.post(
|
|
103
|
-
"/v1/assistants",
|
|
105
|
+
"/v1/assistants",
|
|
106
|
+
AssistantCreateResponse,
|
|
107
|
+
json_data=request.model_dump(exclude_none=True),
|
|
104
108
|
)
|
|
105
109
|
|
|
106
|
-
def update(
|
|
110
|
+
def update(
|
|
111
|
+
self, assistant_id: str, request: AssistantUpdateRequest
|
|
112
|
+
) -> AssistantUpdateResponse:
|
|
107
113
|
"""Update an existing assistant.
|
|
108
114
|
|
|
109
115
|
Args:
|
|
@@ -111,11 +117,11 @@ class AssistantService:
|
|
|
111
117
|
request: Assistant update request
|
|
112
118
|
|
|
113
119
|
Returns:
|
|
114
|
-
|
|
120
|
+
AssistantUpdateResponse with optional validation results
|
|
115
121
|
"""
|
|
116
122
|
return self._api.put(
|
|
117
123
|
f"/v1/assistants/{assistant_id}",
|
|
118
|
-
|
|
124
|
+
AssistantUpdateResponse,
|
|
119
125
|
json_data=request.model_dump(exclude_none=True),
|
|
120
126
|
)
|
|
121
127
|
|
|
@@ -296,7 +302,8 @@ class AssistantService:
|
|
|
296
302
|
if hasattr(version, "assistant_ids")
|
|
297
303
|
else assistant.assistant_ids,
|
|
298
304
|
)
|
|
299
|
-
|
|
305
|
+
update_resp = self.update(assistant_id, update_req)
|
|
306
|
+
resp = update_resp.model_dump()
|
|
300
307
|
resp["_rollback_fallback"] = True
|
|
301
308
|
resp["_target_version"] = version_number
|
|
302
309
|
if change_notes:
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""CodeMie guardrail service implementation for managing guardrail assignments."""
|
|
2
|
+
|
|
3
|
+
from ..models.guardrails import (
|
|
4
|
+
GuardrailAssignmentRequest,
|
|
5
|
+
GuardrailAssignmentResponse,
|
|
6
|
+
)
|
|
7
|
+
from ..utils import ApiRequestHandler
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CodemieGuardrailService:
|
|
11
|
+
"""Service for managing CodeMie guardrail assignments."""
|
|
12
|
+
|
|
13
|
+
def __init__(self, api_domain: str, token: str, verify_ssl: bool = True):
|
|
14
|
+
"""Initialize the CodeMie guardrail service.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
api_domain: Base URL for the CodeMie API
|
|
18
|
+
token: Authentication token
|
|
19
|
+
verify_ssl: Whether to verify SSL certificates
|
|
20
|
+
"""
|
|
21
|
+
self._api = ApiRequestHandler(api_domain, token, verify_ssl)
|
|
22
|
+
|
|
23
|
+
def assign_guardrails(
|
|
24
|
+
self,
|
|
25
|
+
guardrail_id: str,
|
|
26
|
+
assignment: GuardrailAssignmentRequest,
|
|
27
|
+
) -> GuardrailAssignmentResponse:
|
|
28
|
+
"""Assign guardrails to project entities (assistants, workflows, datasources).
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
guardrail_id: ID of the guardrail to assign (AI run ID from installation)
|
|
32
|
+
assignment: Assignment configuration for different entity types
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
GuardrailAssignmentResponse with success status
|
|
36
|
+
|
|
37
|
+
Example:
|
|
38
|
+
>>> from codemie_sdk.models.guardrails import (
|
|
39
|
+
... GuardrailAssignmentRequest,
|
|
40
|
+
... GuardrailAssignmentEntity,
|
|
41
|
+
... GuardrailAssignmentSetting
|
|
42
|
+
... )
|
|
43
|
+
>>> # Assign guardrail to all project assistants
|
|
44
|
+
>>> assignment = GuardrailAssignmentRequest(
|
|
45
|
+
... assistants=GuardrailAssignmentEntity(
|
|
46
|
+
... settings=[GuardrailAssignmentSetting(mode="all", source="input")],
|
|
47
|
+
... items=[]
|
|
48
|
+
... )
|
|
49
|
+
... )
|
|
50
|
+
>>> response = client.codemie_guardrails.assign_guardrails(
|
|
51
|
+
... guardrail_id="ai_run_123",
|
|
52
|
+
... assignment=assignment
|
|
53
|
+
... )
|
|
54
|
+
>>> if response.success:
|
|
55
|
+
... print("Guardrail assigned successfully!")
|
|
56
|
+
>>>
|
|
57
|
+
>>> # Assign to specific assistants
|
|
58
|
+
>>> assignment = GuardrailAssignmentRequest(
|
|
59
|
+
... assistants=GuardrailAssignmentEntity(
|
|
60
|
+
... settings=[],
|
|
61
|
+
... items=["asst_123", "asst_456"]
|
|
62
|
+
... )
|
|
63
|
+
... )
|
|
64
|
+
>>> response = client.codemie_guardrails.assign_guardrails(
|
|
65
|
+
... guardrail_id="ai_run_123",
|
|
66
|
+
... assignment=assignment
|
|
67
|
+
... )
|
|
68
|
+
"""
|
|
69
|
+
payload = assignment.model_dump(by_alias=True)
|
|
70
|
+
|
|
71
|
+
return self._api.put(
|
|
72
|
+
f"/v1/guardrails/{guardrail_id}/assignments",
|
|
73
|
+
GuardrailAssignmentResponse,
|
|
74
|
+
json_data=payload,
|
|
75
|
+
wrap_response=False,
|
|
76
|
+
)
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
codemie_sdk/__init__.py,sha256=
|
|
1
|
+
codemie_sdk/__init__.py,sha256=4ha4xbTsassZHl3AsbIM6rEF3wfl0h2e0YcZiAOZb7Q,5258
|
|
2
2
|
codemie_sdk/auth/__init__.py,sha256=IksEj223xEZtJ-cQ0AT9L0Bs9psIJ8QNzDXrPTUQ3xQ,126
|
|
3
3
|
codemie_sdk/auth/credentials.py,sha256=OzR_CXPBNTEC6VmNdzcCHF7rWWGrVf3agAlGKgPtTiU,4361
|
|
4
4
|
codemie_sdk/client/__init__.py,sha256=yf6C39MmrJ6gK9ZHMhBeynKwUUYVSUTQbKxU8-4qpKg,101
|
|
5
|
-
codemie_sdk/client/client.py,sha256=
|
|
5
|
+
codemie_sdk/client/client.py,sha256=SV-wo892o3YlvaGcLL9Cx0mDFggBZFBsxCVfZwjnokI,8039
|
|
6
6
|
codemie_sdk/exceptions.py,sha256=XoVPyognx-JmyVxLHkZPAcX1CMi1OoT1diBFJLU54so,1183
|
|
7
7
|
codemie_sdk/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
codemie_sdk/models/
|
|
8
|
+
codemie_sdk/models/admin.py,sha256=eAsz4rFFrXCXjUubn4U23AmhZA5bAT0ip5RyfyEc5e0,805
|
|
9
|
+
codemie_sdk/models/analytics.py,sha256=mquZwaIwouQMAXEDy0E5ClvmIFz7rtTcgu-OzVhTMn4,5008
|
|
10
|
+
codemie_sdk/models/assistant.py,sha256=KJ1bgDKRnur_O1XNlE__Um-mI_zG_LLO2WLDUlL9VQw,15907
|
|
9
11
|
codemie_sdk/models/common.py,sha256=gmZ-ps8TbaieNKr0kUKoQEjhVrHD2CAYomOpZQRatH8,1195
|
|
10
12
|
codemie_sdk/models/conversation.py,sha256=tGlqtVnoRCbTm8J8Y1BUmBvMpLW3IRFE0CIHJYoNU_Y,4238
|
|
11
13
|
codemie_sdk/models/datasource.py,sha256=rL1pUkdPq7_KmnuPkSCO9Bp7DlAXCN51YrtbP3os3qM,13843
|
|
12
14
|
codemie_sdk/models/file_operation.py,sha256=D2hnsxOO9lzVMw0BNCgKPfHf28bWQmbw5rccgaTXI90,747
|
|
15
|
+
codemie_sdk/models/guardrails.py,sha256=6AyN0kx8lII85jFwLQztdCZJ2nPpjAoI6PU2f3TP7RM,2139
|
|
13
16
|
codemie_sdk/models/integration.py,sha256=FFFcggLf9kh5QVle1T8Jexyh5bc3hgh39YHIp8xfMZ0,2328
|
|
14
17
|
codemie_sdk/models/llm.py,sha256=ppb9-1dx1UFhRuJpSR3ij7H6Pfhe9nO4C4BEOIbToy4,1192
|
|
15
18
|
codemie_sdk/models/task.py,sha256=J4ZFRY3s8qBGrqB5NLQF0rMbInLh4s7OEZ0ZfmnW0Ho,1476
|
|
@@ -22,7 +25,10 @@ codemie_sdk/models/workflow.py,sha256=qfk0rBJnFUMpcEDq_E5GB3hzYKbe_bb2NYJlLZJwUE
|
|
|
22
25
|
codemie_sdk/models/workflow_execution_payload.py,sha256=Pa28ElqsJLudscJnmZhXUEJWJXLw55xc-KYBPi97EZ4,724
|
|
23
26
|
codemie_sdk/models/workflow_state.py,sha256=okEMKzkiBU3GHs9VNBoiEMOnOeZRMXGYtpL0NYSg-FY,1374
|
|
24
27
|
codemie_sdk/models/workflow_thoughts.py,sha256=CjHaIPgca9kQAjpoq8IpX4MuDeql1SvaoKS5RmyU2SE,616
|
|
25
|
-
codemie_sdk/services/
|
|
28
|
+
codemie_sdk/services/admin.py,sha256=j_d_LuHHC70ckIz1ImqwccQIk1Ew05_Hl0-lw6meWVA,1723
|
|
29
|
+
codemie_sdk/services/analytics.py,sha256=A7J-cC-82vD1m8bLYX3Nyz5MdpveuMT61-M_827f52A,14956
|
|
30
|
+
codemie_sdk/services/assistant.py,sha256=GIiD_t-g1dJnuNmZOQZlr4020hse0NIBE1mULQS_65k,16247
|
|
31
|
+
codemie_sdk/services/codemie_guardrails.py,sha256=VI4dqoswYAQMHCgTsJds7Uugq0zk9TPSdKzt6keSyQQ,2812
|
|
26
32
|
codemie_sdk/services/conversation.py,sha256=Ss0mkGaBi4u8-YKzhRYUJOfoFqJueDp9JurI5DRCGT8,2566
|
|
27
33
|
codemie_sdk/services/datasource.py,sha256=vusKiIyRZwliBUPzp78saXuiIEAg1f4FLz-g5ildRFY,9773
|
|
28
34
|
codemie_sdk/services/files.py,sha256=SgqPmI1jnWIQ7pdxZSaRDnCFU7OnJllb5XLH-1q3zNg,2512
|
|
@@ -40,6 +46,6 @@ codemie_sdk/services/workflow_execution.py,sha256=BfbnoyMutQ4_SkpKdCi-F2A5r9JqEf
|
|
|
40
46
|
codemie_sdk/services/workflow_execution_state.py,sha256=tXoaa8yT09xgYEUNiHhVULe76TwGwVgZupMIUyyLxdo,2070
|
|
41
47
|
codemie_sdk/utils/__init__.py,sha256=BXAJJfAzO89-kMYvWWo9wSNhSbGgF3vB1In9sePFhMM,109
|
|
42
48
|
codemie_sdk/utils/http.py,sha256=pVNYH1PTqfu8ZzP3tBCugVUOroh_QcKu2ej8EzeDm4Q,10337
|
|
43
|
-
codemie_sdk_python-0.1.
|
|
44
|
-
codemie_sdk_python-0.1.
|
|
45
|
-
codemie_sdk_python-0.1.
|
|
49
|
+
codemie_sdk_python-0.1.289.dist-info/METADATA,sha256=GnMMB5-Ho8ArDwv2VrRfH38nk4CN7x6Kb1MaulAi4vo,36787
|
|
50
|
+
codemie_sdk_python-0.1.289.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
51
|
+
codemie_sdk_python-0.1.289.dist-info/RECORD,,
|
|
File without changes
|