pltr-cli 0.10.0__py3-none-any.whl → 0.12.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.
- pltr/__init__.py +1 -1
- pltr/cli.py +16 -0
- pltr/commands/admin.py +553 -9
- pltr/commands/aip_agents.py +333 -0
- pltr/commands/connectivity.py +309 -1
- pltr/commands/cp.py +103 -0
- pltr/commands/dataset.py +104 -4
- pltr/commands/mediasets.py +176 -0
- pltr/commands/ontology.py +137 -13
- pltr/commands/orchestration.py +167 -11
- pltr/commands/project.py +249 -0
- pltr/commands/resource.py +452 -0
- pltr/commands/sql.py +54 -7
- pltr/commands/third_party_applications.py +82 -0
- pltr/services/admin.py +318 -1
- pltr/services/aip_agents.py +147 -0
- pltr/services/base.py +104 -1
- pltr/services/connectivity.py +139 -0
- pltr/services/copy.py +391 -0
- pltr/services/dataset.py +80 -9
- pltr/services/mediasets.py +144 -9
- pltr/services/ontology.py +119 -1
- pltr/services/orchestration.py +133 -1
- pltr/services/project.py +136 -0
- pltr/services/resource.py +227 -0
- pltr/services/sql.py +44 -20
- pltr/services/third_party_applications.py +53 -0
- pltr/utils/formatting.py +195 -1
- pltr/utils/pagination.py +325 -0
- {pltr_cli-0.10.0.dist-info → pltr_cli-0.12.0.dist-info}/METADATA +5 -3
- pltr_cli-0.12.0.dist-info/RECORD +62 -0
- {pltr_cli-0.10.0.dist-info → pltr_cli-0.12.0.dist-info}/WHEEL +1 -1
- pltr_cli-0.10.0.dist-info/RECORD +0 -55
- {pltr_cli-0.10.0.dist-info → pltr_cli-0.12.0.dist-info}/entry_points.txt +0 -0
- {pltr_cli-0.10.0.dist-info → pltr_cli-0.12.0.dist-info}/licenses/LICENSE +0 -0
pltr/services/project.py
CHANGED
|
@@ -185,6 +185,126 @@ class ProjectService(BaseService):
|
|
|
185
185
|
except Exception as e:
|
|
186
186
|
raise RuntimeError(f"Failed to get projects batch: {e}")
|
|
187
187
|
|
|
188
|
+
# ==================== Organization Operations ====================
|
|
189
|
+
|
|
190
|
+
def add_organizations(self, project_rid: str, organization_rids: List[str]) -> None:
|
|
191
|
+
"""
|
|
192
|
+
Add organizations to a project.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
project_rid: Project Resource Identifier
|
|
196
|
+
organization_rids: List of organization RIDs to add
|
|
197
|
+
|
|
198
|
+
Raises:
|
|
199
|
+
RuntimeError: If adding organizations fails
|
|
200
|
+
"""
|
|
201
|
+
try:
|
|
202
|
+
self.service.Project.add_organizations(
|
|
203
|
+
project_rid, organization_rids=organization_rids, preview=True
|
|
204
|
+
)
|
|
205
|
+
except Exception as e:
|
|
206
|
+
raise RuntimeError(
|
|
207
|
+
f"Failed to add organizations to project {project_rid}: {e}"
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
def remove_organizations(
|
|
211
|
+
self, project_rid: str, organization_rids: List[str]
|
|
212
|
+
) -> None:
|
|
213
|
+
"""
|
|
214
|
+
Remove organizations from a project.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
project_rid: Project Resource Identifier
|
|
218
|
+
organization_rids: List of organization RIDs to remove
|
|
219
|
+
|
|
220
|
+
Raises:
|
|
221
|
+
RuntimeError: If removing organizations fails
|
|
222
|
+
"""
|
|
223
|
+
try:
|
|
224
|
+
self.service.Project.remove_organizations(
|
|
225
|
+
project_rid, organization_rids=organization_rids, preview=True
|
|
226
|
+
)
|
|
227
|
+
except Exception as e:
|
|
228
|
+
raise RuntimeError(
|
|
229
|
+
f"Failed to remove organizations from project {project_rid}: {e}"
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
def list_organizations(
|
|
233
|
+
self,
|
|
234
|
+
project_rid: str,
|
|
235
|
+
page_size: Optional[int] = None,
|
|
236
|
+
page_token: Optional[str] = None,
|
|
237
|
+
) -> List[Dict[str, Any]]:
|
|
238
|
+
"""
|
|
239
|
+
List organizations directly applied to a project.
|
|
240
|
+
|
|
241
|
+
Args:
|
|
242
|
+
project_rid: Project Resource Identifier
|
|
243
|
+
page_size: Number of items per page (optional)
|
|
244
|
+
page_token: Pagination token (optional)
|
|
245
|
+
|
|
246
|
+
Returns:
|
|
247
|
+
List of organization information dictionaries
|
|
248
|
+
"""
|
|
249
|
+
try:
|
|
250
|
+
organizations = []
|
|
251
|
+
list_params: Dict[str, Any] = {"preview": True}
|
|
252
|
+
|
|
253
|
+
if page_size:
|
|
254
|
+
list_params["page_size"] = page_size
|
|
255
|
+
if page_token:
|
|
256
|
+
list_params["page_token"] = page_token
|
|
257
|
+
|
|
258
|
+
for org in self.service.Project.organizations(project_rid, **list_params):
|
|
259
|
+
organizations.append(self._format_organization_info(org))
|
|
260
|
+
return organizations
|
|
261
|
+
except Exception as e:
|
|
262
|
+
raise RuntimeError(
|
|
263
|
+
f"Failed to list organizations for project {project_rid}: {e}"
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
# ==================== Template Operations ====================
|
|
267
|
+
|
|
268
|
+
def create_project_from_template(
|
|
269
|
+
self,
|
|
270
|
+
template_rid: str,
|
|
271
|
+
variable_values: Dict[str, str],
|
|
272
|
+
default_roles: Optional[List[str]] = None,
|
|
273
|
+
organization_rids: Optional[List[str]] = None,
|
|
274
|
+
project_description: Optional[str] = None,
|
|
275
|
+
) -> Dict[str, Any]:
|
|
276
|
+
"""
|
|
277
|
+
Create a project from a template.
|
|
278
|
+
|
|
279
|
+
Args:
|
|
280
|
+
template_rid: Template Resource Identifier
|
|
281
|
+
variable_values: Dictionary mapping template variable names to values
|
|
282
|
+
default_roles: List of default role names (optional)
|
|
283
|
+
organization_rids: List of organization RIDs (optional)
|
|
284
|
+
project_description: Project description (optional)
|
|
285
|
+
|
|
286
|
+
Returns:
|
|
287
|
+
Created project information
|
|
288
|
+
"""
|
|
289
|
+
try:
|
|
290
|
+
create_params: Dict[str, Any] = {
|
|
291
|
+
"template_rid": template_rid,
|
|
292
|
+
"variable_values": variable_values,
|
|
293
|
+
"preview": True,
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if default_roles:
|
|
297
|
+
create_params["default_roles"] = default_roles
|
|
298
|
+
if organization_rids:
|
|
299
|
+
create_params["organization_rids"] = organization_rids
|
|
300
|
+
if project_description:
|
|
301
|
+
create_params["project_description"] = project_description
|
|
302
|
+
|
|
303
|
+
project = self.service.Project.create_from_template(**create_params)
|
|
304
|
+
return self._format_project_info(project)
|
|
305
|
+
except Exception as e:
|
|
306
|
+
raise RuntimeError(f"Failed to create project from template: {e}")
|
|
307
|
+
|
|
188
308
|
def _format_project_info(self, project: Any) -> Dict[str, Any]:
|
|
189
309
|
"""
|
|
190
310
|
Format project information for consistent output.
|
|
@@ -213,6 +333,22 @@ class ProjectService(BaseService):
|
|
|
213
333
|
"type": "project",
|
|
214
334
|
}
|
|
215
335
|
|
|
336
|
+
def _format_organization_info(self, organization: Any) -> Dict[str, Any]:
|
|
337
|
+
"""
|
|
338
|
+
Format organization information for consistent output.
|
|
339
|
+
|
|
340
|
+
Args:
|
|
341
|
+
organization: Organization object from Foundry SDK
|
|
342
|
+
|
|
343
|
+
Returns:
|
|
344
|
+
Formatted organization information dictionary
|
|
345
|
+
"""
|
|
346
|
+
return {
|
|
347
|
+
"organization_rid": getattr(organization, "organization_rid", None),
|
|
348
|
+
"display_name": getattr(organization, "display_name", None),
|
|
349
|
+
"description": getattr(organization, "description", None),
|
|
350
|
+
}
|
|
351
|
+
|
|
216
352
|
def _format_timestamp(self, timestamp: Any) -> Optional[str]:
|
|
217
353
|
"""
|
|
218
354
|
Format timestamp for display.
|
pltr/services/resource.py
CHANGED
|
@@ -239,6 +239,184 @@ class ResourceService(BaseService):
|
|
|
239
239
|
except Exception as e:
|
|
240
240
|
raise RuntimeError(f"Failed to search resources: {e}")
|
|
241
241
|
|
|
242
|
+
# ==================== Trash Operations ====================
|
|
243
|
+
|
|
244
|
+
def delete_resource(self, resource_rid: str) -> None:
|
|
245
|
+
"""
|
|
246
|
+
Move a resource to trash.
|
|
247
|
+
|
|
248
|
+
The resource can be restored later or permanently deleted.
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
resource_rid: Resource Identifier
|
|
252
|
+
|
|
253
|
+
Raises:
|
|
254
|
+
RuntimeError: If deletion fails
|
|
255
|
+
"""
|
|
256
|
+
try:
|
|
257
|
+
self.service.Resource.delete(resource_rid, preview=True)
|
|
258
|
+
except Exception as e:
|
|
259
|
+
raise RuntimeError(f"Failed to delete resource {resource_rid}: {e}")
|
|
260
|
+
|
|
261
|
+
def restore_resource(self, resource_rid: str) -> None:
|
|
262
|
+
"""
|
|
263
|
+
Restore a resource from trash.
|
|
264
|
+
|
|
265
|
+
This also restores any directly trashed ancestors.
|
|
266
|
+
Operation is ignored if the resource is not trashed.
|
|
267
|
+
|
|
268
|
+
Args:
|
|
269
|
+
resource_rid: Resource Identifier
|
|
270
|
+
|
|
271
|
+
Raises:
|
|
272
|
+
RuntimeError: If restoration fails
|
|
273
|
+
"""
|
|
274
|
+
try:
|
|
275
|
+
self.service.Resource.restore(resource_rid, preview=True)
|
|
276
|
+
except Exception as e:
|
|
277
|
+
raise RuntimeError(f"Failed to restore resource {resource_rid}: {e}")
|
|
278
|
+
|
|
279
|
+
def permanently_delete_resource(self, resource_rid: str) -> None:
|
|
280
|
+
"""
|
|
281
|
+
Permanently delete a resource from trash.
|
|
282
|
+
|
|
283
|
+
The resource must already be in the trash. This operation is irreversible.
|
|
284
|
+
|
|
285
|
+
Args:
|
|
286
|
+
resource_rid: Resource Identifier
|
|
287
|
+
|
|
288
|
+
Raises:
|
|
289
|
+
RuntimeError: If permanent deletion fails
|
|
290
|
+
"""
|
|
291
|
+
try:
|
|
292
|
+
self.service.Resource.permanently_delete(resource_rid, preview=True)
|
|
293
|
+
except Exception as e:
|
|
294
|
+
raise RuntimeError(
|
|
295
|
+
f"Failed to permanently delete resource {resource_rid}: {e}"
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
# ==================== Markings Operations ====================
|
|
299
|
+
|
|
300
|
+
def add_markings(self, resource_rid: str, marking_ids: List[str]) -> None:
|
|
301
|
+
"""
|
|
302
|
+
Add markings to a resource.
|
|
303
|
+
|
|
304
|
+
Args:
|
|
305
|
+
resource_rid: Resource Identifier
|
|
306
|
+
marking_ids: List of marking identifiers to add
|
|
307
|
+
|
|
308
|
+
Raises:
|
|
309
|
+
RuntimeError: If adding markings fails
|
|
310
|
+
"""
|
|
311
|
+
try:
|
|
312
|
+
self.service.Resource.add_markings(
|
|
313
|
+
resource_rid, marking_ids=marking_ids, preview=True
|
|
314
|
+
)
|
|
315
|
+
except Exception as e:
|
|
316
|
+
raise RuntimeError(
|
|
317
|
+
f"Failed to add markings to resource {resource_rid}: {e}"
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
def remove_markings(self, resource_rid: str, marking_ids: List[str]) -> None:
|
|
321
|
+
"""
|
|
322
|
+
Remove markings from a resource.
|
|
323
|
+
|
|
324
|
+
Args:
|
|
325
|
+
resource_rid: Resource Identifier
|
|
326
|
+
marking_ids: List of marking identifiers to remove
|
|
327
|
+
|
|
328
|
+
Raises:
|
|
329
|
+
RuntimeError: If removing markings fails
|
|
330
|
+
"""
|
|
331
|
+
try:
|
|
332
|
+
self.service.Resource.remove_markings(
|
|
333
|
+
resource_rid, marking_ids=marking_ids, preview=True
|
|
334
|
+
)
|
|
335
|
+
except Exception as e:
|
|
336
|
+
raise RuntimeError(
|
|
337
|
+
f"Failed to remove markings from resource {resource_rid}: {e}"
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
def list_markings(
|
|
341
|
+
self,
|
|
342
|
+
resource_rid: str,
|
|
343
|
+
page_size: Optional[int] = None,
|
|
344
|
+
page_token: Optional[str] = None,
|
|
345
|
+
) -> List[Dict[str, Any]]:
|
|
346
|
+
"""
|
|
347
|
+
List markings directly applied to a resource.
|
|
348
|
+
|
|
349
|
+
Args:
|
|
350
|
+
resource_rid: Resource Identifier
|
|
351
|
+
page_size: Number of items per page (optional)
|
|
352
|
+
page_token: Pagination token (optional)
|
|
353
|
+
|
|
354
|
+
Returns:
|
|
355
|
+
List of marking information dictionaries
|
|
356
|
+
"""
|
|
357
|
+
try:
|
|
358
|
+
markings = []
|
|
359
|
+
list_params: Dict[str, Any] = {"preview": True}
|
|
360
|
+
|
|
361
|
+
if page_size:
|
|
362
|
+
list_params["page_size"] = page_size
|
|
363
|
+
if page_token:
|
|
364
|
+
list_params["page_token"] = page_token
|
|
365
|
+
|
|
366
|
+
for marking in self.service.Resource.markings(resource_rid, **list_params):
|
|
367
|
+
markings.append(self._format_marking_info(marking))
|
|
368
|
+
return markings
|
|
369
|
+
except Exception as e:
|
|
370
|
+
raise RuntimeError(
|
|
371
|
+
f"Failed to list markings for resource {resource_rid}: {e}"
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
# ==================== Access & Batch Operations ====================
|
|
375
|
+
|
|
376
|
+
def get_access_requirements(self, resource_rid: str) -> Dict[str, Any]:
|
|
377
|
+
"""
|
|
378
|
+
Get access requirements for a resource.
|
|
379
|
+
|
|
380
|
+
Returns the Organizations and Markings required to view the resource.
|
|
381
|
+
|
|
382
|
+
Args:
|
|
383
|
+
resource_rid: Resource Identifier
|
|
384
|
+
|
|
385
|
+
Returns:
|
|
386
|
+
Access requirements dictionary with organizations and markings
|
|
387
|
+
"""
|
|
388
|
+
try:
|
|
389
|
+
requirements = self.service.Resource.get_access_requirements(
|
|
390
|
+
resource_rid, preview=True
|
|
391
|
+
)
|
|
392
|
+
return self._format_access_requirements(requirements)
|
|
393
|
+
except Exception as e:
|
|
394
|
+
raise RuntimeError(
|
|
395
|
+
f"Failed to get access requirements for resource {resource_rid}: {e}"
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
def get_resources_by_path_batch(self, paths: List[str]) -> List[Dict[str, Any]]:
|
|
399
|
+
"""
|
|
400
|
+
Get multiple resources by their absolute paths in a single request.
|
|
401
|
+
|
|
402
|
+
Args:
|
|
403
|
+
paths: List of absolute paths (max 1000)
|
|
404
|
+
|
|
405
|
+
Returns:
|
|
406
|
+
List of resource information dictionaries
|
|
407
|
+
"""
|
|
408
|
+
if len(paths) > 1000:
|
|
409
|
+
raise ValueError("Maximum batch size is 1000 paths")
|
|
410
|
+
|
|
411
|
+
try:
|
|
412
|
+
response = self.service.Resource.get_by_path_batch(body=paths, preview=True)
|
|
413
|
+
resources = []
|
|
414
|
+
for resource in response.resources:
|
|
415
|
+
resources.append(self._format_resource_info(resource))
|
|
416
|
+
return resources
|
|
417
|
+
except Exception as e:
|
|
418
|
+
raise RuntimeError(f"Failed to get resources by path batch: {e}")
|
|
419
|
+
|
|
242
420
|
def _format_resource_info(self, resource: Any) -> Dict[str, Any]:
|
|
243
421
|
"""
|
|
244
422
|
Format resource information for consistent output.
|
|
@@ -303,3 +481,52 @@ class ResourceService(BaseService):
|
|
|
303
481
|
if hasattr(timestamp, "time"):
|
|
304
482
|
return str(timestamp.time)
|
|
305
483
|
return str(timestamp)
|
|
484
|
+
|
|
485
|
+
def _format_marking_info(self, marking: Any) -> Dict[str, Any]:
|
|
486
|
+
"""
|
|
487
|
+
Format marking information for consistent output.
|
|
488
|
+
|
|
489
|
+
Args:
|
|
490
|
+
marking: Marking object from Foundry SDK
|
|
491
|
+
|
|
492
|
+
Returns:
|
|
493
|
+
Formatted marking information dictionary
|
|
494
|
+
"""
|
|
495
|
+
return {
|
|
496
|
+
"marking_id": getattr(marking, "marking_id", None),
|
|
497
|
+
"display_name": getattr(marking, "display_name", None),
|
|
498
|
+
"description": getattr(marking, "description", None),
|
|
499
|
+
"category_id": getattr(marking, "category_id", None),
|
|
500
|
+
"category_display_name": getattr(marking, "category_display_name", None),
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
def _format_access_requirements(self, requirements: Any) -> Dict[str, Any]:
|
|
504
|
+
"""
|
|
505
|
+
Format access requirements for consistent output.
|
|
506
|
+
|
|
507
|
+
Args:
|
|
508
|
+
requirements: AccessRequirements object from Foundry SDK
|
|
509
|
+
|
|
510
|
+
Returns:
|
|
511
|
+
Formatted access requirements dictionary
|
|
512
|
+
"""
|
|
513
|
+
organizations = []
|
|
514
|
+
markings = []
|
|
515
|
+
|
|
516
|
+
if hasattr(requirements, "organizations"):
|
|
517
|
+
for org in getattr(requirements, "organizations", []) or []:
|
|
518
|
+
organizations.append(
|
|
519
|
+
{
|
|
520
|
+
"organization_rid": getattr(org, "organization_rid", None),
|
|
521
|
+
"display_name": getattr(org, "display_name", None),
|
|
522
|
+
}
|
|
523
|
+
)
|
|
524
|
+
|
|
525
|
+
if hasattr(requirements, "markings"):
|
|
526
|
+
for marking in getattr(requirements, "markings", []) or []:
|
|
527
|
+
markings.append(self._format_marking_info(marking))
|
|
528
|
+
|
|
529
|
+
return {
|
|
530
|
+
"organizations": organizations,
|
|
531
|
+
"markings": markings,
|
|
532
|
+
}
|
pltr/services/sql.py
CHANGED
|
@@ -30,6 +30,7 @@ class SqlService(BaseService):
|
|
|
30
30
|
fallback_branch_ids: Optional[List[str]] = None,
|
|
31
31
|
timeout: int = 300,
|
|
32
32
|
format: str = "table",
|
|
33
|
+
preview: bool = True,
|
|
33
34
|
) -> Dict[str, Any]:
|
|
34
35
|
"""
|
|
35
36
|
Execute a SQL query and wait for completion.
|
|
@@ -39,6 +40,7 @@ class SqlService(BaseService):
|
|
|
39
40
|
fallback_branch_ids: Optional list of branch IDs for fallback
|
|
40
41
|
timeout: Maximum time to wait for query completion (seconds)
|
|
41
42
|
format: Output format for results ('table', 'json', 'raw')
|
|
43
|
+
preview: Enable preview mode (required for SQL API, defaults to True)
|
|
42
44
|
|
|
43
45
|
Returns:
|
|
44
46
|
Dictionary containing query results and metadata
|
|
@@ -49,19 +51,23 @@ class SqlService(BaseService):
|
|
|
49
51
|
try:
|
|
50
52
|
# Submit the query
|
|
51
53
|
status = self.service.execute(
|
|
52
|
-
query=query, fallback_branch_ids=fallback_branch_ids
|
|
54
|
+
query=query, fallback_branch_ids=fallback_branch_ids, preview=preview
|
|
53
55
|
)
|
|
54
56
|
|
|
55
57
|
# If the query completed immediately
|
|
56
58
|
if isinstance(status, SucceededQueryStatus):
|
|
57
|
-
return self._format_completed_query(
|
|
59
|
+
return self._format_completed_query(
|
|
60
|
+
status.query_id, format, preview=preview
|
|
61
|
+
)
|
|
58
62
|
elif isinstance(status, FailedQueryStatus):
|
|
59
63
|
raise RuntimeError(f"Query failed: {status.error_message}")
|
|
60
64
|
elif isinstance(status, CanceledQueryStatus):
|
|
61
65
|
raise RuntimeError("Query was canceled")
|
|
62
66
|
elif isinstance(status, RunningQueryStatus):
|
|
63
67
|
# Wait for completion
|
|
64
|
-
return self._wait_for_query_completion(
|
|
68
|
+
return self._wait_for_query_completion(
|
|
69
|
+
status.query_id, timeout, format, preview=preview
|
|
70
|
+
)
|
|
65
71
|
else:
|
|
66
72
|
raise RuntimeError(f"Unknown query status type: {type(status)}")
|
|
67
73
|
|
|
@@ -71,7 +77,10 @@ class SqlService(BaseService):
|
|
|
71
77
|
raise RuntimeError(f"Failed to execute query: {e}")
|
|
72
78
|
|
|
73
79
|
def submit_query(
|
|
74
|
-
self,
|
|
80
|
+
self,
|
|
81
|
+
query: str,
|
|
82
|
+
fallback_branch_ids: Optional[List[str]] = None,
|
|
83
|
+
preview: bool = True,
|
|
75
84
|
) -> Dict[str, Any]:
|
|
76
85
|
"""
|
|
77
86
|
Submit a SQL query without waiting for completion.
|
|
@@ -79,6 +88,7 @@ class SqlService(BaseService):
|
|
|
79
88
|
Args:
|
|
80
89
|
query: SQL query string
|
|
81
90
|
fallback_branch_ids: Optional list of branch IDs for fallback
|
|
91
|
+
preview: Enable preview mode (required for SQL API, defaults to True)
|
|
82
92
|
|
|
83
93
|
Returns:
|
|
84
94
|
Dictionary containing query ID and initial status
|
|
@@ -88,18 +98,19 @@ class SqlService(BaseService):
|
|
|
88
98
|
"""
|
|
89
99
|
try:
|
|
90
100
|
status = self.service.execute(
|
|
91
|
-
query=query, fallback_branch_ids=fallback_branch_ids
|
|
101
|
+
query=query, fallback_branch_ids=fallback_branch_ids, preview=preview
|
|
92
102
|
)
|
|
93
103
|
return self._format_query_status(status)
|
|
94
104
|
except Exception as e:
|
|
95
105
|
raise RuntimeError(f"Failed to submit query: {e}")
|
|
96
106
|
|
|
97
|
-
def get_query_status(self, query_id: str) -> Dict[str, Any]:
|
|
107
|
+
def get_query_status(self, query_id: str, preview: bool = True) -> Dict[str, Any]:
|
|
98
108
|
"""
|
|
99
109
|
Get the status of a submitted query.
|
|
100
110
|
|
|
101
111
|
Args:
|
|
102
112
|
query_id: Query identifier
|
|
113
|
+
preview: Enable preview mode (required for SQL API, defaults to True)
|
|
103
114
|
|
|
104
115
|
Returns:
|
|
105
116
|
Dictionary containing query status information
|
|
@@ -108,18 +119,21 @@ class SqlService(BaseService):
|
|
|
108
119
|
RuntimeError: If status check fails
|
|
109
120
|
"""
|
|
110
121
|
try:
|
|
111
|
-
status = self.service.get_status(query_id)
|
|
122
|
+
status = self.service.get_status(query_id, preview=preview)
|
|
112
123
|
return self._format_query_status(status)
|
|
113
124
|
except Exception as e:
|
|
114
125
|
raise RuntimeError(f"Failed to get query status: {e}")
|
|
115
126
|
|
|
116
|
-
def get_query_results(
|
|
127
|
+
def get_query_results(
|
|
128
|
+
self, query_id: str, format: str = "table", preview: bool = True
|
|
129
|
+
) -> Dict[str, Any]:
|
|
117
130
|
"""
|
|
118
131
|
Get the results of a completed query.
|
|
119
132
|
|
|
120
133
|
Args:
|
|
121
134
|
query_id: Query identifier
|
|
122
135
|
format: Output format ('table', 'json', 'raw')
|
|
136
|
+
preview: Enable preview mode (required for SQL API, defaults to True)
|
|
123
137
|
|
|
124
138
|
Returns:
|
|
125
139
|
Dictionary containing query results
|
|
@@ -129,7 +143,7 @@ class SqlService(BaseService):
|
|
|
129
143
|
"""
|
|
130
144
|
try:
|
|
131
145
|
# First check if the query has completed successfully
|
|
132
|
-
status = self.service.get_status(query_id)
|
|
146
|
+
status = self.service.get_status(query_id, preview=preview)
|
|
133
147
|
if not isinstance(status, SucceededQueryStatus):
|
|
134
148
|
status_info = self._format_query_status(status)
|
|
135
149
|
if isinstance(status, FailedQueryStatus):
|
|
@@ -142,7 +156,7 @@ class SqlService(BaseService):
|
|
|
142
156
|
raise RuntimeError(f"Query status: {status_info['status']}")
|
|
143
157
|
|
|
144
158
|
# Get the results
|
|
145
|
-
results_bytes = self.service.get_results(query_id)
|
|
159
|
+
results_bytes = self.service.get_results(query_id, preview=preview)
|
|
146
160
|
return self._format_query_results(results_bytes, format)
|
|
147
161
|
|
|
148
162
|
except Exception as e:
|
|
@@ -150,12 +164,13 @@ class SqlService(BaseService):
|
|
|
150
164
|
raise
|
|
151
165
|
raise RuntimeError(f"Failed to get query results: {e}")
|
|
152
166
|
|
|
153
|
-
def cancel_query(self, query_id: str) -> Dict[str, Any]:
|
|
167
|
+
def cancel_query(self, query_id: str, preview: bool = True) -> Dict[str, Any]:
|
|
154
168
|
"""
|
|
155
169
|
Cancel a running query.
|
|
156
170
|
|
|
157
171
|
Args:
|
|
158
172
|
query_id: Query identifier
|
|
173
|
+
preview: Enable preview mode (required for SQL API, defaults to True)
|
|
159
174
|
|
|
160
175
|
Returns:
|
|
161
176
|
Dictionary containing cancellation status
|
|
@@ -164,15 +179,19 @@ class SqlService(BaseService):
|
|
|
164
179
|
RuntimeError: If cancellation fails
|
|
165
180
|
"""
|
|
166
181
|
try:
|
|
167
|
-
self.service.cancel(query_id)
|
|
182
|
+
self.service.cancel(query_id, preview=preview)
|
|
168
183
|
# Get updated status after cancellation
|
|
169
|
-
status = self.service.get_status(query_id)
|
|
184
|
+
status = self.service.get_status(query_id, preview=preview)
|
|
170
185
|
return self._format_query_status(status)
|
|
171
186
|
except Exception as e:
|
|
172
187
|
raise RuntimeError(f"Failed to cancel query: {e}")
|
|
173
188
|
|
|
174
189
|
def wait_for_completion(
|
|
175
|
-
self,
|
|
190
|
+
self,
|
|
191
|
+
query_id: str,
|
|
192
|
+
timeout: int = 300,
|
|
193
|
+
poll_interval: int = 2,
|
|
194
|
+
preview: bool = True,
|
|
176
195
|
) -> Dict[str, Any]:
|
|
177
196
|
"""
|
|
178
197
|
Wait for a query to complete.
|
|
@@ -181,6 +200,7 @@ class SqlService(BaseService):
|
|
|
181
200
|
query_id: Query identifier
|
|
182
201
|
timeout: Maximum time to wait (seconds)
|
|
183
202
|
poll_interval: Time between status checks (seconds)
|
|
203
|
+
preview: Enable preview mode (required for SQL API, defaults to True)
|
|
184
204
|
|
|
185
205
|
Returns:
|
|
186
206
|
Dictionary containing final query status
|
|
@@ -192,7 +212,7 @@ class SqlService(BaseService):
|
|
|
192
212
|
|
|
193
213
|
while time.time() - start_time < timeout:
|
|
194
214
|
try:
|
|
195
|
-
status = self.service.get_status(query_id)
|
|
215
|
+
status = self.service.get_status(query_id, preview=preview)
|
|
196
216
|
|
|
197
217
|
if isinstance(status, SucceededQueryStatus):
|
|
198
218
|
return self._format_query_status(status)
|
|
@@ -216,7 +236,7 @@ class SqlService(BaseService):
|
|
|
216
236
|
raise RuntimeError(f"Query timed out after {timeout} seconds")
|
|
217
237
|
|
|
218
238
|
def _wait_for_query_completion(
|
|
219
|
-
self, query_id: str, timeout: int, format: str
|
|
239
|
+
self, query_id: str, timeout: int, format: str, preview: bool = True
|
|
220
240
|
) -> Dict[str, Any]:
|
|
221
241
|
"""
|
|
222
242
|
Wait for query completion and return formatted results.
|
|
@@ -225,28 +245,32 @@ class SqlService(BaseService):
|
|
|
225
245
|
query_id: Query identifier
|
|
226
246
|
timeout: Maximum wait time
|
|
227
247
|
format: Result format
|
|
248
|
+
preview: Enable preview mode (required for SQL API, defaults to True)
|
|
228
249
|
|
|
229
250
|
Returns:
|
|
230
251
|
Dictionary with query results
|
|
231
252
|
"""
|
|
232
253
|
# Wait for completion
|
|
233
|
-
self.wait_for_completion(query_id, timeout)
|
|
254
|
+
self.wait_for_completion(query_id, timeout, preview=preview)
|
|
234
255
|
|
|
235
256
|
# Get results
|
|
236
|
-
return self._format_completed_query(query_id, format)
|
|
257
|
+
return self._format_completed_query(query_id, format, preview=preview)
|
|
237
258
|
|
|
238
|
-
def _format_completed_query(
|
|
259
|
+
def _format_completed_query(
|
|
260
|
+
self, query_id: str, format: str, preview: bool = True
|
|
261
|
+
) -> Dict[str, Any]:
|
|
239
262
|
"""
|
|
240
263
|
Format a completed query's results.
|
|
241
264
|
|
|
242
265
|
Args:
|
|
243
266
|
query_id: Query identifier
|
|
244
267
|
format: Result format
|
|
268
|
+
preview: Enable preview mode (required for SQL API, defaults to True)
|
|
245
269
|
|
|
246
270
|
Returns:
|
|
247
271
|
Formatted query results
|
|
248
272
|
"""
|
|
249
|
-
results_bytes = self.service.get_results(query_id)
|
|
273
|
+
results_bytes = self.service.get_results(query_id, preview=preview)
|
|
250
274
|
results = self._format_query_results(results_bytes, format)
|
|
251
275
|
|
|
252
276
|
return {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Third-party applications service wrapper for Foundry SDK.
|
|
3
|
+
Provides access to third-party application management operations.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Any, Dict
|
|
7
|
+
|
|
8
|
+
from .base import BaseService
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ThirdPartyApplicationsService(BaseService):
|
|
12
|
+
"""Service wrapper for Foundry third-party applications operations."""
|
|
13
|
+
|
|
14
|
+
def _get_service(self) -> Any:
|
|
15
|
+
"""Get the Foundry third-party applications service."""
|
|
16
|
+
return self.client.third_party_applications.ThirdPartyApplication
|
|
17
|
+
|
|
18
|
+
def get_application(
|
|
19
|
+
self, application_rid: str, preview: bool = False
|
|
20
|
+
) -> Dict[str, Any]:
|
|
21
|
+
"""
|
|
22
|
+
Get information about a specific third-party application.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
application_rid: Third-party application Resource Identifier
|
|
26
|
+
Expected format: ri.third-party-applications.<realm>.third-party-application.<locator>
|
|
27
|
+
Example: ri.third-party-applications.main.third-party-application.my-app-123
|
|
28
|
+
preview: Enable preview mode (default: False)
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
Third-party application information dictionary containing:
|
|
32
|
+
- rid: Application resource identifier
|
|
33
|
+
- name: Application name
|
|
34
|
+
- description: Application description (if available)
|
|
35
|
+
- status: Application status (if available)
|
|
36
|
+
|
|
37
|
+
Raises:
|
|
38
|
+
RuntimeError: If the operation fails
|
|
39
|
+
|
|
40
|
+
Example:
|
|
41
|
+
>>> service = ThirdPartyApplicationsService()
|
|
42
|
+
>>> app = service.get_application(
|
|
43
|
+
... "ri.third-party-applications.main.third-party-application.my-app"
|
|
44
|
+
... )
|
|
45
|
+
>>> print(app['name'])
|
|
46
|
+
"""
|
|
47
|
+
try:
|
|
48
|
+
application = self.service.get(application_rid, preview=preview)
|
|
49
|
+
return self._serialize_response(application)
|
|
50
|
+
except Exception as e:
|
|
51
|
+
raise RuntimeError(
|
|
52
|
+
f"Failed to get third-party application {application_rid}: {e}"
|
|
53
|
+
)
|