ainative-python 2.0.0__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.
- ainative/__init__.py +46 -0
- ainative/agent_coordination.py +249 -0
- ainative/agent_identity_system.py +1566 -0
- ainative/agent_learning.py +239 -0
- ainative/agent_orchestration.py +202 -0
- ainative/agent_state.py +231 -0
- ainative/agent_swarm/__init__.py +510 -0
- ainative/auth.py +113 -0
- ainative/cli.py +698 -0
- ainative/cli_utils/__init__.py +13 -0
- ainative/cli_utils/diff.py +292 -0
- ainative/cli_utils/formatters.py +227 -0
- ainative/client.py +272 -0
- ainative/commands/__init__.py +28 -0
- ainative/commands/agents.py +238 -0
- ainative/commands/coordination.py +108 -0
- ainative/commands/inspect.py +483 -0
- ainative/commands/learning.py +119 -0
- ainative/commands/local.py +544 -0
- ainative/commands/state.py +144 -0
- ainative/commands/swarm.py +184 -0
- ainative/commands/sync.py +157 -0
- ainative/commands/tasks.py +191 -0
- ainative/exceptions.py +87 -0
- ainative/zerodb/__init__.py +89 -0
- ainative/zerodb/analytics.py +232 -0
- ainative/zerodb/memory.py +260 -0
- ainative/zerodb/projects.py +224 -0
- ainative/zerodb/tables.py +362 -0
- ainative/zerodb/vectors.py +231 -0
- ainative_python-2.0.0.dist-info/METADATA +550 -0
- ainative_python-2.0.0.dist-info/RECORD +35 -0
- ainative_python-2.0.0.dist-info/WHEEL +5 -0
- ainative_python-2.0.0.dist-info/entry_points.txt +2 -0
- ainative_python-2.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ZeroDB Analytics Module
|
|
3
|
+
|
|
4
|
+
Provides analytics and insights for ZeroDB operations.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING, Dict, Any, Optional, List
|
|
8
|
+
from datetime import datetime, timedelta
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from ..client import AINativeClient
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AnalyticsClient:
|
|
15
|
+
"""Client for ZeroDB analytics operations."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, client: "AINativeClient"):
|
|
18
|
+
"""
|
|
19
|
+
Initialize analytics client.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
client: Parent AINative client instance
|
|
23
|
+
"""
|
|
24
|
+
self.client = client
|
|
25
|
+
self.base_path = "/zerodb/analytics"
|
|
26
|
+
|
|
27
|
+
def get_usage(
|
|
28
|
+
self,
|
|
29
|
+
project_id: Optional[str] = None,
|
|
30
|
+
start_date: Optional[datetime] = None,
|
|
31
|
+
end_date: Optional[datetime] = None,
|
|
32
|
+
granularity: str = "daily",
|
|
33
|
+
) -> Dict[str, Any]:
|
|
34
|
+
"""
|
|
35
|
+
Get usage analytics.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
project_id: Optional project ID filter
|
|
39
|
+
start_date: Start date for analytics
|
|
40
|
+
end_date: End date for analytics
|
|
41
|
+
granularity: Data granularity (hourly, daily, weekly, monthly)
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
Usage analytics data
|
|
45
|
+
"""
|
|
46
|
+
params = {"granularity": granularity}
|
|
47
|
+
|
|
48
|
+
if project_id:
|
|
49
|
+
params["project_id"] = project_id
|
|
50
|
+
if start_date:
|
|
51
|
+
params["start_date"] = start_date.isoformat()
|
|
52
|
+
if end_date:
|
|
53
|
+
params["end_date"] = end_date.isoformat()
|
|
54
|
+
|
|
55
|
+
return self.client.get(f"{self.base_path}/usage", params=params)
|
|
56
|
+
|
|
57
|
+
def get_performance_metrics(
|
|
58
|
+
self,
|
|
59
|
+
project_id: Optional[str] = None,
|
|
60
|
+
metric_type: str = "all",
|
|
61
|
+
) -> Dict[str, Any]:
|
|
62
|
+
"""
|
|
63
|
+
Get performance metrics.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
project_id: Optional project ID filter
|
|
67
|
+
metric_type: Type of metrics (latency, throughput, errors, all)
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
Performance metrics data
|
|
71
|
+
"""
|
|
72
|
+
params = {"metric_type": metric_type}
|
|
73
|
+
|
|
74
|
+
if project_id:
|
|
75
|
+
params["project_id"] = project_id
|
|
76
|
+
|
|
77
|
+
return self.client.get(f"{self.base_path}/performance", params=params)
|
|
78
|
+
|
|
79
|
+
def get_storage_stats(
|
|
80
|
+
self,
|
|
81
|
+
project_id: Optional[str] = None,
|
|
82
|
+
) -> Dict[str, Any]:
|
|
83
|
+
"""
|
|
84
|
+
Get storage statistics.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
project_id: Optional project ID filter
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
Storage statistics including size, vector count, etc.
|
|
91
|
+
"""
|
|
92
|
+
params = {}
|
|
93
|
+
if project_id:
|
|
94
|
+
params["project_id"] = project_id
|
|
95
|
+
|
|
96
|
+
return self.client.get(f"{self.base_path}/storage", params=params)
|
|
97
|
+
|
|
98
|
+
def get_query_insights(
|
|
99
|
+
self,
|
|
100
|
+
project_id: Optional[str] = None,
|
|
101
|
+
limit: int = 100,
|
|
102
|
+
) -> Dict[str, Any]:
|
|
103
|
+
"""
|
|
104
|
+
Get query pattern insights.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
project_id: Optional project ID filter
|
|
108
|
+
limit: Maximum number of insights
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
Query insights and patterns
|
|
112
|
+
"""
|
|
113
|
+
params = {"limit": limit}
|
|
114
|
+
|
|
115
|
+
if project_id:
|
|
116
|
+
params["project_id"] = project_id
|
|
117
|
+
|
|
118
|
+
return self.client.get(f"{self.base_path}/queries", params=params)
|
|
119
|
+
|
|
120
|
+
def get_cost_analysis(
|
|
121
|
+
self,
|
|
122
|
+
project_id: Optional[str] = None,
|
|
123
|
+
start_date: Optional[datetime] = None,
|
|
124
|
+
end_date: Optional[datetime] = None,
|
|
125
|
+
) -> Dict[str, Any]:
|
|
126
|
+
"""
|
|
127
|
+
Get cost analysis and projections.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
project_id: Optional project ID filter
|
|
131
|
+
start_date: Start date for analysis
|
|
132
|
+
end_date: End date for analysis
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
Cost analysis data
|
|
136
|
+
"""
|
|
137
|
+
params = {}
|
|
138
|
+
|
|
139
|
+
if project_id:
|
|
140
|
+
params["project_id"] = project_id
|
|
141
|
+
if start_date:
|
|
142
|
+
params["start_date"] = start_date.isoformat()
|
|
143
|
+
if end_date:
|
|
144
|
+
params["end_date"] = end_date.isoformat()
|
|
145
|
+
|
|
146
|
+
return self.client.get(f"{self.base_path}/costs", params=params)
|
|
147
|
+
|
|
148
|
+
def get_trends(
|
|
149
|
+
self,
|
|
150
|
+
metric: str,
|
|
151
|
+
project_id: Optional[str] = None,
|
|
152
|
+
period: int = 30,
|
|
153
|
+
) -> List[Dict[str, Any]]:
|
|
154
|
+
"""
|
|
155
|
+
Get trend data for specific metrics.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
metric: Metric name (vectors, queries, storage, errors)
|
|
159
|
+
project_id: Optional project ID filter
|
|
160
|
+
period: Number of days to analyze
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
Trend data points
|
|
164
|
+
"""
|
|
165
|
+
params = {
|
|
166
|
+
"metric": metric,
|
|
167
|
+
"period": period,
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if project_id:
|
|
171
|
+
params["project_id"] = project_id
|
|
172
|
+
|
|
173
|
+
response = self.client.get(f"{self.base_path}/trends", params=params)
|
|
174
|
+
return response.get("data", [])
|
|
175
|
+
|
|
176
|
+
def get_anomalies(
|
|
177
|
+
self,
|
|
178
|
+
project_id: Optional[str] = None,
|
|
179
|
+
severity: str = "all",
|
|
180
|
+
) -> List[Dict[str, Any]]:
|
|
181
|
+
"""
|
|
182
|
+
Get detected anomalies in usage patterns.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
project_id: Optional project ID filter
|
|
186
|
+
severity: Severity filter (low, medium, high, critical, all)
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
List of detected anomalies
|
|
190
|
+
"""
|
|
191
|
+
params = {"severity": severity}
|
|
192
|
+
|
|
193
|
+
if project_id:
|
|
194
|
+
params["project_id"] = project_id
|
|
195
|
+
|
|
196
|
+
response = self.client.get(f"{self.base_path}/anomalies", params=params)
|
|
197
|
+
return response.get("anomalies", [])
|
|
198
|
+
|
|
199
|
+
def export_report(
|
|
200
|
+
self,
|
|
201
|
+
report_type: str = "summary",
|
|
202
|
+
project_id: Optional[str] = None,
|
|
203
|
+
format: str = "json",
|
|
204
|
+
start_date: Optional[datetime] = None,
|
|
205
|
+
end_date: Optional[datetime] = None,
|
|
206
|
+
) -> Dict[str, Any]:
|
|
207
|
+
"""
|
|
208
|
+
Export analytics report.
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
report_type: Type of report (summary, detailed, custom)
|
|
212
|
+
project_id: Optional project ID filter
|
|
213
|
+
format: Export format (json, csv, pdf)
|
|
214
|
+
start_date: Start date for report
|
|
215
|
+
end_date: End date for report
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
Report data or download URL
|
|
219
|
+
"""
|
|
220
|
+
data = {
|
|
221
|
+
"report_type": report_type,
|
|
222
|
+
"format": format,
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if project_id:
|
|
226
|
+
data["project_id"] = project_id
|
|
227
|
+
if start_date:
|
|
228
|
+
data["start_date"] = start_date.isoformat()
|
|
229
|
+
if end_date:
|
|
230
|
+
data["end_date"] = end_date.isoformat()
|
|
231
|
+
|
|
232
|
+
return self.client.post(f"{self.base_path}/export", data=data)
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ZeroDB Memory Module
|
|
3
|
+
|
|
4
|
+
Handles memory operations for context retention and retrieval.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING, List, Dict, Any, Optional
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
from enum import Enum
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from ..client import AINativeClient
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class MemoryPriority(Enum):
|
|
16
|
+
"""Memory priority levels."""
|
|
17
|
+
LOW = "low"
|
|
18
|
+
MEDIUM = "medium"
|
|
19
|
+
HIGH = "high"
|
|
20
|
+
CRITICAL = "critical"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class MemoryClient:
|
|
24
|
+
"""Client for ZeroDB memory operations."""
|
|
25
|
+
|
|
26
|
+
def __init__(self, client: "AINativeClient"):
|
|
27
|
+
"""
|
|
28
|
+
Initialize memory client.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
client: Parent AINative client instance
|
|
32
|
+
"""
|
|
33
|
+
self.client = client
|
|
34
|
+
self.base_path = "/zerodb/memory"
|
|
35
|
+
|
|
36
|
+
def create(
|
|
37
|
+
self,
|
|
38
|
+
content: str,
|
|
39
|
+
title: Optional[str] = None,
|
|
40
|
+
tags: Optional[List[str]] = None,
|
|
41
|
+
priority: MemoryPriority = MemoryPriority.MEDIUM,
|
|
42
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
43
|
+
project_id: Optional[str] = None,
|
|
44
|
+
user_id: Optional[str] = None,
|
|
45
|
+
expires_at: Optional[datetime] = None,
|
|
46
|
+
) -> Dict[str, Any]:
|
|
47
|
+
"""
|
|
48
|
+
Create a new memory entry.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
content: Memory content
|
|
52
|
+
title: Memory title
|
|
53
|
+
tags: List of tags
|
|
54
|
+
priority: Memory priority level
|
|
55
|
+
metadata: Additional metadata
|
|
56
|
+
project_id: Associated project ID
|
|
57
|
+
user_id: Associated user ID
|
|
58
|
+
expires_at: Expiration timestamp
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
Created memory details
|
|
62
|
+
"""
|
|
63
|
+
data = {
|
|
64
|
+
"content": content,
|
|
65
|
+
"title": title or "Memory Entry",
|
|
66
|
+
"tags": tags or [],
|
|
67
|
+
"priority": priority.value,
|
|
68
|
+
"metadata": metadata or {},
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if project_id:
|
|
72
|
+
data["project_id"] = project_id
|
|
73
|
+
if user_id:
|
|
74
|
+
data["user_id"] = user_id
|
|
75
|
+
if expires_at:
|
|
76
|
+
data["expires_at"] = expires_at.isoformat()
|
|
77
|
+
|
|
78
|
+
return self.client.post(self.base_path, data=data)
|
|
79
|
+
|
|
80
|
+
def list(
|
|
81
|
+
self,
|
|
82
|
+
limit: int = 100,
|
|
83
|
+
offset: int = 0,
|
|
84
|
+
project_id: Optional[str] = None,
|
|
85
|
+
user_id: Optional[str] = None,
|
|
86
|
+
tags: Optional[List[str]] = None,
|
|
87
|
+
priority: Optional[MemoryPriority] = None,
|
|
88
|
+
search: Optional[str] = None,
|
|
89
|
+
) -> Dict[str, Any]:
|
|
90
|
+
"""
|
|
91
|
+
List memory entries.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
limit: Maximum number of entries to return
|
|
95
|
+
offset: Number of entries to skip
|
|
96
|
+
project_id: Filter by project ID
|
|
97
|
+
user_id: Filter by user ID
|
|
98
|
+
tags: Filter by tags
|
|
99
|
+
priority: Filter by priority
|
|
100
|
+
search: Search query
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
Dictionary containing memories list and pagination info
|
|
104
|
+
"""
|
|
105
|
+
params = {
|
|
106
|
+
"limit": limit,
|
|
107
|
+
"offset": offset,
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if project_id:
|
|
111
|
+
params["project_id"] = project_id
|
|
112
|
+
if user_id:
|
|
113
|
+
params["user_id"] = user_id
|
|
114
|
+
if tags:
|
|
115
|
+
params["tags"] = ",".join(tags)
|
|
116
|
+
if priority:
|
|
117
|
+
params["priority"] = priority.value
|
|
118
|
+
if search:
|
|
119
|
+
params["search"] = search
|
|
120
|
+
|
|
121
|
+
return self.client.get(f"{self.base_path}ies", params=params)
|
|
122
|
+
|
|
123
|
+
def get(self, memory_id: str) -> Dict[str, Any]:
|
|
124
|
+
"""
|
|
125
|
+
Get a specific memory entry.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
memory_id: Memory ID
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
Memory details
|
|
132
|
+
"""
|
|
133
|
+
return self.client.get(f"{self.base_path}/{memory_id}")
|
|
134
|
+
|
|
135
|
+
def update(
|
|
136
|
+
self,
|
|
137
|
+
memory_id: str,
|
|
138
|
+
content: Optional[str] = None,
|
|
139
|
+
title: Optional[str] = None,
|
|
140
|
+
tags: Optional[List[str]] = None,
|
|
141
|
+
priority: Optional[MemoryPriority] = None,
|
|
142
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
143
|
+
) -> Dict[str, Any]:
|
|
144
|
+
"""
|
|
145
|
+
Update a memory entry.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
memory_id: Memory ID
|
|
149
|
+
content: New content
|
|
150
|
+
title: New title
|
|
151
|
+
tags: New tags
|
|
152
|
+
priority: New priority
|
|
153
|
+
metadata: New metadata
|
|
154
|
+
|
|
155
|
+
Returns:
|
|
156
|
+
Updated memory details
|
|
157
|
+
"""
|
|
158
|
+
data = {}
|
|
159
|
+
if content is not None:
|
|
160
|
+
data["content"] = content
|
|
161
|
+
if title is not None:
|
|
162
|
+
data["title"] = title
|
|
163
|
+
if tags is not None:
|
|
164
|
+
data["tags"] = tags
|
|
165
|
+
if priority is not None:
|
|
166
|
+
data["priority"] = priority.value
|
|
167
|
+
if metadata is not None:
|
|
168
|
+
data["metadata"] = metadata
|
|
169
|
+
|
|
170
|
+
return self.client.patch(f"{self.base_path}/{memory_id}", data=data)
|
|
171
|
+
|
|
172
|
+
def delete(self, memory_id: str) -> Dict[str, Any]:
|
|
173
|
+
"""
|
|
174
|
+
Delete a memory entry.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
memory_id: Memory ID
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
Deletion confirmation
|
|
181
|
+
"""
|
|
182
|
+
return self.client.delete(f"{self.base_path}/{memory_id}")
|
|
183
|
+
|
|
184
|
+
def search(
|
|
185
|
+
self,
|
|
186
|
+
query: str,
|
|
187
|
+
limit: int = 10,
|
|
188
|
+
project_id: Optional[str] = None,
|
|
189
|
+
user_id: Optional[str] = None,
|
|
190
|
+
semantic: bool = True,
|
|
191
|
+
) -> List[Dict[str, Any]]:
|
|
192
|
+
"""
|
|
193
|
+
Search memories using text or semantic search.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
query: Search query
|
|
197
|
+
limit: Maximum number of results
|
|
198
|
+
project_id: Filter by project ID
|
|
199
|
+
user_id: Filter by user ID
|
|
200
|
+
semantic: Use semantic search (if False, uses text search)
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
List of matching memories
|
|
204
|
+
"""
|
|
205
|
+
data = {
|
|
206
|
+
"query": query,
|
|
207
|
+
"limit": limit,
|
|
208
|
+
"semantic": semantic,
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if project_id:
|
|
212
|
+
data["project_id"] = project_id
|
|
213
|
+
if user_id:
|
|
214
|
+
data["user_id"] = user_id
|
|
215
|
+
|
|
216
|
+
response = self.client.post(f"{self.base_path}/search", data=data)
|
|
217
|
+
return response.get("results", [])
|
|
218
|
+
|
|
219
|
+
def bulk_create(
|
|
220
|
+
self,
|
|
221
|
+
memories: List[Dict[str, Any]],
|
|
222
|
+
project_id: Optional[str] = None,
|
|
223
|
+
) -> Dict[str, Any]:
|
|
224
|
+
"""
|
|
225
|
+
Create multiple memory entries at once.
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
memories: List of memory data dictionaries
|
|
229
|
+
project_id: Project ID for all memories
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
Bulk creation result
|
|
233
|
+
"""
|
|
234
|
+
data = {
|
|
235
|
+
"memories": memories,
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if project_id:
|
|
239
|
+
data["project_id"] = project_id
|
|
240
|
+
|
|
241
|
+
return self.client.post(f"{self.base_path}/bulk", data=data)
|
|
242
|
+
|
|
243
|
+
def get_related(
|
|
244
|
+
self,
|
|
245
|
+
memory_id: str,
|
|
246
|
+
limit: int = 5,
|
|
247
|
+
) -> List[Dict[str, Any]]:
|
|
248
|
+
"""
|
|
249
|
+
Get memories related to a specific memory.
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
memory_id: Memory ID
|
|
253
|
+
limit: Maximum number of related memories
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
List of related memories
|
|
257
|
+
"""
|
|
258
|
+
params = {"limit": limit}
|
|
259
|
+
response = self.client.get(f"{self.base_path}/{memory_id}/related", params=params)
|
|
260
|
+
return response.get("memories", [])
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ZeroDB Projects Module
|
|
3
|
+
|
|
4
|
+
Handles project management operations in ZeroDB.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING, List, Dict, Any, Optional
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
from enum import Enum
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from ..client import AINativeClient
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ProjectStatus(Enum):
|
|
16
|
+
"""Project status enumeration."""
|
|
17
|
+
ACTIVE = "active"
|
|
18
|
+
SUSPENDED = "suspended"
|
|
19
|
+
ARCHIVED = "archived"
|
|
20
|
+
DELETED = "deleted"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ProjectsClient:
|
|
24
|
+
"""Client for ZeroDB project operations."""
|
|
25
|
+
|
|
26
|
+
def __init__(self, client: "AINativeClient"):
|
|
27
|
+
"""
|
|
28
|
+
Initialize projects client.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
client: Parent AINative client instance
|
|
32
|
+
"""
|
|
33
|
+
self.client = client
|
|
34
|
+
self.base_path = "/zerodb/projects"
|
|
35
|
+
|
|
36
|
+
def list(
|
|
37
|
+
self,
|
|
38
|
+
limit: int = 100,
|
|
39
|
+
offset: int = 0,
|
|
40
|
+
status: Optional[ProjectStatus] = None,
|
|
41
|
+
organization_id: Optional[str] = None,
|
|
42
|
+
) -> Dict[str, Any]:
|
|
43
|
+
"""
|
|
44
|
+
List all projects.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
limit: Maximum number of projects to return
|
|
48
|
+
offset: Number of projects to skip
|
|
49
|
+
status: Filter by project status
|
|
50
|
+
organization_id: Filter by organization ID
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
Dictionary containing projects list and pagination info
|
|
54
|
+
"""
|
|
55
|
+
params = {
|
|
56
|
+
"limit": limit,
|
|
57
|
+
"offset": offset,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if status:
|
|
61
|
+
params["status"] = status.value
|
|
62
|
+
if organization_id:
|
|
63
|
+
params["organization_id"] = organization_id
|
|
64
|
+
|
|
65
|
+
return self.client.get(self.base_path, params=params)
|
|
66
|
+
|
|
67
|
+
def create(
|
|
68
|
+
self,
|
|
69
|
+
name: str,
|
|
70
|
+
description: Optional[str] = None,
|
|
71
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
72
|
+
config: Optional[Dict[str, Any]] = None,
|
|
73
|
+
) -> Dict[str, Any]:
|
|
74
|
+
"""
|
|
75
|
+
Create a new project.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
name: Project name
|
|
79
|
+
description: Project description
|
|
80
|
+
metadata: Additional metadata
|
|
81
|
+
config: Project configuration
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
Created project details
|
|
85
|
+
"""
|
|
86
|
+
data = {
|
|
87
|
+
"name": name,
|
|
88
|
+
"description": description or "",
|
|
89
|
+
"metadata": metadata or {},
|
|
90
|
+
"config": config or {},
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return self.client.post(self.base_path, data=data)
|
|
94
|
+
|
|
95
|
+
def get(self, project_id: str) -> Dict[str, Any]:
|
|
96
|
+
"""
|
|
97
|
+
Get project details.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
project_id: Project ID
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
Project details
|
|
104
|
+
"""
|
|
105
|
+
return self.client.get(f"{self.base_path}/{project_id}")
|
|
106
|
+
|
|
107
|
+
def update(
|
|
108
|
+
self,
|
|
109
|
+
project_id: str,
|
|
110
|
+
name: Optional[str] = None,
|
|
111
|
+
description: Optional[str] = None,
|
|
112
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
113
|
+
config: Optional[Dict[str, Any]] = None,
|
|
114
|
+
) -> Dict[str, Any]:
|
|
115
|
+
"""
|
|
116
|
+
Update project details.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
project_id: Project ID
|
|
120
|
+
name: New project name
|
|
121
|
+
description: New project description
|
|
122
|
+
metadata: Updated metadata
|
|
123
|
+
config: Updated configuration
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
Updated project details
|
|
127
|
+
"""
|
|
128
|
+
data = {}
|
|
129
|
+
if name is not None:
|
|
130
|
+
data["name"] = name
|
|
131
|
+
if description is not None:
|
|
132
|
+
data["description"] = description
|
|
133
|
+
if metadata is not None:
|
|
134
|
+
data["metadata"] = metadata
|
|
135
|
+
if config is not None:
|
|
136
|
+
data["config"] = config
|
|
137
|
+
|
|
138
|
+
return self.client.patch(f"{self.base_path}/{project_id}", data=data)
|
|
139
|
+
|
|
140
|
+
def update_status(
|
|
141
|
+
self,
|
|
142
|
+
project_id: str,
|
|
143
|
+
status: ProjectStatus,
|
|
144
|
+
reason: Optional[str] = None,
|
|
145
|
+
) -> Dict[str, Any]:
|
|
146
|
+
"""
|
|
147
|
+
Update project status.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
project_id: Project ID
|
|
151
|
+
status: New status
|
|
152
|
+
reason: Reason for status change
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
Updated project details
|
|
156
|
+
"""
|
|
157
|
+
data = {
|
|
158
|
+
"status": status.value,
|
|
159
|
+
"reason": reason,
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return self.client.put(f"{self.base_path}/{project_id}/status", data=data)
|
|
163
|
+
|
|
164
|
+
def suspend(self, project_id: str, reason: Optional[str] = None) -> Dict[str, Any]:
|
|
165
|
+
"""
|
|
166
|
+
Suspend a project.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
project_id: Project ID
|
|
170
|
+
reason: Reason for suspension
|
|
171
|
+
|
|
172
|
+
Returns:
|
|
173
|
+
Updated project details
|
|
174
|
+
"""
|
|
175
|
+
return self.update_status(project_id, ProjectStatus.SUSPENDED, reason)
|
|
176
|
+
|
|
177
|
+
def activate(self, project_id: str) -> Dict[str, Any]:
|
|
178
|
+
"""
|
|
179
|
+
Activate a suspended project.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
project_id: Project ID
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
Updated project details
|
|
186
|
+
"""
|
|
187
|
+
return self.update_status(project_id, ProjectStatus.ACTIVE)
|
|
188
|
+
|
|
189
|
+
def delete(self, project_id: str) -> Dict[str, Any]:
|
|
190
|
+
"""
|
|
191
|
+
Delete a project.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
project_id: Project ID
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
Deletion confirmation
|
|
198
|
+
"""
|
|
199
|
+
return self.client.delete(f"{self.base_path}/{project_id}")
|
|
200
|
+
|
|
201
|
+
def get_statistics(self, project_id: str) -> Dict[str, Any]:
|
|
202
|
+
"""
|
|
203
|
+
Get project statistics.
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
project_id: Project ID
|
|
207
|
+
|
|
208
|
+
Returns:
|
|
209
|
+
Project statistics including storage, vectors, etc.
|
|
210
|
+
"""
|
|
211
|
+
return self.client.get(f"{self.base_path}/{project_id}/statistics")
|
|
212
|
+
|
|
213
|
+
def get_collections(self, project_id: str) -> List[Dict[str, Any]]:
|
|
214
|
+
"""
|
|
215
|
+
Get all collections for a project.
|
|
216
|
+
|
|
217
|
+
Args:
|
|
218
|
+
project_id: Project ID
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
List of collections
|
|
222
|
+
"""
|
|
223
|
+
response = self.client.get(f"{self.base_path}/{project_id}/collections")
|
|
224
|
+
return response.get("collections", [])
|