agentrun-mem0ai 0.0.11__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.
- agentrun_mem0/__init__.py +6 -0
- agentrun_mem0/client/__init__.py +0 -0
- agentrun_mem0/client/main.py +1747 -0
- agentrun_mem0/client/project.py +931 -0
- agentrun_mem0/client/utils.py +115 -0
- agentrun_mem0/configs/__init__.py +0 -0
- agentrun_mem0/configs/base.py +90 -0
- agentrun_mem0/configs/embeddings/__init__.py +0 -0
- agentrun_mem0/configs/embeddings/base.py +110 -0
- agentrun_mem0/configs/enums.py +7 -0
- agentrun_mem0/configs/llms/__init__.py +0 -0
- agentrun_mem0/configs/llms/anthropic.py +56 -0
- agentrun_mem0/configs/llms/aws_bedrock.py +192 -0
- agentrun_mem0/configs/llms/azure.py +57 -0
- agentrun_mem0/configs/llms/base.py +62 -0
- agentrun_mem0/configs/llms/deepseek.py +56 -0
- agentrun_mem0/configs/llms/lmstudio.py +59 -0
- agentrun_mem0/configs/llms/ollama.py +56 -0
- agentrun_mem0/configs/llms/openai.py +79 -0
- agentrun_mem0/configs/llms/vllm.py +56 -0
- agentrun_mem0/configs/prompts.py +459 -0
- agentrun_mem0/configs/rerankers/__init__.py +0 -0
- agentrun_mem0/configs/rerankers/base.py +17 -0
- agentrun_mem0/configs/rerankers/cohere.py +15 -0
- agentrun_mem0/configs/rerankers/config.py +12 -0
- agentrun_mem0/configs/rerankers/huggingface.py +17 -0
- agentrun_mem0/configs/rerankers/llm.py +48 -0
- agentrun_mem0/configs/rerankers/sentence_transformer.py +16 -0
- agentrun_mem0/configs/rerankers/zero_entropy.py +28 -0
- agentrun_mem0/configs/vector_stores/__init__.py +0 -0
- agentrun_mem0/configs/vector_stores/alibabacloud_mysql.py +64 -0
- agentrun_mem0/configs/vector_stores/aliyun_tablestore.py +32 -0
- agentrun_mem0/configs/vector_stores/azure_ai_search.py +57 -0
- agentrun_mem0/configs/vector_stores/azure_mysql.py +84 -0
- agentrun_mem0/configs/vector_stores/baidu.py +27 -0
- agentrun_mem0/configs/vector_stores/chroma.py +58 -0
- agentrun_mem0/configs/vector_stores/databricks.py +61 -0
- agentrun_mem0/configs/vector_stores/elasticsearch.py +65 -0
- agentrun_mem0/configs/vector_stores/faiss.py +37 -0
- agentrun_mem0/configs/vector_stores/langchain.py +30 -0
- agentrun_mem0/configs/vector_stores/milvus.py +42 -0
- agentrun_mem0/configs/vector_stores/mongodb.py +25 -0
- agentrun_mem0/configs/vector_stores/neptune.py +27 -0
- agentrun_mem0/configs/vector_stores/opensearch.py +41 -0
- agentrun_mem0/configs/vector_stores/pgvector.py +52 -0
- agentrun_mem0/configs/vector_stores/pinecone.py +55 -0
- agentrun_mem0/configs/vector_stores/qdrant.py +47 -0
- agentrun_mem0/configs/vector_stores/redis.py +24 -0
- agentrun_mem0/configs/vector_stores/s3_vectors.py +28 -0
- agentrun_mem0/configs/vector_stores/supabase.py +44 -0
- agentrun_mem0/configs/vector_stores/upstash_vector.py +34 -0
- agentrun_mem0/configs/vector_stores/valkey.py +15 -0
- agentrun_mem0/configs/vector_stores/vertex_ai_vector_search.py +28 -0
- agentrun_mem0/configs/vector_stores/weaviate.py +41 -0
- agentrun_mem0/embeddings/__init__.py +0 -0
- agentrun_mem0/embeddings/aws_bedrock.py +100 -0
- agentrun_mem0/embeddings/azure_openai.py +55 -0
- agentrun_mem0/embeddings/base.py +31 -0
- agentrun_mem0/embeddings/configs.py +30 -0
- agentrun_mem0/embeddings/gemini.py +39 -0
- agentrun_mem0/embeddings/huggingface.py +44 -0
- agentrun_mem0/embeddings/langchain.py +35 -0
- agentrun_mem0/embeddings/lmstudio.py +29 -0
- agentrun_mem0/embeddings/mock.py +11 -0
- agentrun_mem0/embeddings/ollama.py +53 -0
- agentrun_mem0/embeddings/openai.py +49 -0
- agentrun_mem0/embeddings/together.py +31 -0
- agentrun_mem0/embeddings/vertexai.py +64 -0
- agentrun_mem0/exceptions.py +503 -0
- agentrun_mem0/graphs/__init__.py +0 -0
- agentrun_mem0/graphs/configs.py +105 -0
- agentrun_mem0/graphs/neptune/__init__.py +0 -0
- agentrun_mem0/graphs/neptune/base.py +497 -0
- agentrun_mem0/graphs/neptune/neptunedb.py +511 -0
- agentrun_mem0/graphs/neptune/neptunegraph.py +474 -0
- agentrun_mem0/graphs/tools.py +371 -0
- agentrun_mem0/graphs/utils.py +97 -0
- agentrun_mem0/llms/__init__.py +0 -0
- agentrun_mem0/llms/anthropic.py +87 -0
- agentrun_mem0/llms/aws_bedrock.py +665 -0
- agentrun_mem0/llms/azure_openai.py +141 -0
- agentrun_mem0/llms/azure_openai_structured.py +91 -0
- agentrun_mem0/llms/base.py +131 -0
- agentrun_mem0/llms/configs.py +34 -0
- agentrun_mem0/llms/deepseek.py +107 -0
- agentrun_mem0/llms/gemini.py +201 -0
- agentrun_mem0/llms/groq.py +88 -0
- agentrun_mem0/llms/langchain.py +94 -0
- agentrun_mem0/llms/litellm.py +87 -0
- agentrun_mem0/llms/lmstudio.py +114 -0
- agentrun_mem0/llms/ollama.py +117 -0
- agentrun_mem0/llms/openai.py +147 -0
- agentrun_mem0/llms/openai_structured.py +52 -0
- agentrun_mem0/llms/sarvam.py +89 -0
- agentrun_mem0/llms/together.py +88 -0
- agentrun_mem0/llms/vllm.py +107 -0
- agentrun_mem0/llms/xai.py +52 -0
- agentrun_mem0/memory/__init__.py +0 -0
- agentrun_mem0/memory/base.py +63 -0
- agentrun_mem0/memory/graph_memory.py +698 -0
- agentrun_mem0/memory/kuzu_memory.py +713 -0
- agentrun_mem0/memory/main.py +2229 -0
- agentrun_mem0/memory/memgraph_memory.py +689 -0
- agentrun_mem0/memory/setup.py +56 -0
- agentrun_mem0/memory/storage.py +218 -0
- agentrun_mem0/memory/telemetry.py +90 -0
- agentrun_mem0/memory/utils.py +208 -0
- agentrun_mem0/proxy/__init__.py +0 -0
- agentrun_mem0/proxy/main.py +189 -0
- agentrun_mem0/reranker/__init__.py +9 -0
- agentrun_mem0/reranker/base.py +20 -0
- agentrun_mem0/reranker/cohere_reranker.py +85 -0
- agentrun_mem0/reranker/huggingface_reranker.py +147 -0
- agentrun_mem0/reranker/llm_reranker.py +142 -0
- agentrun_mem0/reranker/sentence_transformer_reranker.py +107 -0
- agentrun_mem0/reranker/zero_entropy_reranker.py +96 -0
- agentrun_mem0/utils/factory.py +283 -0
- agentrun_mem0/utils/gcp_auth.py +167 -0
- agentrun_mem0/vector_stores/__init__.py +0 -0
- agentrun_mem0/vector_stores/alibabacloud_mysql.py +547 -0
- agentrun_mem0/vector_stores/aliyun_tablestore.py +252 -0
- agentrun_mem0/vector_stores/azure_ai_search.py +396 -0
- agentrun_mem0/vector_stores/azure_mysql.py +463 -0
- agentrun_mem0/vector_stores/baidu.py +368 -0
- agentrun_mem0/vector_stores/base.py +58 -0
- agentrun_mem0/vector_stores/chroma.py +332 -0
- agentrun_mem0/vector_stores/configs.py +67 -0
- agentrun_mem0/vector_stores/databricks.py +761 -0
- agentrun_mem0/vector_stores/elasticsearch.py +237 -0
- agentrun_mem0/vector_stores/faiss.py +479 -0
- agentrun_mem0/vector_stores/langchain.py +180 -0
- agentrun_mem0/vector_stores/milvus.py +250 -0
- agentrun_mem0/vector_stores/mongodb.py +310 -0
- agentrun_mem0/vector_stores/neptune_analytics.py +467 -0
- agentrun_mem0/vector_stores/opensearch.py +292 -0
- agentrun_mem0/vector_stores/pgvector.py +404 -0
- agentrun_mem0/vector_stores/pinecone.py +382 -0
- agentrun_mem0/vector_stores/qdrant.py +270 -0
- agentrun_mem0/vector_stores/redis.py +295 -0
- agentrun_mem0/vector_stores/s3_vectors.py +176 -0
- agentrun_mem0/vector_stores/supabase.py +237 -0
- agentrun_mem0/vector_stores/upstash_vector.py +293 -0
- agentrun_mem0/vector_stores/valkey.py +824 -0
- agentrun_mem0/vector_stores/vertex_ai_vector_search.py +635 -0
- agentrun_mem0/vector_stores/weaviate.py +343 -0
- agentrun_mem0ai-0.0.11.data/data/README.md +205 -0
- agentrun_mem0ai-0.0.11.dist-info/METADATA +277 -0
- agentrun_mem0ai-0.0.11.dist-info/RECORD +150 -0
- agentrun_mem0ai-0.0.11.dist-info/WHEEL +4 -0
- agentrun_mem0ai-0.0.11.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,931 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from abc import ABC, abstractmethod
|
|
3
|
+
from typing import Any, Dict, List, Optional
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
7
|
+
|
|
8
|
+
from agentrun_mem0.client.utils import api_error_handler
|
|
9
|
+
from agentrun_mem0.memory.telemetry import capture_client_event
|
|
10
|
+
# Exception classes are referenced in docstrings only
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ProjectConfig(BaseModel):
|
|
16
|
+
"""
|
|
17
|
+
Configuration for project management operations.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
org_id: Optional[str] = Field(default=None, description="Organization ID")
|
|
21
|
+
project_id: Optional[str] = Field(default=None, description="Project ID")
|
|
22
|
+
user_email: Optional[str] = Field(default=None, description="User email")
|
|
23
|
+
|
|
24
|
+
model_config = ConfigDict(validate_assignment=True, extra="forbid")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class BaseProject(ABC):
|
|
28
|
+
"""
|
|
29
|
+
Abstract base class for project management operations.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(
|
|
33
|
+
self,
|
|
34
|
+
client: Any,
|
|
35
|
+
config: Optional[ProjectConfig] = None,
|
|
36
|
+
org_id: Optional[str] = None,
|
|
37
|
+
project_id: Optional[str] = None,
|
|
38
|
+
user_email: Optional[str] = None,
|
|
39
|
+
):
|
|
40
|
+
"""
|
|
41
|
+
Initialize the project manager.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
client: HTTP client instance
|
|
45
|
+
config: Project manager configuration
|
|
46
|
+
org_id: Organization ID
|
|
47
|
+
project_id: Project ID
|
|
48
|
+
user_email: User email
|
|
49
|
+
"""
|
|
50
|
+
self._client = client
|
|
51
|
+
|
|
52
|
+
# Handle config initialization
|
|
53
|
+
if config is not None:
|
|
54
|
+
self.config = config
|
|
55
|
+
else:
|
|
56
|
+
# Create config from parameters
|
|
57
|
+
self.config = ProjectConfig(org_id=org_id, project_id=project_id, user_email=user_email)
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def org_id(self) -> Optional[str]:
|
|
61
|
+
"""Get the organization ID."""
|
|
62
|
+
return self.config.org_id
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def project_id(self) -> Optional[str]:
|
|
66
|
+
"""Get the project ID."""
|
|
67
|
+
return self.config.project_id
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def user_email(self) -> Optional[str]:
|
|
71
|
+
"""Get the user email."""
|
|
72
|
+
return self.config.user_email
|
|
73
|
+
|
|
74
|
+
def _validate_org_project(self) -> None:
|
|
75
|
+
"""
|
|
76
|
+
Validate that both org_id and project_id are set.
|
|
77
|
+
|
|
78
|
+
Raises:
|
|
79
|
+
ValueError: If org_id or project_id are not set.
|
|
80
|
+
"""
|
|
81
|
+
if not (self.config.org_id and self.config.project_id):
|
|
82
|
+
raise ValueError("org_id and project_id must be set to access project operations")
|
|
83
|
+
|
|
84
|
+
def _prepare_params(self, kwargs: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
|
|
85
|
+
"""
|
|
86
|
+
Prepare query parameters for API requests.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
kwargs: Additional keyword arguments.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
Dictionary containing prepared parameters.
|
|
93
|
+
|
|
94
|
+
Raises:
|
|
95
|
+
ValueError: If org_id or project_id validation fails.
|
|
96
|
+
"""
|
|
97
|
+
if kwargs is None:
|
|
98
|
+
kwargs = {}
|
|
99
|
+
|
|
100
|
+
# Add org_id and project_id if available
|
|
101
|
+
if self.config.org_id and self.config.project_id:
|
|
102
|
+
kwargs["org_id"] = self.config.org_id
|
|
103
|
+
kwargs["project_id"] = self.config.project_id
|
|
104
|
+
elif self.config.org_id or self.config.project_id:
|
|
105
|
+
raise ValueError("Please provide both org_id and project_id")
|
|
106
|
+
|
|
107
|
+
return {k: v for k, v in kwargs.items() if v is not None}
|
|
108
|
+
|
|
109
|
+
def _prepare_org_params(self, kwargs: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
|
|
110
|
+
"""
|
|
111
|
+
Prepare query parameters for organization-level API requests.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
kwargs: Additional keyword arguments.
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
Dictionary containing prepared parameters.
|
|
118
|
+
|
|
119
|
+
Raises:
|
|
120
|
+
ValueError: If org_id is not provided.
|
|
121
|
+
"""
|
|
122
|
+
if kwargs is None:
|
|
123
|
+
kwargs = {}
|
|
124
|
+
|
|
125
|
+
# Add org_id if available
|
|
126
|
+
if self.config.org_id:
|
|
127
|
+
kwargs["org_id"] = self.config.org_id
|
|
128
|
+
else:
|
|
129
|
+
raise ValueError("org_id must be set for organization-level operations")
|
|
130
|
+
|
|
131
|
+
return {k: v for k, v in kwargs.items() if v is not None}
|
|
132
|
+
|
|
133
|
+
@abstractmethod
|
|
134
|
+
def get(self, fields: Optional[List[str]] = None) -> Dict[str, Any]:
|
|
135
|
+
"""
|
|
136
|
+
Get project details.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
fields: List of fields to retrieve
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
Dictionary containing the requested project fields.
|
|
143
|
+
|
|
144
|
+
Raises:
|
|
145
|
+
ValidationError: If the input data is invalid.
|
|
146
|
+
AuthenticationError: If authentication fails.
|
|
147
|
+
RateLimitError: If rate limits are exceeded.
|
|
148
|
+
NetworkError: If network connectivity issues occur.
|
|
149
|
+
ValueError: If org_id or project_id are not set.
|
|
150
|
+
"""
|
|
151
|
+
pass
|
|
152
|
+
|
|
153
|
+
@abstractmethod
|
|
154
|
+
def create(self, name: str, description: Optional[str] = None) -> Dict[str, Any]:
|
|
155
|
+
"""
|
|
156
|
+
Create a new project within the organization.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
name: Name of the project to be created
|
|
160
|
+
description: Optional description for the project
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
Dictionary containing the created project details.
|
|
164
|
+
|
|
165
|
+
Raises:
|
|
166
|
+
ValidationError: If the input data is invalid.
|
|
167
|
+
AuthenticationError: If authentication fails.
|
|
168
|
+
RateLimitError: If rate limits are exceeded.
|
|
169
|
+
NetworkError: If network connectivity issues occur.
|
|
170
|
+
ValueError: If org_id is not set.
|
|
171
|
+
"""
|
|
172
|
+
pass
|
|
173
|
+
|
|
174
|
+
@abstractmethod
|
|
175
|
+
def update(
|
|
176
|
+
self,
|
|
177
|
+
custom_instructions: Optional[str] = None,
|
|
178
|
+
custom_categories: Optional[List[str]] = None,
|
|
179
|
+
retrieval_criteria: Optional[List[Dict[str, Any]]] = None,
|
|
180
|
+
enable_graph: Optional[bool] = None,
|
|
181
|
+
) -> Dict[str, Any]:
|
|
182
|
+
"""
|
|
183
|
+
Update project settings.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
custom_instructions: New instructions for the project
|
|
187
|
+
custom_categories: New categories for the project
|
|
188
|
+
retrieval_criteria: New retrieval criteria for the project
|
|
189
|
+
enable_graph: Enable or disable the graph for the project
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
Dictionary containing the API response.
|
|
193
|
+
|
|
194
|
+
Raises:
|
|
195
|
+
ValidationError: If the input data is invalid.
|
|
196
|
+
AuthenticationError: If authentication fails.
|
|
197
|
+
RateLimitError: If rate limits are exceeded.
|
|
198
|
+
NetworkError: If network connectivity issues occur.
|
|
199
|
+
ValueError: If org_id or project_id are not set.
|
|
200
|
+
"""
|
|
201
|
+
pass
|
|
202
|
+
|
|
203
|
+
@abstractmethod
|
|
204
|
+
def delete(self) -> Dict[str, Any]:
|
|
205
|
+
"""
|
|
206
|
+
Delete the current project and its related data.
|
|
207
|
+
|
|
208
|
+
Returns:
|
|
209
|
+
Dictionary containing the API response.
|
|
210
|
+
|
|
211
|
+
Raises:
|
|
212
|
+
ValidationError: If the input data is invalid.
|
|
213
|
+
AuthenticationError: If authentication fails.
|
|
214
|
+
RateLimitError: If rate limits are exceeded.
|
|
215
|
+
NetworkError: If network connectivity issues occur.
|
|
216
|
+
ValueError: If org_id or project_id are not set.
|
|
217
|
+
"""
|
|
218
|
+
pass
|
|
219
|
+
|
|
220
|
+
@abstractmethod
|
|
221
|
+
def get_members(self) -> Dict[str, Any]:
|
|
222
|
+
"""
|
|
223
|
+
Get all members of the current project.
|
|
224
|
+
|
|
225
|
+
Returns:
|
|
226
|
+
Dictionary containing the list of project members.
|
|
227
|
+
|
|
228
|
+
Raises:
|
|
229
|
+
ValidationError: If the input data is invalid.
|
|
230
|
+
AuthenticationError: If authentication fails.
|
|
231
|
+
RateLimitError: If rate limits are exceeded.
|
|
232
|
+
NetworkError: If network connectivity issues occur.
|
|
233
|
+
ValueError: If org_id or project_id are not set.
|
|
234
|
+
"""
|
|
235
|
+
pass
|
|
236
|
+
|
|
237
|
+
@abstractmethod
|
|
238
|
+
def add_member(self, email: str, role: str = "READER") -> Dict[str, Any]:
|
|
239
|
+
"""
|
|
240
|
+
Add a new member to the current project.
|
|
241
|
+
|
|
242
|
+
Args:
|
|
243
|
+
email: Email address of the user to add
|
|
244
|
+
role: Role to assign ("READER" or "OWNER")
|
|
245
|
+
|
|
246
|
+
Returns:
|
|
247
|
+
Dictionary containing the API response.
|
|
248
|
+
|
|
249
|
+
Raises:
|
|
250
|
+
ValidationError: If the input data is invalid.
|
|
251
|
+
AuthenticationError: If authentication fails.
|
|
252
|
+
RateLimitError: If rate limits are exceeded.
|
|
253
|
+
NetworkError: If network connectivity issues occur.
|
|
254
|
+
ValueError: If org_id or project_id are not set.
|
|
255
|
+
"""
|
|
256
|
+
pass
|
|
257
|
+
|
|
258
|
+
@abstractmethod
|
|
259
|
+
def update_member(self, email: str, role: str) -> Dict[str, Any]:
|
|
260
|
+
"""
|
|
261
|
+
Update a member's role in the current project.
|
|
262
|
+
|
|
263
|
+
Args:
|
|
264
|
+
email: Email address of the user to update
|
|
265
|
+
role: New role to assign ("READER" or "OWNER")
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
Dictionary containing the API response.
|
|
269
|
+
|
|
270
|
+
Raises:
|
|
271
|
+
ValidationError: If the input data is invalid.
|
|
272
|
+
AuthenticationError: If authentication fails.
|
|
273
|
+
RateLimitError: If rate limits are exceeded.
|
|
274
|
+
NetworkError: If network connectivity issues occur.
|
|
275
|
+
ValueError: If org_id or project_id are not set.
|
|
276
|
+
"""
|
|
277
|
+
pass
|
|
278
|
+
|
|
279
|
+
@abstractmethod
|
|
280
|
+
def remove_member(self, email: str) -> Dict[str, Any]:
|
|
281
|
+
"""
|
|
282
|
+
Remove a member from the current project.
|
|
283
|
+
|
|
284
|
+
Args:
|
|
285
|
+
email: Email address of the user to remove
|
|
286
|
+
|
|
287
|
+
Returns:
|
|
288
|
+
Dictionary containing the API response.
|
|
289
|
+
|
|
290
|
+
Raises:
|
|
291
|
+
ValidationError: If the input data is invalid.
|
|
292
|
+
AuthenticationError: If authentication fails.
|
|
293
|
+
RateLimitError: If rate limits are exceeded.
|
|
294
|
+
NetworkError: If network connectivity issues occur.
|
|
295
|
+
ValueError: If org_id or project_id are not set.
|
|
296
|
+
"""
|
|
297
|
+
pass
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
class Project(BaseProject):
|
|
301
|
+
"""
|
|
302
|
+
Synchronous project management operations.
|
|
303
|
+
"""
|
|
304
|
+
|
|
305
|
+
def __init__(
|
|
306
|
+
self,
|
|
307
|
+
client: httpx.Client,
|
|
308
|
+
config: Optional[ProjectConfig] = None,
|
|
309
|
+
org_id: Optional[str] = None,
|
|
310
|
+
project_id: Optional[str] = None,
|
|
311
|
+
user_email: Optional[str] = None,
|
|
312
|
+
):
|
|
313
|
+
"""
|
|
314
|
+
Initialize the synchronous project manager.
|
|
315
|
+
|
|
316
|
+
Args:
|
|
317
|
+
client: HTTP client instance
|
|
318
|
+
config: Project manager configuration
|
|
319
|
+
org_id: Organization ID
|
|
320
|
+
project_id: Project ID
|
|
321
|
+
user_email: User email
|
|
322
|
+
"""
|
|
323
|
+
super().__init__(client, config, org_id, project_id, user_email)
|
|
324
|
+
self._validate_org_project()
|
|
325
|
+
|
|
326
|
+
@api_error_handler
|
|
327
|
+
def get(self, fields: Optional[List[str]] = None) -> Dict[str, Any]:
|
|
328
|
+
"""
|
|
329
|
+
Get project details.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
fields: List of fields to retrieve
|
|
333
|
+
|
|
334
|
+
Returns:
|
|
335
|
+
Dictionary containing the requested project fields.
|
|
336
|
+
|
|
337
|
+
Raises:
|
|
338
|
+
ValidationError: If the input data is invalid.
|
|
339
|
+
AuthenticationError: If authentication fails.
|
|
340
|
+
RateLimitError: If rate limits are exceeded.
|
|
341
|
+
NetworkError: If network connectivity issues occur.
|
|
342
|
+
ValueError: If org_id or project_id are not set.
|
|
343
|
+
"""
|
|
344
|
+
params = self._prepare_params({"fields": fields})
|
|
345
|
+
response = self._client.get(
|
|
346
|
+
f"/api/v1/orgs/organizations/{self.config.org_id}/projects/{self.config.project_id}/",
|
|
347
|
+
params=params,
|
|
348
|
+
)
|
|
349
|
+
response.raise_for_status()
|
|
350
|
+
capture_client_event(
|
|
351
|
+
"client.project.get",
|
|
352
|
+
self,
|
|
353
|
+
{"fields": fields, "sync_type": "sync"},
|
|
354
|
+
)
|
|
355
|
+
return response.json()
|
|
356
|
+
|
|
357
|
+
@api_error_handler
|
|
358
|
+
def create(self, name: str, description: Optional[str] = None) -> Dict[str, Any]:
|
|
359
|
+
"""
|
|
360
|
+
Create a new project within the organization.
|
|
361
|
+
|
|
362
|
+
Args:
|
|
363
|
+
name: Name of the project to be created
|
|
364
|
+
description: Optional description for the project
|
|
365
|
+
|
|
366
|
+
Returns:
|
|
367
|
+
Dictionary containing the created project details.
|
|
368
|
+
|
|
369
|
+
Raises:
|
|
370
|
+
ValidationError: If the input data is invalid.
|
|
371
|
+
AuthenticationError: If authentication fails.
|
|
372
|
+
RateLimitError: If rate limits are exceeded.
|
|
373
|
+
NetworkError: If network connectivity issues occur.
|
|
374
|
+
ValueError: If org_id is not set.
|
|
375
|
+
"""
|
|
376
|
+
if not self.config.org_id:
|
|
377
|
+
raise ValueError("org_id must be set to create a project")
|
|
378
|
+
|
|
379
|
+
payload = {"name": name}
|
|
380
|
+
if description is not None:
|
|
381
|
+
payload["description"] = description
|
|
382
|
+
|
|
383
|
+
response = self._client.post(
|
|
384
|
+
f"/api/v1/orgs/organizations/{self.config.org_id}/projects/",
|
|
385
|
+
json=payload,
|
|
386
|
+
)
|
|
387
|
+
response.raise_for_status()
|
|
388
|
+
capture_client_event(
|
|
389
|
+
"client.project.create",
|
|
390
|
+
self,
|
|
391
|
+
{"name": name, "description": description, "sync_type": "sync"},
|
|
392
|
+
)
|
|
393
|
+
return response.json()
|
|
394
|
+
|
|
395
|
+
@api_error_handler
|
|
396
|
+
def update(
|
|
397
|
+
self,
|
|
398
|
+
custom_instructions: Optional[str] = None,
|
|
399
|
+
custom_categories: Optional[List[str]] = None,
|
|
400
|
+
retrieval_criteria: Optional[List[Dict[str, Any]]] = None,
|
|
401
|
+
enable_graph: Optional[bool] = None,
|
|
402
|
+
) -> Dict[str, Any]:
|
|
403
|
+
"""
|
|
404
|
+
Update project settings.
|
|
405
|
+
|
|
406
|
+
Args:
|
|
407
|
+
custom_instructions: New instructions for the project
|
|
408
|
+
custom_categories: New categories for the project
|
|
409
|
+
retrieval_criteria: New retrieval criteria for the project
|
|
410
|
+
enable_graph: Enable or disable the graph for the project
|
|
411
|
+
|
|
412
|
+
Returns:
|
|
413
|
+
Dictionary containing the API response.
|
|
414
|
+
|
|
415
|
+
Raises:
|
|
416
|
+
ValidationError: If the input data is invalid.
|
|
417
|
+
AuthenticationError: If authentication fails.
|
|
418
|
+
RateLimitError: If rate limits are exceeded.
|
|
419
|
+
NetworkError: If network connectivity issues occur.
|
|
420
|
+
ValueError: If org_id or project_id are not set.
|
|
421
|
+
"""
|
|
422
|
+
if (
|
|
423
|
+
custom_instructions is None
|
|
424
|
+
and custom_categories is None
|
|
425
|
+
and retrieval_criteria is None
|
|
426
|
+
and enable_graph is None
|
|
427
|
+
):
|
|
428
|
+
raise ValueError(
|
|
429
|
+
"At least one parameter must be provided for update: "
|
|
430
|
+
"custom_instructions, custom_categories, retrieval_criteria, "
|
|
431
|
+
"enable_graph"
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
payload = self._prepare_params(
|
|
435
|
+
{
|
|
436
|
+
"custom_instructions": custom_instructions,
|
|
437
|
+
"custom_categories": custom_categories,
|
|
438
|
+
"retrieval_criteria": retrieval_criteria,
|
|
439
|
+
"enable_graph": enable_graph,
|
|
440
|
+
}
|
|
441
|
+
)
|
|
442
|
+
response = self._client.patch(
|
|
443
|
+
f"/api/v1/orgs/organizations/{self.config.org_id}/projects/{self.config.project_id}/",
|
|
444
|
+
json=payload,
|
|
445
|
+
)
|
|
446
|
+
response.raise_for_status()
|
|
447
|
+
capture_client_event(
|
|
448
|
+
"client.project.update",
|
|
449
|
+
self,
|
|
450
|
+
{
|
|
451
|
+
"custom_instructions": custom_instructions,
|
|
452
|
+
"custom_categories": custom_categories,
|
|
453
|
+
"retrieval_criteria": retrieval_criteria,
|
|
454
|
+
"enable_graph": enable_graph,
|
|
455
|
+
"sync_type": "sync",
|
|
456
|
+
},
|
|
457
|
+
)
|
|
458
|
+
return response.json()
|
|
459
|
+
|
|
460
|
+
@api_error_handler
|
|
461
|
+
def delete(self) -> Dict[str, Any]:
|
|
462
|
+
"""
|
|
463
|
+
Delete the current project and its related data.
|
|
464
|
+
|
|
465
|
+
Returns:
|
|
466
|
+
Dictionary containing the API response.
|
|
467
|
+
|
|
468
|
+
Raises:
|
|
469
|
+
ValidationError: If the input data is invalid.
|
|
470
|
+
AuthenticationError: If authentication fails.
|
|
471
|
+
RateLimitError: If rate limits are exceeded.
|
|
472
|
+
NetworkError: If network connectivity issues occur.
|
|
473
|
+
ValueError: If org_id or project_id are not set.
|
|
474
|
+
"""
|
|
475
|
+
response = self._client.delete(
|
|
476
|
+
f"/api/v1/orgs/organizations/{self.config.org_id}/projects/{self.config.project_id}/",
|
|
477
|
+
)
|
|
478
|
+
response.raise_for_status()
|
|
479
|
+
capture_client_event(
|
|
480
|
+
"client.project.delete",
|
|
481
|
+
self,
|
|
482
|
+
{"sync_type": "sync"},
|
|
483
|
+
)
|
|
484
|
+
return response.json()
|
|
485
|
+
|
|
486
|
+
@api_error_handler
|
|
487
|
+
def get_members(self) -> Dict[str, Any]:
|
|
488
|
+
"""
|
|
489
|
+
Get all members of the current project.
|
|
490
|
+
|
|
491
|
+
Returns:
|
|
492
|
+
Dictionary containing the list of project members.
|
|
493
|
+
|
|
494
|
+
Raises:
|
|
495
|
+
ValidationError: If the input data is invalid.
|
|
496
|
+
AuthenticationError: If authentication fails.
|
|
497
|
+
RateLimitError: If rate limits are exceeded.
|
|
498
|
+
NetworkError: If network connectivity issues occur.
|
|
499
|
+
ValueError: If org_id or project_id are not set.
|
|
500
|
+
"""
|
|
501
|
+
response = self._client.get(
|
|
502
|
+
f"/api/v1/orgs/organizations/{self.config.org_id}/projects/{self.config.project_id}/members/",
|
|
503
|
+
)
|
|
504
|
+
response.raise_for_status()
|
|
505
|
+
capture_client_event(
|
|
506
|
+
"client.project.get_members",
|
|
507
|
+
self,
|
|
508
|
+
{"sync_type": "sync"},
|
|
509
|
+
)
|
|
510
|
+
return response.json()
|
|
511
|
+
|
|
512
|
+
@api_error_handler
|
|
513
|
+
def add_member(self, email: str, role: str = "READER") -> Dict[str, Any]:
|
|
514
|
+
"""
|
|
515
|
+
Add a new member to the current project.
|
|
516
|
+
|
|
517
|
+
Args:
|
|
518
|
+
email: Email address of the user to add
|
|
519
|
+
role: Role to assign ("READER" or "OWNER")
|
|
520
|
+
|
|
521
|
+
Returns:
|
|
522
|
+
Dictionary containing the API response.
|
|
523
|
+
|
|
524
|
+
Raises:
|
|
525
|
+
ValidationError: If the input data is invalid.
|
|
526
|
+
AuthenticationError: If authentication fails.
|
|
527
|
+
RateLimitError: If rate limits are exceeded.
|
|
528
|
+
NetworkError: If network connectivity issues occur.
|
|
529
|
+
ValueError: If org_id or project_id are not set.
|
|
530
|
+
"""
|
|
531
|
+
if role not in ["READER", "OWNER"]:
|
|
532
|
+
raise ValueError("Role must be either 'READER' or 'OWNER'")
|
|
533
|
+
|
|
534
|
+
payload = {"email": email, "role": role}
|
|
535
|
+
|
|
536
|
+
response = self._client.post(
|
|
537
|
+
f"/api/v1/orgs/organizations/{self.config.org_id}/projects/{self.config.project_id}/members/",
|
|
538
|
+
json=payload,
|
|
539
|
+
)
|
|
540
|
+
response.raise_for_status()
|
|
541
|
+
capture_client_event(
|
|
542
|
+
"client.project.add_member",
|
|
543
|
+
self,
|
|
544
|
+
{"email": email, "role": role, "sync_type": "sync"},
|
|
545
|
+
)
|
|
546
|
+
return response.json()
|
|
547
|
+
|
|
548
|
+
@api_error_handler
|
|
549
|
+
def update_member(self, email: str, role: str) -> Dict[str, Any]:
|
|
550
|
+
"""
|
|
551
|
+
Update a member's role in the current project.
|
|
552
|
+
|
|
553
|
+
Args:
|
|
554
|
+
email: Email address of the user to update
|
|
555
|
+
role: New role to assign ("READER" or "OWNER")
|
|
556
|
+
|
|
557
|
+
Returns:
|
|
558
|
+
Dictionary containing the API response.
|
|
559
|
+
|
|
560
|
+
Raises:
|
|
561
|
+
ValidationError: If the input data is invalid.
|
|
562
|
+
AuthenticationError: If authentication fails.
|
|
563
|
+
RateLimitError: If rate limits are exceeded.
|
|
564
|
+
NetworkError: If network connectivity issues occur.
|
|
565
|
+
ValueError: If org_id or project_id are not set.
|
|
566
|
+
"""
|
|
567
|
+
if role not in ["READER", "OWNER"]:
|
|
568
|
+
raise ValueError("Role must be either 'READER' or 'OWNER'")
|
|
569
|
+
|
|
570
|
+
payload = {"email": email, "role": role}
|
|
571
|
+
|
|
572
|
+
response = self._client.put(
|
|
573
|
+
f"/api/v1/orgs/organizations/{self.config.org_id}/projects/{self.config.project_id}/members/",
|
|
574
|
+
json=payload,
|
|
575
|
+
)
|
|
576
|
+
response.raise_for_status()
|
|
577
|
+
capture_client_event(
|
|
578
|
+
"client.project.update_member",
|
|
579
|
+
self,
|
|
580
|
+
{"email": email, "role": role, "sync_type": "sync"},
|
|
581
|
+
)
|
|
582
|
+
return response.json()
|
|
583
|
+
|
|
584
|
+
@api_error_handler
|
|
585
|
+
def remove_member(self, email: str) -> Dict[str, Any]:
|
|
586
|
+
"""
|
|
587
|
+
Remove a member from the current project.
|
|
588
|
+
|
|
589
|
+
Args:
|
|
590
|
+
email: Email address of the user to remove
|
|
591
|
+
|
|
592
|
+
Returns:
|
|
593
|
+
Dictionary containing the API response.
|
|
594
|
+
|
|
595
|
+
Raises:
|
|
596
|
+
ValidationError: If the input data is invalid.
|
|
597
|
+
AuthenticationError: If authentication fails.
|
|
598
|
+
RateLimitError: If rate limits are exceeded.
|
|
599
|
+
NetworkError: If network connectivity issues occur.
|
|
600
|
+
ValueError: If org_id or project_id are not set.
|
|
601
|
+
"""
|
|
602
|
+
params = {"email": email}
|
|
603
|
+
|
|
604
|
+
response = self._client.delete(
|
|
605
|
+
f"/api/v1/orgs/organizations/{self.config.org_id}/projects/{self.config.project_id}/members/",
|
|
606
|
+
params=params,
|
|
607
|
+
)
|
|
608
|
+
response.raise_for_status()
|
|
609
|
+
capture_client_event(
|
|
610
|
+
"client.project.remove_member",
|
|
611
|
+
self,
|
|
612
|
+
{"email": email, "sync_type": "sync"},
|
|
613
|
+
)
|
|
614
|
+
return response.json()
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
class AsyncProject(BaseProject):
|
|
618
|
+
"""
|
|
619
|
+
Asynchronous project management operations.
|
|
620
|
+
"""
|
|
621
|
+
|
|
622
|
+
def __init__(
|
|
623
|
+
self,
|
|
624
|
+
client: httpx.AsyncClient,
|
|
625
|
+
config: Optional[ProjectConfig] = None,
|
|
626
|
+
org_id: Optional[str] = None,
|
|
627
|
+
project_id: Optional[str] = None,
|
|
628
|
+
user_email: Optional[str] = None,
|
|
629
|
+
):
|
|
630
|
+
"""
|
|
631
|
+
Initialize the asynchronous project manager.
|
|
632
|
+
|
|
633
|
+
Args:
|
|
634
|
+
client: HTTP client instance
|
|
635
|
+
config: Project manager configuration
|
|
636
|
+
org_id: Organization ID
|
|
637
|
+
project_id: Project ID
|
|
638
|
+
user_email: User email
|
|
639
|
+
"""
|
|
640
|
+
super().__init__(client, config, org_id, project_id, user_email)
|
|
641
|
+
self._validate_org_project()
|
|
642
|
+
|
|
643
|
+
@api_error_handler
|
|
644
|
+
async def get(self, fields: Optional[List[str]] = None) -> Dict[str, Any]:
|
|
645
|
+
"""
|
|
646
|
+
Get project details.
|
|
647
|
+
|
|
648
|
+
Args:
|
|
649
|
+
fields: List of fields to retrieve
|
|
650
|
+
|
|
651
|
+
Returns:
|
|
652
|
+
Dictionary containing the requested project fields.
|
|
653
|
+
|
|
654
|
+
Raises:
|
|
655
|
+
ValidationError: If the input data is invalid.
|
|
656
|
+
AuthenticationError: If authentication fails.
|
|
657
|
+
RateLimitError: If rate limits are exceeded.
|
|
658
|
+
NetworkError: If network connectivity issues occur.
|
|
659
|
+
ValueError: If org_id or project_id are not set.
|
|
660
|
+
"""
|
|
661
|
+
params = self._prepare_params({"fields": fields})
|
|
662
|
+
response = await self._client.get(
|
|
663
|
+
f"/api/v1/orgs/organizations/{self.config.org_id}/projects/{self.config.project_id}/",
|
|
664
|
+
params=params,
|
|
665
|
+
)
|
|
666
|
+
response.raise_for_status()
|
|
667
|
+
capture_client_event(
|
|
668
|
+
"client.project.get",
|
|
669
|
+
self,
|
|
670
|
+
{"fields": fields, "sync_type": "async"},
|
|
671
|
+
)
|
|
672
|
+
return response.json()
|
|
673
|
+
|
|
674
|
+
@api_error_handler
|
|
675
|
+
async def create(self, name: str, description: Optional[str] = None) -> Dict[str, Any]:
|
|
676
|
+
"""
|
|
677
|
+
Create a new project within the organization.
|
|
678
|
+
|
|
679
|
+
Args:
|
|
680
|
+
name: Name of the project to be created
|
|
681
|
+
description: Optional description for the project
|
|
682
|
+
|
|
683
|
+
Returns:
|
|
684
|
+
Dictionary containing the created project details.
|
|
685
|
+
|
|
686
|
+
Raises:
|
|
687
|
+
ValidationError: If the input data is invalid.
|
|
688
|
+
AuthenticationError: If authentication fails.
|
|
689
|
+
RateLimitError: If rate limits are exceeded.
|
|
690
|
+
NetworkError: If network connectivity issues occur.
|
|
691
|
+
ValueError: If org_id is not set.
|
|
692
|
+
"""
|
|
693
|
+
if not self.config.org_id:
|
|
694
|
+
raise ValueError("org_id must be set to create a project")
|
|
695
|
+
|
|
696
|
+
payload = {"name": name}
|
|
697
|
+
if description is not None:
|
|
698
|
+
payload["description"] = description
|
|
699
|
+
|
|
700
|
+
response = await self._client.post(
|
|
701
|
+
f"/api/v1/orgs/organizations/{self.config.org_id}/projects/",
|
|
702
|
+
json=payload,
|
|
703
|
+
)
|
|
704
|
+
response.raise_for_status()
|
|
705
|
+
capture_client_event(
|
|
706
|
+
"client.project.create",
|
|
707
|
+
self,
|
|
708
|
+
{"name": name, "description": description, "sync_type": "async"},
|
|
709
|
+
)
|
|
710
|
+
return response.json()
|
|
711
|
+
|
|
712
|
+
@api_error_handler
|
|
713
|
+
async def update(
|
|
714
|
+
self,
|
|
715
|
+
custom_instructions: Optional[str] = None,
|
|
716
|
+
custom_categories: Optional[List[str]] = None,
|
|
717
|
+
retrieval_criteria: Optional[List[Dict[str, Any]]] = None,
|
|
718
|
+
enable_graph: Optional[bool] = None,
|
|
719
|
+
) -> Dict[str, Any]:
|
|
720
|
+
"""
|
|
721
|
+
Update project settings.
|
|
722
|
+
|
|
723
|
+
Args:
|
|
724
|
+
custom_instructions: New instructions for the project
|
|
725
|
+
custom_categories: New categories for the project
|
|
726
|
+
retrieval_criteria: New retrieval criteria for the project
|
|
727
|
+
enable_graph: Enable or disable the graph for the project
|
|
728
|
+
|
|
729
|
+
Returns:
|
|
730
|
+
Dictionary containing the API response.
|
|
731
|
+
|
|
732
|
+
Raises:
|
|
733
|
+
ValidationError: If the input data is invalid.
|
|
734
|
+
AuthenticationError: If authentication fails.
|
|
735
|
+
RateLimitError: If rate limits are exceeded.
|
|
736
|
+
NetworkError: If network connectivity issues occur.
|
|
737
|
+
ValueError: If org_id or project_id are not set.
|
|
738
|
+
"""
|
|
739
|
+
if (
|
|
740
|
+
custom_instructions is None
|
|
741
|
+
and custom_categories is None
|
|
742
|
+
and retrieval_criteria is None
|
|
743
|
+
and enable_graph is None
|
|
744
|
+
):
|
|
745
|
+
raise ValueError(
|
|
746
|
+
"At least one parameter must be provided for update: "
|
|
747
|
+
"custom_instructions, custom_categories, retrieval_criteria, "
|
|
748
|
+
"enable_graph"
|
|
749
|
+
)
|
|
750
|
+
|
|
751
|
+
payload = self._prepare_params(
|
|
752
|
+
{
|
|
753
|
+
"custom_instructions": custom_instructions,
|
|
754
|
+
"custom_categories": custom_categories,
|
|
755
|
+
"retrieval_criteria": retrieval_criteria,
|
|
756
|
+
"enable_graph": enable_graph,
|
|
757
|
+
}
|
|
758
|
+
)
|
|
759
|
+
response = await self._client.patch(
|
|
760
|
+
f"/api/v1/orgs/organizations/{self.config.org_id}/projects/{self.config.project_id}/",
|
|
761
|
+
json=payload,
|
|
762
|
+
)
|
|
763
|
+
response.raise_for_status()
|
|
764
|
+
capture_client_event(
|
|
765
|
+
"client.project.update",
|
|
766
|
+
self,
|
|
767
|
+
{
|
|
768
|
+
"custom_instructions": custom_instructions,
|
|
769
|
+
"custom_categories": custom_categories,
|
|
770
|
+
"retrieval_criteria": retrieval_criteria,
|
|
771
|
+
"enable_graph": enable_graph,
|
|
772
|
+
"sync_type": "async",
|
|
773
|
+
},
|
|
774
|
+
)
|
|
775
|
+
return response.json()
|
|
776
|
+
|
|
777
|
+
@api_error_handler
|
|
778
|
+
async def delete(self) -> Dict[str, Any]:
|
|
779
|
+
"""
|
|
780
|
+
Delete the current project and its related data.
|
|
781
|
+
|
|
782
|
+
Returns:
|
|
783
|
+
Dictionary containing the API response.
|
|
784
|
+
|
|
785
|
+
Raises:
|
|
786
|
+
ValidationError: If the input data is invalid.
|
|
787
|
+
AuthenticationError: If authentication fails.
|
|
788
|
+
RateLimitError: If rate limits are exceeded.
|
|
789
|
+
NetworkError: If network connectivity issues occur.
|
|
790
|
+
ValueError: If org_id or project_id are not set.
|
|
791
|
+
"""
|
|
792
|
+
response = await self._client.delete(
|
|
793
|
+
f"/api/v1/orgs/organizations/{self.config.org_id}/projects/{self.config.project_id}/",
|
|
794
|
+
)
|
|
795
|
+
response.raise_for_status()
|
|
796
|
+
capture_client_event(
|
|
797
|
+
"client.project.delete",
|
|
798
|
+
self,
|
|
799
|
+
{"sync_type": "async"},
|
|
800
|
+
)
|
|
801
|
+
return response.json()
|
|
802
|
+
|
|
803
|
+
@api_error_handler
|
|
804
|
+
async def get_members(self) -> Dict[str, Any]:
|
|
805
|
+
"""
|
|
806
|
+
Get all members of the current project.
|
|
807
|
+
|
|
808
|
+
Returns:
|
|
809
|
+
Dictionary containing the list of project members.
|
|
810
|
+
|
|
811
|
+
Raises:
|
|
812
|
+
ValidationError: If the input data is invalid.
|
|
813
|
+
AuthenticationError: If authentication fails.
|
|
814
|
+
RateLimitError: If rate limits are exceeded.
|
|
815
|
+
NetworkError: If network connectivity issues occur.
|
|
816
|
+
ValueError: If org_id or project_id are not set.
|
|
817
|
+
"""
|
|
818
|
+
response = await self._client.get(
|
|
819
|
+
f"/api/v1/orgs/organizations/{self.config.org_id}/projects/{self.config.project_id}/members/",
|
|
820
|
+
)
|
|
821
|
+
response.raise_for_status()
|
|
822
|
+
capture_client_event(
|
|
823
|
+
"client.project.get_members",
|
|
824
|
+
self,
|
|
825
|
+
{"sync_type": "async"},
|
|
826
|
+
)
|
|
827
|
+
return response.json()
|
|
828
|
+
|
|
829
|
+
@api_error_handler
|
|
830
|
+
async def add_member(self, email: str, role: str = "READER") -> Dict[str, Any]:
|
|
831
|
+
"""
|
|
832
|
+
Add a new member to the current project.
|
|
833
|
+
|
|
834
|
+
Args:
|
|
835
|
+
email: Email address of the user to add
|
|
836
|
+
role: Role to assign ("READER" or "OWNER")
|
|
837
|
+
|
|
838
|
+
Returns:
|
|
839
|
+
Dictionary containing the API response.
|
|
840
|
+
|
|
841
|
+
Raises:
|
|
842
|
+
ValidationError: If the input data is invalid.
|
|
843
|
+
AuthenticationError: If authentication fails.
|
|
844
|
+
RateLimitError: If rate limits are exceeded.
|
|
845
|
+
NetworkError: If network connectivity issues occur.
|
|
846
|
+
ValueError: If org_id or project_id are not set.
|
|
847
|
+
"""
|
|
848
|
+
if role not in ["READER", "OWNER"]:
|
|
849
|
+
raise ValueError("Role must be either 'READER' or 'OWNER'")
|
|
850
|
+
|
|
851
|
+
payload = {"email": email, "role": role}
|
|
852
|
+
|
|
853
|
+
response = await self._client.post(
|
|
854
|
+
f"/api/v1/orgs/organizations/{self.config.org_id}/projects/{self.config.project_id}/members/",
|
|
855
|
+
json=payload,
|
|
856
|
+
)
|
|
857
|
+
response.raise_for_status()
|
|
858
|
+
capture_client_event(
|
|
859
|
+
"client.project.add_member",
|
|
860
|
+
self,
|
|
861
|
+
{"email": email, "role": role, "sync_type": "async"},
|
|
862
|
+
)
|
|
863
|
+
return response.json()
|
|
864
|
+
|
|
865
|
+
@api_error_handler
|
|
866
|
+
async def update_member(self, email: str, role: str) -> Dict[str, Any]:
|
|
867
|
+
"""
|
|
868
|
+
Update a member's role in the current project.
|
|
869
|
+
|
|
870
|
+
Args:
|
|
871
|
+
email: Email address of the user to update
|
|
872
|
+
role: New role to assign ("READER" or "OWNER")
|
|
873
|
+
|
|
874
|
+
Returns:
|
|
875
|
+
Dictionary containing the API response.
|
|
876
|
+
|
|
877
|
+
Raises:
|
|
878
|
+
ValidationError: If the input data is invalid.
|
|
879
|
+
AuthenticationError: If authentication fails.
|
|
880
|
+
RateLimitError: If rate limits are exceeded.
|
|
881
|
+
NetworkError: If network connectivity issues occur.
|
|
882
|
+
ValueError: If org_id or project_id are not set.
|
|
883
|
+
"""
|
|
884
|
+
if role not in ["READER", "OWNER"]:
|
|
885
|
+
raise ValueError("Role must be either 'READER' or 'OWNER'")
|
|
886
|
+
|
|
887
|
+
payload = {"email": email, "role": role}
|
|
888
|
+
|
|
889
|
+
response = await self._client.put(
|
|
890
|
+
f"/api/v1/orgs/organizations/{self.config.org_id}/projects/{self.config.project_id}/members/",
|
|
891
|
+
json=payload,
|
|
892
|
+
)
|
|
893
|
+
response.raise_for_status()
|
|
894
|
+
capture_client_event(
|
|
895
|
+
"client.project.update_member",
|
|
896
|
+
self,
|
|
897
|
+
{"email": email, "role": role, "sync_type": "async"},
|
|
898
|
+
)
|
|
899
|
+
return response.json()
|
|
900
|
+
|
|
901
|
+
@api_error_handler
|
|
902
|
+
async def remove_member(self, email: str) -> Dict[str, Any]:
|
|
903
|
+
"""
|
|
904
|
+
Remove a member from the current project.
|
|
905
|
+
|
|
906
|
+
Args:
|
|
907
|
+
email: Email address of the user to remove
|
|
908
|
+
|
|
909
|
+
Returns:
|
|
910
|
+
Dictionary containing the API response.
|
|
911
|
+
|
|
912
|
+
Raises:
|
|
913
|
+
ValidationError: If the input data is invalid.
|
|
914
|
+
AuthenticationError: If authentication fails.
|
|
915
|
+
RateLimitError: If rate limits are exceeded.
|
|
916
|
+
NetworkError: If network connectivity issues occur.
|
|
917
|
+
ValueError: If org_id or project_id are not set.
|
|
918
|
+
"""
|
|
919
|
+
params = {"email": email}
|
|
920
|
+
|
|
921
|
+
response = await self._client.delete(
|
|
922
|
+
f"/api/v1/orgs/organizations/{self.config.org_id}/projects/{self.config.project_id}/members/",
|
|
923
|
+
params=params,
|
|
924
|
+
)
|
|
925
|
+
response.raise_for_status()
|
|
926
|
+
capture_client_event(
|
|
927
|
+
"client.project.remove_member",
|
|
928
|
+
self,
|
|
929
|
+
{"email": email, "sync_type": "async"},
|
|
930
|
+
)
|
|
931
|
+
return response.json()
|