pltr-cli 0.5.0__py3-none-any.whl → 0.5.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.
@@ -0,0 +1,232 @@
1
+ """
2
+ Project service wrapper for Foundry SDK filesystem API.
3
+ """
4
+
5
+ from typing import Any, Optional, Dict, List
6
+
7
+ from .base import BaseService
8
+
9
+
10
+ class ProjectService(BaseService):
11
+ """Service wrapper for Foundry project operations using filesystem API."""
12
+
13
+ def _get_service(self) -> Any:
14
+ """Get the Foundry filesystem service."""
15
+ return self.client.filesystem
16
+
17
+ def create_project(
18
+ self,
19
+ display_name: str,
20
+ space_rid: str,
21
+ description: Optional[str] = None,
22
+ organization_rids: Optional[List[str]] = None,
23
+ default_roles: Optional[List[str]] = None,
24
+ role_grants: Optional[List[Dict[str, Any]]] = None,
25
+ ) -> Dict[str, Any]:
26
+ """
27
+ Create a new project.
28
+
29
+ Args:
30
+ display_name: Project display name (cannot contain '/')
31
+ space_rid: Space Resource Identifier where project will be created
32
+ description: Project description (optional)
33
+ organization_rids: List of organization RIDs (optional)
34
+ default_roles: List of default role names (optional)
35
+ role_grants: List of role grant specifications (optional)
36
+
37
+ Returns:
38
+ Created project information
39
+ """
40
+ try:
41
+ # Prepare the create request payload
42
+ create_request: Dict[str, Any] = {
43
+ "display_name": display_name,
44
+ "space_rid": space_rid,
45
+ }
46
+
47
+ if description:
48
+ create_request["description"] = description
49
+ if organization_rids:
50
+ create_request["organization_rids"] = organization_rids
51
+ if default_roles:
52
+ create_request["default_roles"] = default_roles
53
+ if role_grants:
54
+ create_request["role_grants"] = role_grants
55
+
56
+ project = self.service.Project.create(
57
+ body=create_request,
58
+ preview=True,
59
+ )
60
+ return self._format_project_info(project)
61
+ except Exception as e:
62
+ raise RuntimeError(f"Failed to create project '{display_name}': {e}")
63
+
64
+ def get_project(self, project_rid: str) -> Dict[str, Any]:
65
+ """
66
+ Get information about a specific project.
67
+
68
+ Args:
69
+ project_rid: Project Resource Identifier
70
+
71
+ Returns:
72
+ Project information dictionary
73
+ """
74
+ try:
75
+ project = self.service.Project.get(project_rid, preview=True)
76
+ return self._format_project_info(project)
77
+ except Exception as e:
78
+ raise RuntimeError(f"Failed to get project {project_rid}: {e}")
79
+
80
+ def list_projects(
81
+ self,
82
+ space_rid: Optional[str] = None,
83
+ page_size: Optional[int] = None,
84
+ page_token: Optional[str] = None,
85
+ ) -> List[Dict[str, Any]]:
86
+ """
87
+ List projects, optionally filtered by space.
88
+
89
+ Args:
90
+ space_rid: Space Resource Identifier to filter by (optional)
91
+ page_size: Number of items per page (optional)
92
+ page_token: Pagination token (optional)
93
+
94
+ Returns:
95
+ List of project information dictionaries
96
+ """
97
+ try:
98
+ projects = []
99
+ list_params: Dict[str, Any] = {"preview": True}
100
+
101
+ if space_rid:
102
+ list_params["space_rid"] = space_rid
103
+ if page_size:
104
+ list_params["page_size"] = page_size
105
+ if page_token:
106
+ list_params["page_token"] = page_token
107
+
108
+ # The list method returns an iterator
109
+ for project in self.service.Project.list(**list_params):
110
+ projects.append(self._format_project_info(project))
111
+ return projects
112
+ except Exception as e:
113
+ raise RuntimeError(f"Failed to list projects: {e}")
114
+
115
+ def delete_project(self, project_rid: str) -> None:
116
+ """
117
+ Delete a project.
118
+
119
+ Args:
120
+ project_rid: Project Resource Identifier
121
+
122
+ Raises:
123
+ RuntimeError: If deletion fails
124
+ """
125
+ try:
126
+ self.service.Project.delete(project_rid, preview=True)
127
+ except Exception as e:
128
+ raise RuntimeError(f"Failed to delete project {project_rid}: {e}")
129
+
130
+ def update_project(
131
+ self,
132
+ project_rid: str,
133
+ display_name: Optional[str] = None,
134
+ description: Optional[str] = None,
135
+ ) -> Dict[str, Any]:
136
+ """
137
+ Update project information.
138
+
139
+ Args:
140
+ project_rid: Project Resource Identifier
141
+ display_name: New display name (optional)
142
+ description: New description (optional)
143
+
144
+ Returns:
145
+ Updated project information
146
+ """
147
+ update_request: Dict[str, Any] = {}
148
+ if display_name:
149
+ update_request["display_name"] = display_name
150
+ if description:
151
+ update_request["description"] = description
152
+
153
+ if not update_request:
154
+ raise ValueError("At least one field must be provided for update")
155
+
156
+ try:
157
+ project = self.service.Project.update(
158
+ project_rid=project_rid,
159
+ body=update_request,
160
+ preview=True,
161
+ )
162
+ return self._format_project_info(project)
163
+ except Exception as e:
164
+ raise RuntimeError(f"Failed to update project {project_rid}: {e}")
165
+
166
+ def get_projects_batch(self, project_rids: List[str]) -> List[Dict[str, Any]]:
167
+ """
168
+ Get multiple projects in a single request.
169
+
170
+ Args:
171
+ project_rids: List of project RIDs (max 1000)
172
+
173
+ Returns:
174
+ List of project information dictionaries
175
+ """
176
+ if len(project_rids) > 1000:
177
+ raise ValueError("Maximum batch size is 1000 projects")
178
+
179
+ try:
180
+ response = self.service.Project.get_batch(body=project_rids, preview=True)
181
+ projects = []
182
+ for project in response.projects:
183
+ projects.append(self._format_project_info(project))
184
+ return projects
185
+ except Exception as e:
186
+ raise RuntimeError(f"Failed to get projects batch: {e}")
187
+
188
+ def _format_project_info(self, project: Any) -> Dict[str, Any]:
189
+ """
190
+ Format project information for consistent output.
191
+
192
+ Args:
193
+ project: Project object from Foundry SDK
194
+
195
+ Returns:
196
+ Formatted project information dictionary
197
+ """
198
+ return {
199
+ "rid": getattr(project, "rid", None),
200
+ "display_name": getattr(project, "display_name", None),
201
+ "description": getattr(project, "description", None),
202
+ "path": getattr(project, "path", None),
203
+ "space_rid": getattr(project, "space_rid", None),
204
+ "created_by": getattr(project, "created_by", None),
205
+ "created_time": self._format_timestamp(
206
+ getattr(project, "created_time", None)
207
+ ),
208
+ "modified_by": getattr(project, "modified_by", None),
209
+ "modified_time": self._format_timestamp(
210
+ getattr(project, "modified_time", None)
211
+ ),
212
+ "trash_status": getattr(project, "trash_status", None),
213
+ "type": "project",
214
+ }
215
+
216
+ def _format_timestamp(self, timestamp: Any) -> Optional[str]:
217
+ """
218
+ Format timestamp for display.
219
+
220
+ Args:
221
+ timestamp: Timestamp object from SDK
222
+
223
+ Returns:
224
+ Formatted timestamp string or None
225
+ """
226
+ if timestamp is None:
227
+ return None
228
+
229
+ # Handle different timestamp formats from the SDK
230
+ if hasattr(timestamp, "time"):
231
+ return str(timestamp.time)
232
+ return str(timestamp)
@@ -0,0 +1,289 @@
1
+ """
2
+ Resource service wrapper for Foundry SDK filesystem API.
3
+ """
4
+
5
+ from typing import Any, Optional, Dict, List
6
+
7
+ from .base import BaseService
8
+
9
+
10
+ class ResourceService(BaseService):
11
+ """Service wrapper for Foundry resource operations using filesystem API."""
12
+
13
+ def _get_service(self) -> Any:
14
+ """Get the Foundry filesystem service."""
15
+ return self.client.filesystem
16
+
17
+ def get_resource(self, resource_rid: str) -> Dict[str, Any]:
18
+ """
19
+ Get information about a specific resource.
20
+
21
+ Args:
22
+ resource_rid: Resource Identifier
23
+
24
+ Returns:
25
+ Resource information dictionary
26
+ """
27
+ try:
28
+ resource = self.service.Resource.get(resource_rid, preview=True)
29
+ return self._format_resource_info(resource)
30
+ except Exception as e:
31
+ raise RuntimeError(f"Failed to get resource {resource_rid}: {e}")
32
+
33
+ def list_resources(
34
+ self,
35
+ folder_rid: Optional[str] = None,
36
+ resource_type: Optional[str] = None,
37
+ page_size: Optional[int] = None,
38
+ page_token: Optional[str] = None,
39
+ ) -> List[Dict[str, Any]]:
40
+ """
41
+ List resources, optionally filtered by folder and type.
42
+
43
+ Args:
44
+ folder_rid: Folder Resource Identifier to filter by (optional)
45
+ resource_type: Resource type to filter by (optional)
46
+ page_size: Number of items per page (optional)
47
+ page_token: Pagination token (optional)
48
+
49
+ Returns:
50
+ List of resource information dictionaries
51
+ """
52
+ try:
53
+ resources = []
54
+ list_params: Dict[str, Any] = {"preview": True}
55
+
56
+ if folder_rid:
57
+ list_params["folder_rid"] = folder_rid
58
+ if resource_type:
59
+ list_params["resource_type"] = resource_type
60
+ if page_size:
61
+ list_params["page_size"] = page_size
62
+ if page_token:
63
+ list_params["page_token"] = page_token
64
+
65
+ # The list method returns an iterator
66
+ for resource in self.service.Resource.list(**list_params):
67
+ resources.append(self._format_resource_info(resource))
68
+ return resources
69
+ except Exception as e:
70
+ raise RuntimeError(f"Failed to list resources: {e}")
71
+
72
+ def get_resources_batch(self, resource_rids: List[str]) -> List[Dict[str, Any]]:
73
+ """
74
+ Get multiple resources in a single request.
75
+
76
+ Args:
77
+ resource_rids: List of resource RIDs (max 1000)
78
+
79
+ Returns:
80
+ List of resource information dictionaries
81
+ """
82
+ if len(resource_rids) > 1000:
83
+ raise ValueError("Maximum batch size is 1000 resources")
84
+
85
+ try:
86
+ response = self.service.Resource.get_batch(body=resource_rids, preview=True)
87
+ resources = []
88
+ for resource in response.resources:
89
+ resources.append(self._format_resource_info(resource))
90
+ return resources
91
+ except Exception as e:
92
+ raise RuntimeError(f"Failed to get resources batch: {e}")
93
+
94
+ def get_resource_metadata(self, resource_rid: str) -> Dict[str, Any]:
95
+ """
96
+ Get metadata for a specific resource.
97
+
98
+ Args:
99
+ resource_rid: Resource Identifier
100
+
101
+ Returns:
102
+ Resource metadata dictionary
103
+ """
104
+ try:
105
+ metadata = self.service.Resource.get_metadata(resource_rid, preview=True)
106
+ return self._format_metadata(metadata)
107
+ except Exception as e:
108
+ raise RuntimeError(
109
+ f"Failed to get metadata for resource {resource_rid}: {e}"
110
+ )
111
+
112
+ def set_resource_metadata(
113
+ self, resource_rid: str, metadata: Dict[str, Any]
114
+ ) -> Dict[str, Any]:
115
+ """
116
+ Set metadata for a specific resource.
117
+
118
+ Args:
119
+ resource_rid: Resource Identifier
120
+ metadata: Metadata dictionary to set
121
+
122
+ Returns:
123
+ Updated resource metadata
124
+ """
125
+ try:
126
+ updated_metadata = self.service.Resource.set_metadata(
127
+ resource_rid=resource_rid,
128
+ body=metadata,
129
+ preview=True,
130
+ )
131
+ return self._format_metadata(updated_metadata)
132
+ except Exception as e:
133
+ raise RuntimeError(
134
+ f"Failed to set metadata for resource {resource_rid}: {e}"
135
+ )
136
+
137
+ def delete_resource_metadata(self, resource_rid: str, keys: List[str]) -> None:
138
+ """
139
+ Delete specific metadata keys for a resource.
140
+
141
+ Args:
142
+ resource_rid: Resource Identifier
143
+ keys: List of metadata keys to delete
144
+
145
+ Raises:
146
+ RuntimeError: If deletion fails
147
+ """
148
+ try:
149
+ self.service.Resource.delete_metadata(
150
+ resource_rid=resource_rid,
151
+ body={"keys": keys},
152
+ preview=True,
153
+ )
154
+ except Exception as e:
155
+ raise RuntimeError(
156
+ f"Failed to delete metadata for resource {resource_rid}: {e}"
157
+ )
158
+
159
+ def move_resource(
160
+ self, resource_rid: str, target_folder_rid: str
161
+ ) -> Dict[str, Any]:
162
+ """
163
+ Move a resource to a different folder.
164
+
165
+ Args:
166
+ resource_rid: Resource Identifier
167
+ target_folder_rid: Target folder Resource Identifier
168
+
169
+ Returns:
170
+ Updated resource information
171
+ """
172
+ try:
173
+ resource = self.service.Resource.move(
174
+ resource_rid=resource_rid,
175
+ body={"target_folder_rid": target_folder_rid},
176
+ preview=True,
177
+ )
178
+ return self._format_resource_info(resource)
179
+ except Exception as e:
180
+ raise RuntimeError(f"Failed to move resource {resource_rid}: {e}")
181
+
182
+ def search_resources(
183
+ self,
184
+ query: str,
185
+ resource_type: Optional[str] = None,
186
+ folder_rid: Optional[str] = None,
187
+ page_size: Optional[int] = None,
188
+ page_token: Optional[str] = None,
189
+ ) -> List[Dict[str, Any]]:
190
+ """
191
+ Search for resources by query string.
192
+
193
+ Args:
194
+ query: Search query string
195
+ resource_type: Resource type to filter by (optional)
196
+ folder_rid: Folder to search within (optional)
197
+ page_size: Number of items per page (optional)
198
+ page_token: Pagination token (optional)
199
+
200
+ Returns:
201
+ List of matching resource information dictionaries
202
+ """
203
+ try:
204
+ resources = []
205
+ search_params: Dict[str, Any] = {
206
+ "query": query,
207
+ "preview": True,
208
+ }
209
+
210
+ if resource_type:
211
+ search_params["resource_type"] = resource_type
212
+ if folder_rid:
213
+ search_params["folder_rid"] = folder_rid
214
+ if page_size:
215
+ search_params["page_size"] = page_size
216
+ if page_token:
217
+ search_params["page_token"] = page_token
218
+
219
+ # The search method returns an iterator
220
+ for resource in self.service.Resource.search(**search_params):
221
+ resources.append(self._format_resource_info(resource))
222
+ return resources
223
+ except Exception as e:
224
+ raise RuntimeError(f"Failed to search resources: {e}")
225
+
226
+ def _format_resource_info(self, resource: Any) -> Dict[str, Any]:
227
+ """
228
+ Format resource information for consistent output.
229
+
230
+ Args:
231
+ resource: Resource object from Foundry SDK
232
+
233
+ Returns:
234
+ Formatted resource information dictionary
235
+ """
236
+ return {
237
+ "rid": getattr(resource, "rid", None),
238
+ "display_name": getattr(resource, "display_name", None),
239
+ "name": getattr(resource, "name", None),
240
+ "description": getattr(resource, "description", None),
241
+ "path": getattr(resource, "path", None),
242
+ "type": getattr(resource, "type", None),
243
+ "folder_rid": getattr(resource, "folder_rid", None),
244
+ "created_by": getattr(resource, "created_by", None),
245
+ "created_time": self._format_timestamp(
246
+ getattr(resource, "created_time", None)
247
+ ),
248
+ "modified_by": getattr(resource, "modified_by", None),
249
+ "modified_time": self._format_timestamp(
250
+ getattr(resource, "modified_time", None)
251
+ ),
252
+ "size_bytes": getattr(resource, "size_bytes", None),
253
+ "trash_status": getattr(resource, "trash_status", None),
254
+ }
255
+
256
+ def _format_metadata(self, metadata: Any) -> Dict[str, Any]:
257
+ """
258
+ Format metadata for consistent output.
259
+
260
+ Args:
261
+ metadata: Metadata object from Foundry SDK
262
+
263
+ Returns:
264
+ Formatted metadata dictionary
265
+ """
266
+ if hasattr(metadata, "__dict__"):
267
+ return dict(metadata.__dict__)
268
+ elif isinstance(metadata, dict):
269
+ return metadata
270
+ else:
271
+ return {"raw": str(metadata)}
272
+
273
+ def _format_timestamp(self, timestamp: Any) -> Optional[str]:
274
+ """
275
+ Format timestamp for display.
276
+
277
+ Args:
278
+ timestamp: Timestamp object from SDK
279
+
280
+ Returns:
281
+ Formatted timestamp string or None
282
+ """
283
+ if timestamp is None:
284
+ return None
285
+
286
+ # Handle different timestamp formats from the SDK
287
+ if hasattr(timestamp, "time"):
288
+ return str(timestamp.time)
289
+ return str(timestamp)