pltr-cli 0.11.0__py3-none-any.whl → 0.13.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.
Files changed (46) hide show
  1. pltr/__init__.py +1 -1
  2. pltr/cli.py +40 -0
  3. pltr/commands/admin.py +565 -11
  4. pltr/commands/aip_agents.py +333 -0
  5. pltr/commands/connectivity.py +309 -1
  6. pltr/commands/cp.py +103 -0
  7. pltr/commands/dataset.py +104 -4
  8. pltr/commands/functions.py +503 -0
  9. pltr/commands/language_models.py +515 -0
  10. pltr/commands/mediasets.py +176 -0
  11. pltr/commands/models.py +362 -0
  12. pltr/commands/ontology.py +44 -13
  13. pltr/commands/orchestration.py +167 -11
  14. pltr/commands/project.py +231 -22
  15. pltr/commands/resource.py +416 -17
  16. pltr/commands/space.py +25 -303
  17. pltr/commands/sql.py +54 -7
  18. pltr/commands/streams.py +616 -0
  19. pltr/commands/third_party_applications.py +82 -0
  20. pltr/services/admin.py +331 -3
  21. pltr/services/aip_agents.py +147 -0
  22. pltr/services/base.py +104 -1
  23. pltr/services/connectivity.py +139 -0
  24. pltr/services/copy.py +391 -0
  25. pltr/services/dataset.py +77 -4
  26. pltr/services/folder.py +6 -1
  27. pltr/services/functions.py +223 -0
  28. pltr/services/language_models.py +281 -0
  29. pltr/services/mediasets.py +144 -9
  30. pltr/services/models.py +179 -0
  31. pltr/services/ontology.py +48 -1
  32. pltr/services/orchestration.py +133 -1
  33. pltr/services/project.py +213 -39
  34. pltr/services/resource.py +229 -60
  35. pltr/services/space.py +24 -175
  36. pltr/services/sql.py +44 -20
  37. pltr/services/streams.py +290 -0
  38. pltr/services/third_party_applications.py +53 -0
  39. pltr/utils/formatting.py +195 -1
  40. pltr/utils/pagination.py +325 -0
  41. {pltr_cli-0.11.0.dist-info → pltr_cli-0.13.0.dist-info}/METADATA +55 -4
  42. pltr_cli-0.13.0.dist-info/RECORD +70 -0
  43. {pltr_cli-0.11.0.dist-info → pltr_cli-0.13.0.dist-info}/WHEEL +1 -1
  44. pltr_cli-0.11.0.dist-info/RECORD +0 -55
  45. {pltr_cli-0.11.0.dist-info → pltr_cli-0.13.0.dist-info}/entry_points.txt +0 -0
  46. {pltr_cli-0.11.0.dist-info → pltr_cli-0.13.0.dist-info}/licenses/LICENSE +0 -0
pltr/commands/project.py CHANGED
@@ -42,6 +42,16 @@ def create_project(
42
42
  "-org",
43
43
  help="Organization RIDs (can be specified multiple times)",
44
44
  ),
45
+ owner_id: Optional[str] = typer.Option(
46
+ None,
47
+ "--owner-id",
48
+ help="Owner principal id (user or group) for compass:manage",
49
+ ),
50
+ owner_type: str = typer.Option(
51
+ "USER",
52
+ "--owner-type",
53
+ help="Owner principal type (USER or GROUP)",
54
+ ),
45
55
  profile: Optional[str] = typer.Option(
46
56
  None, "--profile", help="Profile name", autocompletion=complete_profile
47
57
  ),
@@ -57,12 +67,23 @@ def create_project(
57
67
  try:
58
68
  service = ProjectService(profile=profile)
59
69
 
70
+ role_grants = None
71
+ if owner_id:
72
+ role_grants = [
73
+ {
74
+ "principal_id": owner_id,
75
+ "principal_type": owner_type,
76
+ "role_name": "compass:manage",
77
+ }
78
+ ]
79
+
60
80
  with SpinnerProgressTracker().track_spinner(f"Creating project '{name}'..."):
61
81
  project = service.create_project(
62
82
  display_name=name,
63
83
  space_rid=space_rid,
64
84
  description=description,
65
85
  organization_rids=organization_rids,
86
+ role_grants=role_grants,
66
87
  )
67
88
 
68
89
  # Cache the RID for future completions
@@ -305,10 +326,85 @@ def delete_project(
305
326
  raise typer.Exit(1)
306
327
 
307
328
 
308
- @app.command("batch-get")
309
- def get_projects_batch(
310
- project_rids: List[str] = typer.Argument(
311
- ..., help="Project Resource Identifiers (space-separated)"
329
+ # ==================== Organization Operations ====================
330
+
331
+
332
+ @app.command("add-orgs")
333
+ def add_organizations(
334
+ project_rid: str = typer.Argument(
335
+ ..., help="Project Resource Identifier", autocompletion=complete_rid
336
+ ),
337
+ organization_rids: List[str] = typer.Option(
338
+ ...,
339
+ "--org",
340
+ "-o",
341
+ help="Organization RID(s) to add (can specify multiple)",
342
+ ),
343
+ profile: Optional[str] = typer.Option(
344
+ None, "--profile", help="Profile name", autocompletion=complete_profile
345
+ ),
346
+ ):
347
+ """Add organizations to a project."""
348
+ try:
349
+ service = ProjectService(profile=profile)
350
+
351
+ with SpinnerProgressTracker().track_spinner(
352
+ f"Adding {len(organization_rids)} organization(s) to project {project_rid}..."
353
+ ):
354
+ service.add_organizations(project_rid, organization_rids)
355
+
356
+ formatter.print_success(
357
+ f"Successfully added {len(organization_rids)} organization(s) to project {project_rid}"
358
+ )
359
+
360
+ except (ProfileNotFoundError, MissingCredentialsError) as e:
361
+ formatter.print_error(f"Authentication error: {e}")
362
+ raise typer.Exit(1)
363
+ except Exception as e:
364
+ formatter.print_error(f"Failed to add organizations: {e}")
365
+ raise typer.Exit(1)
366
+
367
+
368
+ @app.command("remove-orgs")
369
+ def remove_organizations(
370
+ project_rid: str = typer.Argument(
371
+ ..., help="Project Resource Identifier", autocompletion=complete_rid
372
+ ),
373
+ organization_rids: List[str] = typer.Option(
374
+ ...,
375
+ "--org",
376
+ "-o",
377
+ help="Organization RID(s) to remove (can specify multiple)",
378
+ ),
379
+ profile: Optional[str] = typer.Option(
380
+ None, "--profile", help="Profile name", autocompletion=complete_profile
381
+ ),
382
+ ):
383
+ """Remove organizations from a project."""
384
+ try:
385
+ service = ProjectService(profile=profile)
386
+
387
+ with SpinnerProgressTracker().track_spinner(
388
+ f"Removing {len(organization_rids)} organization(s) from project {project_rid}..."
389
+ ):
390
+ service.remove_organizations(project_rid, organization_rids)
391
+
392
+ formatter.print_success(
393
+ f"Successfully removed {len(organization_rids)} organization(s) from project {project_rid}"
394
+ )
395
+
396
+ except (ProfileNotFoundError, MissingCredentialsError) as e:
397
+ formatter.print_error(f"Authentication error: {e}")
398
+ raise typer.Exit(1)
399
+ except Exception as e:
400
+ formatter.print_error(f"Failed to remove organizations: {e}")
401
+ raise typer.Exit(1)
402
+
403
+
404
+ @app.command("list-orgs")
405
+ def list_organizations(
406
+ project_rid: str = typer.Argument(
407
+ ..., help="Project Resource Identifier", autocompletion=complete_rid
312
408
  ),
313
409
  profile: Optional[str] = typer.Option(
314
410
  None, "--profile", help="Profile name", autocompletion=complete_profile
@@ -320,49 +416,136 @@ def get_projects_batch(
320
416
  help="Output format (table, json, csv)",
321
417
  autocompletion=complete_output_format,
322
418
  ),
323
- output: Optional[str] = typer.Option(
324
- None, "--output", "-o", help="Output file path"
419
+ output: Optional[str] = typer.Option(None, "--output", help="Output file path"),
420
+ page_size: Optional[int] = typer.Option(
421
+ None, "--page-size", help="Number of items per page"
325
422
  ),
326
423
  ):
327
- """Get multiple projects in a single request (max 1000)."""
424
+ """List organizations directly applied to a project."""
328
425
  try:
329
426
  service = ProjectService(profile=profile)
330
427
 
331
428
  with SpinnerProgressTracker().track_spinner(
332
- f"Fetching {len(project_rids)} projects..."
429
+ f"Fetching organizations for project {project_rid}..."
333
430
  ):
334
- projects = service.get_projects_batch(project_rids)
431
+ organizations = service.list_organizations(project_rid, page_size=page_size)
335
432
 
336
- # Cache RIDs for future completions
337
- for project in projects:
338
- if project.get("rid"):
339
- cache_rid(project["rid"])
433
+ if not organizations:
434
+ formatter.print_info("No organizations found on this project.")
435
+ return
340
436
 
341
437
  # Format output
342
438
  if format == "json":
343
439
  if output:
344
- formatter.save_to_file(projects, output, "json")
440
+ formatter.save_to_file(organizations, output, "json")
345
441
  else:
346
- formatter.format_list(projects)
442
+ formatter.format_list(organizations)
347
443
  elif format == "csv":
348
444
  if output:
349
- formatter.save_to_file(projects, output, "csv")
445
+ formatter.save_to_file(organizations, output, "csv")
350
446
  else:
351
- formatter.format_list(projects)
447
+ formatter.format_list(organizations)
352
448
  else:
353
- _format_projects_table(projects)
449
+ _format_organizations_table(organizations)
354
450
 
355
451
  if output:
356
- formatter.print_success(f"Projects information saved to {output}")
452
+ formatter.print_success(f"Organizations list saved to {output}")
357
453
 
358
454
  except (ProfileNotFoundError, MissingCredentialsError) as e:
359
455
  formatter.print_error(f"Authentication error: {e}")
360
456
  raise typer.Exit(1)
361
- except ValueError as e:
362
- formatter.print_error(f"Invalid request: {e}")
457
+ except Exception as e:
458
+ formatter.print_error(f"Failed to list organizations: {e}")
459
+ raise typer.Exit(1)
460
+
461
+
462
+ # ==================== Template Operations ====================
463
+
464
+
465
+ @app.command("create-from-template")
466
+ def create_from_template(
467
+ template_rid: str = typer.Option(
468
+ ...,
469
+ "--template-rid",
470
+ "-t",
471
+ help="Template Resource Identifier",
472
+ autocompletion=complete_rid,
473
+ ),
474
+ variable: List[str] = typer.Option(
475
+ ...,
476
+ "--var",
477
+ "-v",
478
+ help="Variable values in format 'name=value' (can specify multiple)",
479
+ ),
480
+ description: Optional[str] = typer.Option(
481
+ None, "--description", "-d", help="Project description"
482
+ ),
483
+ organization_rids: Optional[List[str]] = typer.Option(
484
+ None,
485
+ "--org",
486
+ "-o",
487
+ help="Organization RIDs (can be specified multiple times)",
488
+ ),
489
+ profile: Optional[str] = typer.Option(
490
+ None, "--profile", help="Profile name", autocompletion=complete_profile
491
+ ),
492
+ format: str = typer.Option(
493
+ "table",
494
+ "--format",
495
+ "-f",
496
+ help="Output format (table, json, csv)",
497
+ autocompletion=complete_output_format,
498
+ ),
499
+ ):
500
+ """Create a project from a template."""
501
+ try:
502
+ # Parse variable values
503
+ variable_values = {}
504
+ for var in variable:
505
+ if "=" not in var:
506
+ formatter.print_error(
507
+ f"Invalid variable format: '{var}'. Use 'name=value' format."
508
+ )
509
+ raise typer.Exit(1)
510
+ name, value = var.split("=", 1)
511
+ name = name.strip()
512
+ if not name:
513
+ formatter.print_error(f"Variable name cannot be empty: '{var}'")
514
+ raise typer.Exit(1)
515
+ variable_values[name] = value
516
+
517
+ service = ProjectService(profile=profile)
518
+
519
+ with SpinnerProgressTracker().track_spinner(
520
+ f"Creating project from template {template_rid}..."
521
+ ):
522
+ project = service.create_project_from_template(
523
+ template_rid=template_rid,
524
+ variable_values=variable_values,
525
+ organization_rids=organization_rids,
526
+ project_description=description,
527
+ )
528
+
529
+ # Cache the RID for future completions
530
+ if project.get("rid"):
531
+ cache_rid(project["rid"])
532
+
533
+ formatter.print_success("Successfully created project from template")
534
+ formatter.print_info(f"Project RID: {project.get('rid', 'unknown')}")
535
+
536
+ # Format output
537
+ if format == "json":
538
+ formatter.format_dict(project)
539
+ elif format == "csv":
540
+ formatter.format_list([project])
541
+ else:
542
+ _format_project_table(project)
543
+
544
+ except (ProfileNotFoundError, MissingCredentialsError) as e:
545
+ formatter.print_error(f"Authentication error: {e}")
363
546
  raise typer.Exit(1)
364
547
  except Exception as e:
365
- formatter.print_error(f"Failed to get projects batch: {e}")
548
+ formatter.print_error(f"Failed to create project from template: {e}")
366
549
  raise typer.Exit(1)
367
550
 
368
551
 
@@ -410,6 +593,24 @@ def _format_projects_table(projects: List[dict]):
410
593
  console.print(f"\nTotal: {len(projects)} projects")
411
594
 
412
595
 
596
+ def _format_organizations_table(organizations: List[dict]):
597
+ """Format organizations as a table."""
598
+ table = Table(title="Organizations", show_header=True, header_style="bold cyan")
599
+ table.add_column("Organization RID")
600
+ table.add_column("Display Name")
601
+ table.add_column("Description")
602
+
603
+ for org in organizations:
604
+ table.add_row(
605
+ org.get("organization_rid", "N/A"),
606
+ org.get("display_name", "N/A"),
607
+ org.get("description", "N/A"),
608
+ )
609
+
610
+ console.print(table)
611
+ console.print(f"\nTotal: {len(organizations)} organizations")
612
+
613
+
413
614
  @app.callback()
414
615
  def main():
415
616
  """
@@ -436,5 +637,13 @@ def main():
436
637
 
437
638
  # Delete project
438
639
  pltr project delete ri.compass.main.project.abc456
640
+
641
+ # Organization operations
642
+ pltr project add-orgs ri.compass.main.project.abc456 -o org-rid-1 -o org-rid-2
643
+ pltr project remove-orgs ri.compass.main.project.abc456 -o org-rid-1
644
+ pltr project list-orgs ri.compass.main.project.abc456
645
+
646
+ # Create from template
647
+ pltr project create-from-template -t template-rid -v "name=MyProject" -v "desc=Description"
439
648
  """
440
649
  pass