magickmind 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- magick_mind/__init__.py +39 -0
- magick_mind/auth/__init__.py +9 -0
- magick_mind/auth/base.py +46 -0
- magick_mind/auth/email_password.py +268 -0
- magick_mind/client.py +188 -0
- magick_mind/config.py +28 -0
- magick_mind/exceptions.py +107 -0
- magick_mind/http/__init__.py +5 -0
- magick_mind/http/client.py +313 -0
- magick_mind/models/__init__.py +17 -0
- magick_mind/models/auth.py +30 -0
- magick_mind/models/common.py +32 -0
- magick_mind/models/errors.py +73 -0
- magick_mind/models/v1/__init__.py +83 -0
- magick_mind/models/v1/api_keys.py +115 -0
- magick_mind/models/v1/artifact.py +151 -0
- magick_mind/models/v1/chat.py +104 -0
- magick_mind/models/v1/corpus.py +82 -0
- magick_mind/models/v1/end_user.py +75 -0
- magick_mind/models/v1/history.py +94 -0
- magick_mind/models/v1/mindspace.py +130 -0
- magick_mind/models/v1/model.py +25 -0
- magick_mind/models/v1/project.py +73 -0
- magick_mind/realtime/__init__.py +5 -0
- magick_mind/realtime/client.py +202 -0
- magick_mind/realtime/handler.py +122 -0
- magick_mind/resources/README.md +201 -0
- magick_mind/resources/__init__.py +42 -0
- magick_mind/resources/base.py +31 -0
- magick_mind/resources/v1/__init__.py +19 -0
- magick_mind/resources/v1/api_keys.py +181 -0
- magick_mind/resources/v1/artifact.py +287 -0
- magick_mind/resources/v1/chat.py +120 -0
- magick_mind/resources/v1/corpus.py +156 -0
- magick_mind/resources/v1/end_user.py +181 -0
- magick_mind/resources/v1/history.py +88 -0
- magick_mind/resources/v1/mindspace.py +331 -0
- magick_mind/resources/v1/model.py +19 -0
- magick_mind/resources/v1/project.py +155 -0
- magick_mind/routes.py +76 -0
- magickmind-0.1.1.dist-info/METADATA +593 -0
- magickmind-0.1.1.dist-info/RECORD +43 -0
- magickmind-0.1.1.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
"""V1 mindspace resource implementation."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Optional
|
|
6
|
+
|
|
7
|
+
from magick_mind.models.v1.mindspace import (
|
|
8
|
+
AddMindSpaceUsersRequest,
|
|
9
|
+
CreateMindSpaceRequest,
|
|
10
|
+
GetMindSpaceListResponse,
|
|
11
|
+
MindSpace,
|
|
12
|
+
MindSpaceType,
|
|
13
|
+
MindspaceMessagesResponse,
|
|
14
|
+
UpdateMindSpaceRequest,
|
|
15
|
+
)
|
|
16
|
+
from magick_mind.resources.base import BaseResource
|
|
17
|
+
from magick_mind.routes import Routes
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from magick_mind.http import HTTPClient
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class MindspaceResourceV1(BaseResource):
|
|
24
|
+
"""
|
|
25
|
+
Mindspace resource client for V1 API.
|
|
26
|
+
|
|
27
|
+
Provides typed interface for managing mindspaces (organizational containers
|
|
28
|
+
for chat conversations, corpus, and users).
|
|
29
|
+
|
|
30
|
+
Example:
|
|
31
|
+
# Create a private mindspace
|
|
32
|
+
mindspace = client.v1.mindspace.create(
|
|
33
|
+
name="My Workspace",
|
|
34
|
+
type="private",
|
|
35
|
+
description="Personal workspace",
|
|
36
|
+
corpus_ids=["corp-123"]
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# List all mindspaces
|
|
40
|
+
mindspaces = client.v1.mindspace.list(user_id="user-456")
|
|
41
|
+
|
|
42
|
+
# Get messages from mindspace
|
|
43
|
+
messages = client.v1.mindspace.get_messages(
|
|
44
|
+
mindspace_id="mind-123",
|
|
45
|
+
limit=50
|
|
46
|
+
)
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def create(
|
|
50
|
+
self,
|
|
51
|
+
name: str,
|
|
52
|
+
type: MindSpaceType,
|
|
53
|
+
description: Optional[str] = None,
|
|
54
|
+
project_id: Optional[str] = None,
|
|
55
|
+
corpus_ids: Optional[list[str]] = None,
|
|
56
|
+
user_ids: Optional[list[str]] = None,
|
|
57
|
+
) -> MindSpace:
|
|
58
|
+
"""
|
|
59
|
+
Create a new mindspace.
|
|
60
|
+
Args:
|
|
61
|
+
name: Mindspace name (max 100 characters)
|
|
62
|
+
type: Mindspace type - either "PRIVATE" or "GROUP"
|
|
63
|
+
description: Optional description (max 256 characters)
|
|
64
|
+
project_id: Optional associated project ID
|
|
65
|
+
corpus_ids: Optional list of corpus IDs to attach
|
|
66
|
+
user_ids: Optional list of user IDs to grant access
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
MindSpace
|
|
70
|
+
|
|
71
|
+
Raises:
|
|
72
|
+
HTTPError: If the API request fails
|
|
73
|
+
ValidationError: If parameters are invalid
|
|
74
|
+
|
|
75
|
+
Example:
|
|
76
|
+
# Create a group mindspace
|
|
77
|
+
mindspace = client.v1.mindspace.create(
|
|
78
|
+
name="Engineering Team",
|
|
79
|
+
type="GROUP",
|
|
80
|
+
description="Team collaboration space",
|
|
81
|
+
corpus_ids=["corp-1", "corp-2"],
|
|
82
|
+
user_ids=["user-1", "user-2"]
|
|
83
|
+
)
|
|
84
|
+
print(f"Created mindspace: {mindspace.id}")
|
|
85
|
+
"""
|
|
86
|
+
# Build and validate request
|
|
87
|
+
request = CreateMindSpaceRequest(
|
|
88
|
+
name=name,
|
|
89
|
+
type=type,
|
|
90
|
+
description=description,
|
|
91
|
+
project_id=project_id,
|
|
92
|
+
corpus_ids=corpus_ids or [],
|
|
93
|
+
user_ids=user_ids or [],
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# Make API call
|
|
97
|
+
response = self._http.post(
|
|
98
|
+
Routes.MINDSPACES, json=request.model_dump(exclude_none=True)
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
return MindSpace.model_validate(response)
|
|
102
|
+
|
|
103
|
+
def get(self, mindspace_id: str) -> MindSpace:
|
|
104
|
+
"""
|
|
105
|
+
Get a mindspace by ID.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
mindspace_id: Mindspace ID to retrieve
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
MindSpace
|
|
112
|
+
|
|
113
|
+
Raises:
|
|
114
|
+
HTTPError: If the API request fails or mindspace not found
|
|
115
|
+
|
|
116
|
+
Example:
|
|
117
|
+
mindspace = client.v1.mindspace.get("mind-123")
|
|
118
|
+
print(f"Mindspace: {mindspace.name}")
|
|
119
|
+
print(f"Type: {mindspace.type}")
|
|
120
|
+
print(f"Corpus: {mindspace.corpus_ids}")
|
|
121
|
+
"""
|
|
122
|
+
response_data = self._http.get(Routes.mindspace(mindspace_id))
|
|
123
|
+
return MindSpace.model_validate(response_data)
|
|
124
|
+
|
|
125
|
+
def list(self, user_id: Optional[str] = None) -> GetMindSpaceListResponse:
|
|
126
|
+
"""
|
|
127
|
+
List mindspaces, optionally filtered by user.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
user_id: Optional user ID to filter mindspaces
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
GetMindSpaceListResponse with list of mindspaces
|
|
134
|
+
|
|
135
|
+
Raises:
|
|
136
|
+
HTTPError: If the API request fails
|
|
137
|
+
|
|
138
|
+
Example:
|
|
139
|
+
# List all mindspaces for a user
|
|
140
|
+
response = client.v1.mindspace.list(user_id="user-456")
|
|
141
|
+
for ms in response.mindspaces:
|
|
142
|
+
print(f"- {ms.name} ({ms.type})")
|
|
143
|
+
"""
|
|
144
|
+
params = {}
|
|
145
|
+
if user_id:
|
|
146
|
+
params["user_id"] = user_id
|
|
147
|
+
|
|
148
|
+
response_data = self._http.get(Routes.MINDSPACES, params=params)
|
|
149
|
+
return GetMindSpaceListResponse.model_validate(response_data)
|
|
150
|
+
|
|
151
|
+
def update(
|
|
152
|
+
self,
|
|
153
|
+
mindspace_id: str,
|
|
154
|
+
name: str,
|
|
155
|
+
description: Optional[str] = None,
|
|
156
|
+
project_id: Optional[str] = None,
|
|
157
|
+
corpus_ids: Optional[list[str]] = None,
|
|
158
|
+
user_ids: Optional[list[str]] = None,
|
|
159
|
+
) -> MindSpace:
|
|
160
|
+
"""
|
|
161
|
+
Update an existing mindspace.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
mindspace_id: Mindspace ID to update
|
|
165
|
+
name: Updated mindspace name (max 100 characters)
|
|
166
|
+
description: Updated description (max 256 characters)
|
|
167
|
+
project_id: Updated associated project ID
|
|
168
|
+
corpus_ids: Updated list of corpus IDs
|
|
169
|
+
user_ids: Updated list of user IDs
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
MindSpace
|
|
173
|
+
|
|
174
|
+
Raises:
|
|
175
|
+
HTTPError: If the API request fails or mindspace not found
|
|
176
|
+
ValidationError: If parameters are invalid
|
|
177
|
+
|
|
178
|
+
Example:
|
|
179
|
+
# Update mindspace to add more corpus
|
|
180
|
+
mindspace = client.v1.mindspace.update(
|
|
181
|
+
mindspace_id="mind-123",
|
|
182
|
+
name="Engineering Team",
|
|
183
|
+
corpus_ids=["corp-1", "corp-2", "corp-3"]
|
|
184
|
+
)
|
|
185
|
+
print(f"Updated: {mindspace.corpus_ids}")
|
|
186
|
+
"""
|
|
187
|
+
# Build and validate request
|
|
188
|
+
request = UpdateMindSpaceRequest(
|
|
189
|
+
name=name,
|
|
190
|
+
description=description,
|
|
191
|
+
project_id=project_id,
|
|
192
|
+
corpus_ids=corpus_ids or [],
|
|
193
|
+
user_ids=user_ids or [],
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
# Make API call
|
|
197
|
+
response = self._http.put(
|
|
198
|
+
Routes.mindspace(mindspace_id),
|
|
199
|
+
json=request.model_dump(exclude_none=True),
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
# Parse and validate response
|
|
203
|
+
return MindSpace.model_validate(response)
|
|
204
|
+
|
|
205
|
+
def delete(self, mindspace_id: str) -> None:
|
|
206
|
+
"""
|
|
207
|
+
Delete a mindspace.
|
|
208
|
+
|
|
209
|
+
Args:
|
|
210
|
+
mindspace_id: Mindspace ID to delete
|
|
211
|
+
|
|
212
|
+
Raises:
|
|
213
|
+
HTTPError: If the API request fails or mindspace not found
|
|
214
|
+
|
|
215
|
+
Example:
|
|
216
|
+
client.v1.mindspace.delete("mind-123")
|
|
217
|
+
print("Mindspace deleted successfully")
|
|
218
|
+
"""
|
|
219
|
+
self._http.delete(Routes.mindspace(mindspace_id))
|
|
220
|
+
|
|
221
|
+
def get_messages(
|
|
222
|
+
self,
|
|
223
|
+
mindspace_id: str,
|
|
224
|
+
after_id: Optional[str] = None,
|
|
225
|
+
before_id: Optional[str] = None,
|
|
226
|
+
limit: int = 50,
|
|
227
|
+
) -> MindspaceMessagesResponse:
|
|
228
|
+
"""
|
|
229
|
+
Fetch chat messages from a mindspace with keyset pagination.
|
|
230
|
+
|
|
231
|
+
Three modes based on parameters:
|
|
232
|
+
- Latest: Just mindspace_id + limit (most recent messages)
|
|
233
|
+
- Forward: mindspace_id + after_id + limit (messages after a point)
|
|
234
|
+
- Backward: mindspace_id + before_id + limit (messages before a point)
|
|
235
|
+
|
|
236
|
+
Args:
|
|
237
|
+
mindspace_id: Mindspace to fetch messages from
|
|
238
|
+
after_id: Get messages after this message ID (forward pagination)
|
|
239
|
+
before_id: Get messages before this message ID (backward pagination)
|
|
240
|
+
limit: Maximum number of messages to return (default: 50)
|
|
241
|
+
|
|
242
|
+
Returns:
|
|
243
|
+
MindspaceMessagesResponse with messages and pagination cursors
|
|
244
|
+
|
|
245
|
+
Raises:
|
|
246
|
+
ValueError: If both after_id and before_id are provided
|
|
247
|
+
HTTPError: If the API request fails
|
|
248
|
+
|
|
249
|
+
Example:
|
|
250
|
+
# Get latest 50 messages
|
|
251
|
+
messages = client.v1.mindspace.get_messages(
|
|
252
|
+
mindspace_id="mind-123"
|
|
253
|
+
)
|
|
254
|
+
for msg in messages.chat_histories:
|
|
255
|
+
print(f"{msg.sent_by_user_id}: {msg.content}")
|
|
256
|
+
|
|
257
|
+
# Forward pagination (newer messages)
|
|
258
|
+
if messages.has_more:
|
|
259
|
+
more = client.v1.mindspace.get_messages(
|
|
260
|
+
mindspace_id="mind-123",
|
|
261
|
+
after_id=messages.next_after_id,
|
|
262
|
+
limit=50
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
# Backward pagination (older messages)
|
|
266
|
+
if messages.has_older:
|
|
267
|
+
older = client.v1.mindspace.get_messages(
|
|
268
|
+
mindspace_id="mind-123",
|
|
269
|
+
before_id=messages.next_before_id,
|
|
270
|
+
limit=50
|
|
271
|
+
)
|
|
272
|
+
"""
|
|
273
|
+
# Validate mutually exclusive parameters
|
|
274
|
+
if after_id and before_id:
|
|
275
|
+
raise ValueError("Cannot specify both after_id and before_id")
|
|
276
|
+
|
|
277
|
+
# Build query parameters
|
|
278
|
+
params = {
|
|
279
|
+
"mindspace_id": mindspace_id,
|
|
280
|
+
"limit": limit,
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if after_id:
|
|
284
|
+
params["after_id"] = after_id
|
|
285
|
+
if before_id:
|
|
286
|
+
params["before_id"] = before_id
|
|
287
|
+
|
|
288
|
+
# Make request
|
|
289
|
+
response_data = self._http.get(Routes.MINDSPACE_MESSAGES, params=params)
|
|
290
|
+
|
|
291
|
+
# Parse and return
|
|
292
|
+
return MindspaceMessagesResponse.model_validate(response_data)
|
|
293
|
+
|
|
294
|
+
def add_users(
|
|
295
|
+
self,
|
|
296
|
+
mindspace_id: str,
|
|
297
|
+
user_ids: list[str],
|
|
298
|
+
) -> MindSpace:
|
|
299
|
+
"""
|
|
300
|
+
Add users to an existing mindspace.
|
|
301
|
+
|
|
302
|
+
Args:
|
|
303
|
+
mindspace_id: Mindspace ID to add users to
|
|
304
|
+
user_ids: List of user IDs to add to the mindspace
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
MindSpace with updated user list
|
|
308
|
+
|
|
309
|
+
Raises:
|
|
310
|
+
HTTPError: If the API request fails or mindspace not found
|
|
311
|
+
ValidationError: If parameters are invalid
|
|
312
|
+
|
|
313
|
+
Example:
|
|
314
|
+
# Add users to a group mindspace
|
|
315
|
+
mindspace = client.v1.mindspace.add_users(
|
|
316
|
+
mindspace_id="mind-123",
|
|
317
|
+
user_ids=["user-3", "user-4"]
|
|
318
|
+
)
|
|
319
|
+
print(f"Updated users: {mindspace.user_ids}")
|
|
320
|
+
"""
|
|
321
|
+
# Build and validate request
|
|
322
|
+
request = AddMindSpaceUsersRequest(user_ids=user_ids)
|
|
323
|
+
|
|
324
|
+
# Make API call
|
|
325
|
+
response = self._http.post(
|
|
326
|
+
Routes.mindspace_users(mindspace_id),
|
|
327
|
+
json=request.model_dump(exclude_none=True),
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
# Parse and validate response
|
|
331
|
+
return MindSpace.model_validate(response)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from typing import Optional, List
|
|
2
|
+
|
|
3
|
+
from magick_mind.resources.base import BaseResource
|
|
4
|
+
from magick_mind.models.v1.model import ModelsListResponse, Model
|
|
5
|
+
from magick_mind.routes import Routes
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ModelsResourceV1(BaseResource):
|
|
9
|
+
"""Resource to interact with the models API."""
|
|
10
|
+
|
|
11
|
+
def list(self) -> List[Model]:
|
|
12
|
+
"""
|
|
13
|
+
List all available models.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
List[Model]: A list of available models.
|
|
17
|
+
"""
|
|
18
|
+
response = ModelsListResponse(**self._http.get(Routes.MODELS))
|
|
19
|
+
return response.data
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Project resource for Magick Mind SDK v1 API.
|
|
3
|
+
|
|
4
|
+
Provides methods for CRUD operations on projects in the agentic SaaS backend.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Optional
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
from magick_mind.models.v1.project import (
|
|
13
|
+
CreateProjectRequest,
|
|
14
|
+
GetProjectListResponse,
|
|
15
|
+
Project,
|
|
16
|
+
UpdateProjectRequest,
|
|
17
|
+
)
|
|
18
|
+
from magick_mind.resources.base import BaseResource
|
|
19
|
+
from magick_mind.routes import Routes
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ProjectResourceV1(BaseResource):
|
|
23
|
+
"""
|
|
24
|
+
Project resource for managing agentic SaaS projects.
|
|
25
|
+
|
|
26
|
+
Projects organize corpus and other resources for multi-tenant backends.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def create(
|
|
30
|
+
self,
|
|
31
|
+
name: str,
|
|
32
|
+
description: str = "",
|
|
33
|
+
corpus_ids: Optional[list[str]] = None,
|
|
34
|
+
) -> Project:
|
|
35
|
+
"""
|
|
36
|
+
Create a new project.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
name: Project name (required)
|
|
40
|
+
description: Project description (optional, max 256 chars)
|
|
41
|
+
corpus_ids: List of corpus IDs to associate with project
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
Created Project object
|
|
45
|
+
|
|
46
|
+
Example:
|
|
47
|
+
project = client.v1.project.create(
|
|
48
|
+
name="My Agentic App",
|
|
49
|
+
description="An AI-powered assistant",
|
|
50
|
+
corpus_ids=["corpus-123"]
|
|
51
|
+
)
|
|
52
|
+
print(f"Created project: {project.id}")
|
|
53
|
+
"""
|
|
54
|
+
request = CreateProjectRequest(
|
|
55
|
+
name=name,
|
|
56
|
+
description=description,
|
|
57
|
+
corpus_ids=corpus_ids or [],
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
response = self._http.post(Routes.PROJECTS, json=request.model_dump())
|
|
61
|
+
return Project.model_validate(response)
|
|
62
|
+
|
|
63
|
+
def get(self, project_id: str) -> Project:
|
|
64
|
+
"""
|
|
65
|
+
Get a project by ID.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
project_id: The project ID to retrieve
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
Project object
|
|
72
|
+
|
|
73
|
+
Example:
|
|
74
|
+
project = client.v1.project.get(project_id="proj-123")
|
|
75
|
+
print(f"Project name: {project.name}")
|
|
76
|
+
"""
|
|
77
|
+
response = self._http.get(Routes.project(project_id))
|
|
78
|
+
return Project.model_validate(response)
|
|
79
|
+
|
|
80
|
+
def list(self, created_by_user_id: Optional[str] = None) -> list[Project]:
|
|
81
|
+
"""
|
|
82
|
+
List projects, optionally filtered by creator user ID.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
created_by_user_id: Optional user ID to filter projects created by this user
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
List of Project objects
|
|
89
|
+
|
|
90
|
+
Example:
|
|
91
|
+
# List all accessible projects
|
|
92
|
+
projects = client.v1.project.list()
|
|
93
|
+
|
|
94
|
+
# List projects created by specific user
|
|
95
|
+
user_projects = client.v1.project.list(created_by_user_id="user-123")
|
|
96
|
+
for project in user_projects:
|
|
97
|
+
print(f"- {project.name}")
|
|
98
|
+
"""
|
|
99
|
+
params = {}
|
|
100
|
+
if created_by_user_id:
|
|
101
|
+
params["user_id"] = created_by_user_id
|
|
102
|
+
|
|
103
|
+
response = self._http.get(Routes.PROJECTS, params=params)
|
|
104
|
+
list_response = GetProjectListResponse.model_validate(response)
|
|
105
|
+
return [Project.model_validate(p) for p in list_response.data]
|
|
106
|
+
|
|
107
|
+
def update(
|
|
108
|
+
self,
|
|
109
|
+
project_id: str,
|
|
110
|
+
name: str,
|
|
111
|
+
description: str = "",
|
|
112
|
+
corpus_ids: Optional[list[str]] = None,
|
|
113
|
+
) -> Project:
|
|
114
|
+
"""
|
|
115
|
+
Update an existing project.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
project_id: The project ID to update
|
|
119
|
+
name: New project name (required)
|
|
120
|
+
description: New project description (optional, max 256 chars)
|
|
121
|
+
corpus_ids: New list of corpus IDs to associate with project
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
Updated Project object
|
|
125
|
+
|
|
126
|
+
Example:
|
|
127
|
+
updated = client.v1.project.update(
|
|
128
|
+
project_id="proj-123",
|
|
129
|
+
name="Updated Name",
|
|
130
|
+
description="Updated description",
|
|
131
|
+
corpus_ids=["corpus-123", "corpus-456"]
|
|
132
|
+
)
|
|
133
|
+
print(f"Updated project: {updated.name}")
|
|
134
|
+
"""
|
|
135
|
+
request = UpdateProjectRequest(
|
|
136
|
+
name=name,
|
|
137
|
+
description=description,
|
|
138
|
+
corpus_ids=corpus_ids or [],
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
response = self._http.put(Routes.project(project_id), json=request.model_dump())
|
|
142
|
+
return Project(**response)
|
|
143
|
+
|
|
144
|
+
def delete(self, project_id: str) -> None:
|
|
145
|
+
"""
|
|
146
|
+
Delete a project.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
project_id: The project ID to delete
|
|
150
|
+
|
|
151
|
+
Example:
|
|
152
|
+
client.v1.project.delete(project_id="proj-123")
|
|
153
|
+
print("Project deleted successfully")
|
|
154
|
+
"""
|
|
155
|
+
self._http.delete(Routes.project(project_id))
|
magick_mind/routes.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Centralized API route constants.
|
|
2
|
+
|
|
3
|
+
All API endpoint paths are defined here to ensure consistency
|
|
4
|
+
across the SDK and make updates easier when the API changes.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Routes:
|
|
9
|
+
"""API v1 route paths for Bifrost."""
|
|
10
|
+
|
|
11
|
+
# Auth endpoints
|
|
12
|
+
AUTH_LOGIN = "/v1/auth/login"
|
|
13
|
+
AUTH_REFRESH = "/v1/auth/refresh"
|
|
14
|
+
|
|
15
|
+
# Chat endpoints
|
|
16
|
+
CHAT = "/v1/chat/magickmind"
|
|
17
|
+
MODELS = "/v1/models"
|
|
18
|
+
|
|
19
|
+
# Mindspace endpoints
|
|
20
|
+
MINDSPACES = "/v1/mindspaces"
|
|
21
|
+
MINDSPACE_MESSAGES = "/v1/mindspaces/messages"
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def mindspace(mindspace_id: str) -> str:
|
|
25
|
+
"""Get path for a specific mindspace."""
|
|
26
|
+
return f"/v1/mindspaces/{mindspace_id}"
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
def mindspace_users(mindspace_id: str) -> str:
|
|
30
|
+
"""Get path to add users to a specific mindspace."""
|
|
31
|
+
return f"/v1/mindspaces/{mindspace_id}/users"
|
|
32
|
+
|
|
33
|
+
# Project endpoints
|
|
34
|
+
PROJECTS = "/v1/projects"
|
|
35
|
+
|
|
36
|
+
@staticmethod
|
|
37
|
+
def project(project_id: str) -> str:
|
|
38
|
+
"""Get path for a specific project."""
|
|
39
|
+
return f"/v1/projects/{project_id}"
|
|
40
|
+
|
|
41
|
+
# End User endpoints
|
|
42
|
+
END_USERS = "/v1/end-users"
|
|
43
|
+
|
|
44
|
+
@staticmethod
|
|
45
|
+
def end_user(end_user_id: str) -> str:
|
|
46
|
+
"""Get path for a specific end user."""
|
|
47
|
+
return f"/v1/end-users/{end_user_id}"
|
|
48
|
+
|
|
49
|
+
# Corpus endpoints
|
|
50
|
+
CORPUS = "/v1/corpus"
|
|
51
|
+
|
|
52
|
+
@staticmethod
|
|
53
|
+
def corpus(corpus_id: str) -> str:
|
|
54
|
+
"""Get path for a specific corpus."""
|
|
55
|
+
return f"/v1/corpus/{corpus_id}"
|
|
56
|
+
|
|
57
|
+
@staticmethod
|
|
58
|
+
def corpus_artifacts_finalize(corpus_id: str) -> str:
|
|
59
|
+
"""Get path for corpus artifact finalization."""
|
|
60
|
+
return f"/v1/corpus/{corpus_id}/artifacts/finalize"
|
|
61
|
+
|
|
62
|
+
# Artifact endpoints
|
|
63
|
+
ARTIFACTS = "/v1/artifacts"
|
|
64
|
+
ARTIFACTS_PRESIGN = "/v1/artifacts/presign"
|
|
65
|
+
ARTIFACTS_FINALIZE = "/v1/artifacts/finalize"
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def artifact(artifact_id: str) -> str:
|
|
69
|
+
"""Get path for a specific artifact."""
|
|
70
|
+
return f"/v1/artifacts/{artifact_id}"
|
|
71
|
+
|
|
72
|
+
# API Keys endpoints
|
|
73
|
+
KEYS = "/v1/keys"
|
|
74
|
+
|
|
75
|
+
# History endpoints (alias for mindspace messages)
|
|
76
|
+
HISTORY_MESSAGES = "/v1/mindspaces/messages"
|