codemie-sdk-python 0.1.286__tar.gz → 0.1.288__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 (51) hide show
  1. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/PKG-INFO +1 -1
  2. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/pyproject.toml +1 -1
  3. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/__init__.py +30 -0
  4. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/client/client.py +7 -0
  5. codemie_sdk_python-0.1.288/src/codemie_sdk/models/analytics.py +148 -0
  6. codemie_sdk_python-0.1.288/src/codemie_sdk/services/analytics.py +463 -0
  7. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/README.md +0 -0
  8. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/auth/__init__.py +0 -0
  9. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/auth/credentials.py +0 -0
  10. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/client/__init__.py +0 -0
  11. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/exceptions.py +0 -0
  12. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/__init__.py +0 -0
  13. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/admin.py +0 -0
  14. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/assistant.py +0 -0
  15. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/common.py +0 -0
  16. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/conversation.py +0 -0
  17. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/datasource.py +0 -0
  18. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/file_operation.py +0 -0
  19. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/guardrails.py +0 -0
  20. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/integration.py +0 -0
  21. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/llm.py +0 -0
  22. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/task.py +0 -0
  23. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/user.py +0 -0
  24. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/vendor_assistant.py +0 -0
  25. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/vendor_guardrail.py +0 -0
  26. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/vendor_knowledgebase.py +0 -0
  27. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/vendor_workflow.py +0 -0
  28. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/workflow.py +0 -0
  29. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/workflow_execution_payload.py +0 -0
  30. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/workflow_state.py +0 -0
  31. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/models/workflow_thoughts.py +0 -0
  32. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/admin.py +0 -0
  33. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/assistant.py +0 -0
  34. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/codemie_guardrails.py +0 -0
  35. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/conversation.py +0 -0
  36. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/datasource.py +0 -0
  37. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/files.py +0 -0
  38. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/integration.py +0 -0
  39. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/llm.py +0 -0
  40. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/task.py +0 -0
  41. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/user.py +0 -0
  42. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/vendor_assistant.py +0 -0
  43. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/vendor_guardrail.py +0 -0
  44. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/vendor_knowledgebase.py +0 -0
  45. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/vendor_workflow.py +0 -0
  46. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/webhook.py +0 -0
  47. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/workflow.py +0 -0
  48. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/workflow_execution.py +0 -0
  49. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/services/workflow_execution_state.py +0 -0
  50. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/utils/__init__.py +0 -0
  51. {codemie_sdk_python-0.1.286 → codemie_sdk_python-0.1.288}/src/codemie_sdk/utils/http.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: codemie-sdk-python
3
- Version: 0.1.286
3
+ Version: 0.1.288
4
4
  Summary: CodeMie SDK for Python
5
5
  Author: Vadym Vlasenko
6
6
  Author-email: vadym_vlasenko@epam.com
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "codemie-sdk-python"
3
- version = "0.1.286"
3
+ version = "0.1.288"
4
4
  description = "CodeMie SDK for Python"
5
5
  authors = [
6
6
  "Vadym Vlasenko <vadym_vlasenko@epam.com>",
@@ -79,11 +79,27 @@ from .models.guardrails import (
79
79
  GuardrailAssignmentRequest,
80
80
  GuardrailAssignmentResponse,
81
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
+ )
82
97
  from .services.vendor_assistant import VendorAssistantService
83
98
  from .services.vendor_workflow import VendorWorkflowService
84
99
  from .services.vendor_knowledgebase import VendorKnowledgeBaseService
85
100
  from .services.vendor_guardrail import VendorGuardrailService
86
101
  from .services.codemie_guardrails import CodemieGuardrailService
102
+ from .services.analytics import AnalyticsService
87
103
 
88
104
  __version__ = "0.2.12"
89
105
  __all__ = [
@@ -144,4 +160,18 @@ __all__ = [
144
160
  "GuardrailAssignmentRequest",
145
161
  "GuardrailAssignmentResponse",
146
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",
147
177
  ]
@@ -4,6 +4,7 @@ from typing import Optional
4
4
 
5
5
  from ..auth.credentials import KeycloakCredentials
6
6
  from ..services.admin import AdminService
7
+ from ..services.analytics import AnalyticsService
7
8
  from ..services.assistant import AssistantService
8
9
  from ..services.conversation import ConversationService
9
10
  from ..services.datasource import DatasourceService
@@ -72,6 +73,9 @@ class CodeMieClient:
72
73
 
73
74
  # Initialize services with verify_ssl parameter and token
74
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
+ )
75
79
  self.assistants = AssistantService(
76
80
  self._api_domain, self._token, verify_ssl=verify_ssl
77
81
  )
@@ -137,6 +141,9 @@ class CodeMieClient:
137
141
  self.admin = AdminService(
138
142
  self._api_domain, self._token, verify_ssl=self._verify_ssl
139
143
  )
144
+ self.analytics = AnalyticsService(
145
+ self._api_domain, self._token, verify_ssl=self._verify_ssl
146
+ )
140
147
  self.assistants = AssistantService(
141
148
  self._api_domain, self._token, verify_ssl=self._verify_ssl
142
149
  )
@@ -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")
@@ -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
+ )