pltr-cli 0.11.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 +44 -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 +75 -1
- pltr/services/mediasets.py +144 -9
- pltr/services/ontology.py +48 -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.11.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.11.0.dist-info → pltr_cli-0.12.0.dist-info}/WHEEL +1 -1
- pltr_cli-0.11.0.dist-info/RECORD +0 -55
- {pltr_cli-0.11.0.dist-info → pltr_cli-0.12.0.dist-info}/entry_points.txt +0 -0
- {pltr_cli-0.11.0.dist-info → pltr_cli-0.12.0.dist-info}/licenses/LICENSE +0 -0
pltr/commands/resource.py
CHANGED
|
@@ -459,6 +459,378 @@ def move_resource(
|
|
|
459
459
|
raise typer.Exit(1)
|
|
460
460
|
|
|
461
461
|
|
|
462
|
+
# ==================== Trash Operations ====================
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
@app.command("delete")
|
|
466
|
+
def delete_resource(
|
|
467
|
+
resource_rid: str = typer.Argument(
|
|
468
|
+
..., help="Resource Identifier", autocompletion=complete_rid
|
|
469
|
+
),
|
|
470
|
+
profile: Optional[str] = typer.Option(
|
|
471
|
+
None, "--profile", help="Profile name", autocompletion=complete_profile
|
|
472
|
+
),
|
|
473
|
+
force: bool = typer.Option(False, "--force", "-f", help="Skip confirmation prompt"),
|
|
474
|
+
):
|
|
475
|
+
"""Move a resource to trash."""
|
|
476
|
+
try:
|
|
477
|
+
if not force:
|
|
478
|
+
confirm = typer.confirm(
|
|
479
|
+
f"Are you sure you want to move resource {resource_rid} to trash?"
|
|
480
|
+
)
|
|
481
|
+
if not confirm:
|
|
482
|
+
formatter.print_info("Operation cancelled.")
|
|
483
|
+
return
|
|
484
|
+
|
|
485
|
+
service = ResourceService(profile=profile)
|
|
486
|
+
|
|
487
|
+
with SpinnerProgressTracker().track_spinner(
|
|
488
|
+
f"Moving resource {resource_rid} to trash..."
|
|
489
|
+
):
|
|
490
|
+
service.delete_resource(resource_rid)
|
|
491
|
+
|
|
492
|
+
formatter.print_success(f"Successfully moved resource {resource_rid} to trash")
|
|
493
|
+
|
|
494
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
495
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
496
|
+
raise typer.Exit(1)
|
|
497
|
+
except Exception as e:
|
|
498
|
+
formatter.print_error(f"Failed to delete resource: {e}")
|
|
499
|
+
raise typer.Exit(1)
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
@app.command("restore")
|
|
503
|
+
def restore_resource(
|
|
504
|
+
resource_rid: str = typer.Argument(
|
|
505
|
+
..., help="Resource Identifier", autocompletion=complete_rid
|
|
506
|
+
),
|
|
507
|
+
profile: Optional[str] = typer.Option(
|
|
508
|
+
None, "--profile", help="Profile name", autocompletion=complete_profile
|
|
509
|
+
),
|
|
510
|
+
):
|
|
511
|
+
"""Restore a resource from trash."""
|
|
512
|
+
try:
|
|
513
|
+
service = ResourceService(profile=profile)
|
|
514
|
+
|
|
515
|
+
with SpinnerProgressTracker().track_spinner(
|
|
516
|
+
f"Restoring resource {resource_rid} from trash..."
|
|
517
|
+
):
|
|
518
|
+
service.restore_resource(resource_rid)
|
|
519
|
+
|
|
520
|
+
formatter.print_success(
|
|
521
|
+
f"Successfully restored resource {resource_rid} from trash"
|
|
522
|
+
)
|
|
523
|
+
|
|
524
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
525
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
526
|
+
raise typer.Exit(1)
|
|
527
|
+
except Exception as e:
|
|
528
|
+
formatter.print_error(f"Failed to restore resource: {e}")
|
|
529
|
+
raise typer.Exit(1)
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
@app.command("permanently-delete")
|
|
533
|
+
def permanently_delete_resource(
|
|
534
|
+
resource_rid: str = typer.Argument(
|
|
535
|
+
..., help="Resource Identifier", autocompletion=complete_rid
|
|
536
|
+
),
|
|
537
|
+
profile: Optional[str] = typer.Option(
|
|
538
|
+
None, "--profile", help="Profile name", autocompletion=complete_profile
|
|
539
|
+
),
|
|
540
|
+
force: bool = typer.Option(False, "--force", "-f", help="Skip confirmation prompt"),
|
|
541
|
+
):
|
|
542
|
+
"""Permanently delete a resource from trash. This action is irreversible."""
|
|
543
|
+
try:
|
|
544
|
+
if not force:
|
|
545
|
+
confirm = typer.confirm(
|
|
546
|
+
f"Are you sure you want to PERMANENTLY delete resource {resource_rid}? "
|
|
547
|
+
"This action cannot be undone!"
|
|
548
|
+
)
|
|
549
|
+
if not confirm:
|
|
550
|
+
formatter.print_info("Operation cancelled.")
|
|
551
|
+
return
|
|
552
|
+
|
|
553
|
+
service = ResourceService(profile=profile)
|
|
554
|
+
|
|
555
|
+
with SpinnerProgressTracker().track_spinner(
|
|
556
|
+
f"Permanently deleting resource {resource_rid}..."
|
|
557
|
+
):
|
|
558
|
+
service.permanently_delete_resource(resource_rid)
|
|
559
|
+
|
|
560
|
+
formatter.print_success(
|
|
561
|
+
f"Successfully permanently deleted resource {resource_rid}"
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
565
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
566
|
+
raise typer.Exit(1)
|
|
567
|
+
except Exception as e:
|
|
568
|
+
formatter.print_error(f"Failed to permanently delete resource: {e}")
|
|
569
|
+
raise typer.Exit(1)
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
# ==================== Markings Operations ====================
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
@app.command("add-markings")
|
|
576
|
+
def add_markings(
|
|
577
|
+
resource_rid: str = typer.Argument(
|
|
578
|
+
..., help="Resource Identifier", autocompletion=complete_rid
|
|
579
|
+
),
|
|
580
|
+
marking_ids: List[str] = typer.Option(
|
|
581
|
+
...,
|
|
582
|
+
"--marking",
|
|
583
|
+
"-m",
|
|
584
|
+
help="Marking identifier(s) to add (can specify multiple)",
|
|
585
|
+
),
|
|
586
|
+
profile: Optional[str] = typer.Option(
|
|
587
|
+
None, "--profile", help="Profile name", autocompletion=complete_profile
|
|
588
|
+
),
|
|
589
|
+
):
|
|
590
|
+
"""Add markings to a resource."""
|
|
591
|
+
try:
|
|
592
|
+
service = ResourceService(profile=profile)
|
|
593
|
+
|
|
594
|
+
with SpinnerProgressTracker().track_spinner(
|
|
595
|
+
f"Adding {len(marking_ids)} marking(s) to resource {resource_rid}..."
|
|
596
|
+
):
|
|
597
|
+
service.add_markings(resource_rid, marking_ids)
|
|
598
|
+
|
|
599
|
+
formatter.print_success(
|
|
600
|
+
f"Successfully added {len(marking_ids)} marking(s) to resource {resource_rid}"
|
|
601
|
+
)
|
|
602
|
+
|
|
603
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
604
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
605
|
+
raise typer.Exit(1)
|
|
606
|
+
except Exception as e:
|
|
607
|
+
formatter.print_error(f"Failed to add markings: {e}")
|
|
608
|
+
raise typer.Exit(1)
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
@app.command("remove-markings")
|
|
612
|
+
def remove_markings(
|
|
613
|
+
resource_rid: str = typer.Argument(
|
|
614
|
+
..., help="Resource Identifier", autocompletion=complete_rid
|
|
615
|
+
),
|
|
616
|
+
marking_ids: List[str] = typer.Option(
|
|
617
|
+
...,
|
|
618
|
+
"--marking",
|
|
619
|
+
"-m",
|
|
620
|
+
help="Marking identifier(s) to remove (can specify multiple)",
|
|
621
|
+
),
|
|
622
|
+
profile: Optional[str] = typer.Option(
|
|
623
|
+
None, "--profile", help="Profile name", autocompletion=complete_profile
|
|
624
|
+
),
|
|
625
|
+
):
|
|
626
|
+
"""Remove markings from a resource."""
|
|
627
|
+
try:
|
|
628
|
+
service = ResourceService(profile=profile)
|
|
629
|
+
|
|
630
|
+
with SpinnerProgressTracker().track_spinner(
|
|
631
|
+
f"Removing {len(marking_ids)} marking(s) from resource {resource_rid}..."
|
|
632
|
+
):
|
|
633
|
+
service.remove_markings(resource_rid, marking_ids)
|
|
634
|
+
|
|
635
|
+
formatter.print_success(
|
|
636
|
+
f"Successfully removed {len(marking_ids)} marking(s) from resource {resource_rid}"
|
|
637
|
+
)
|
|
638
|
+
|
|
639
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
640
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
641
|
+
raise typer.Exit(1)
|
|
642
|
+
except Exception as e:
|
|
643
|
+
formatter.print_error(f"Failed to remove markings: {e}")
|
|
644
|
+
raise typer.Exit(1)
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
@app.command("list-markings")
|
|
648
|
+
def list_markings(
|
|
649
|
+
resource_rid: str = typer.Argument(
|
|
650
|
+
..., help="Resource Identifier", autocompletion=complete_rid
|
|
651
|
+
),
|
|
652
|
+
profile: Optional[str] = typer.Option(
|
|
653
|
+
None, "--profile", help="Profile name", autocompletion=complete_profile
|
|
654
|
+
),
|
|
655
|
+
format: str = typer.Option(
|
|
656
|
+
"table",
|
|
657
|
+
"--format",
|
|
658
|
+
"-f",
|
|
659
|
+
help="Output format (table, json, csv)",
|
|
660
|
+
autocompletion=complete_output_format,
|
|
661
|
+
),
|
|
662
|
+
output: Optional[str] = typer.Option(
|
|
663
|
+
None, "--output", "-o", help="Output file path"
|
|
664
|
+
),
|
|
665
|
+
page_size: Optional[int] = typer.Option(
|
|
666
|
+
None, "--page-size", help="Number of items per page"
|
|
667
|
+
),
|
|
668
|
+
):
|
|
669
|
+
"""List markings directly applied to a resource."""
|
|
670
|
+
try:
|
|
671
|
+
service = ResourceService(profile=profile)
|
|
672
|
+
|
|
673
|
+
with SpinnerProgressTracker().track_spinner(
|
|
674
|
+
f"Fetching markings for resource {resource_rid}..."
|
|
675
|
+
):
|
|
676
|
+
markings = service.list_markings(resource_rid, page_size=page_size)
|
|
677
|
+
|
|
678
|
+
if not markings:
|
|
679
|
+
formatter.print_info("No markings found on this resource.")
|
|
680
|
+
return
|
|
681
|
+
|
|
682
|
+
# Format output
|
|
683
|
+
if format == "json":
|
|
684
|
+
if output:
|
|
685
|
+
formatter.save_to_file(markings, output, "json")
|
|
686
|
+
else:
|
|
687
|
+
formatter.format_list(markings)
|
|
688
|
+
elif format == "csv":
|
|
689
|
+
if output:
|
|
690
|
+
formatter.save_to_file(markings, output, "csv")
|
|
691
|
+
else:
|
|
692
|
+
formatter.format_list(markings)
|
|
693
|
+
else:
|
|
694
|
+
_format_markings_table(markings)
|
|
695
|
+
|
|
696
|
+
if output:
|
|
697
|
+
formatter.print_success(f"Markings list saved to {output}")
|
|
698
|
+
|
|
699
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
700
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
701
|
+
raise typer.Exit(1)
|
|
702
|
+
except Exception as e:
|
|
703
|
+
formatter.print_error(f"Failed to list markings: {e}")
|
|
704
|
+
raise typer.Exit(1)
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
# ==================== Access & Batch Operations ====================
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
@app.command("access-requirements")
|
|
711
|
+
def get_access_requirements(
|
|
712
|
+
resource_rid: str = typer.Argument(
|
|
713
|
+
..., help="Resource Identifier", autocompletion=complete_rid
|
|
714
|
+
),
|
|
715
|
+
profile: Optional[str] = typer.Option(
|
|
716
|
+
None, "--profile", help="Profile name", autocompletion=complete_profile
|
|
717
|
+
),
|
|
718
|
+
format: str = typer.Option(
|
|
719
|
+
"table",
|
|
720
|
+
"--format",
|
|
721
|
+
"-f",
|
|
722
|
+
help="Output format (table, json, csv)",
|
|
723
|
+
autocompletion=complete_output_format,
|
|
724
|
+
),
|
|
725
|
+
output: Optional[str] = typer.Option(
|
|
726
|
+
None, "--output", "-o", help="Output file path"
|
|
727
|
+
),
|
|
728
|
+
):
|
|
729
|
+
"""Get access requirements (organizations and markings) for a resource."""
|
|
730
|
+
try:
|
|
731
|
+
service = ResourceService(profile=profile)
|
|
732
|
+
|
|
733
|
+
with SpinnerProgressTracker().track_spinner(
|
|
734
|
+
f"Fetching access requirements for resource {resource_rid}..."
|
|
735
|
+
):
|
|
736
|
+
requirements = service.get_access_requirements(resource_rid)
|
|
737
|
+
|
|
738
|
+
# Format output
|
|
739
|
+
if format == "json":
|
|
740
|
+
if output:
|
|
741
|
+
formatter.save_to_file(requirements, output, "json")
|
|
742
|
+
else:
|
|
743
|
+
formatter.format_dict(requirements)
|
|
744
|
+
elif format == "csv":
|
|
745
|
+
# Flatten for CSV output
|
|
746
|
+
flat_data = []
|
|
747
|
+
for org in requirements.get("organizations", []):
|
|
748
|
+
flat_data.append({"type": "organization", **org})
|
|
749
|
+
for marking in requirements.get("markings", []):
|
|
750
|
+
flat_data.append({"type": "marking", **marking})
|
|
751
|
+
if output:
|
|
752
|
+
formatter.save_to_file(flat_data, output, "csv")
|
|
753
|
+
else:
|
|
754
|
+
formatter.format_list(flat_data)
|
|
755
|
+
else:
|
|
756
|
+
_format_access_requirements_table(requirements)
|
|
757
|
+
|
|
758
|
+
if output:
|
|
759
|
+
formatter.print_success(f"Access requirements saved to {output}")
|
|
760
|
+
|
|
761
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
762
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
763
|
+
raise typer.Exit(1)
|
|
764
|
+
except Exception as e:
|
|
765
|
+
formatter.print_error(f"Failed to get access requirements: {e}")
|
|
766
|
+
raise typer.Exit(1)
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
@app.command("batch-get-by-path")
|
|
770
|
+
def get_resources_by_path_batch(
|
|
771
|
+
paths: List[str] = typer.Argument(
|
|
772
|
+
..., help="Absolute paths to resources (space-separated)"
|
|
773
|
+
),
|
|
774
|
+
profile: Optional[str] = typer.Option(
|
|
775
|
+
None, "--profile", help="Profile name", autocompletion=complete_profile
|
|
776
|
+
),
|
|
777
|
+
format: str = typer.Option(
|
|
778
|
+
"table",
|
|
779
|
+
"--format",
|
|
780
|
+
"-f",
|
|
781
|
+
help="Output format (table, json, csv)",
|
|
782
|
+
autocompletion=complete_output_format,
|
|
783
|
+
),
|
|
784
|
+
output: Optional[str] = typer.Option(
|
|
785
|
+
None, "--output", "-o", help="Output file path"
|
|
786
|
+
),
|
|
787
|
+
):
|
|
788
|
+
"""Get multiple resources by their absolute paths (max 1000)."""
|
|
789
|
+
try:
|
|
790
|
+
if len(paths) > 1000:
|
|
791
|
+
formatter.print_error("Maximum batch size is 1000 paths")
|
|
792
|
+
raise typer.Exit(1)
|
|
793
|
+
|
|
794
|
+
service = ResourceService(profile=profile)
|
|
795
|
+
|
|
796
|
+
with SpinnerProgressTracker().track_spinner(
|
|
797
|
+
f"Fetching {len(paths)} resources by path..."
|
|
798
|
+
):
|
|
799
|
+
resources = service.get_resources_by_path_batch(paths)
|
|
800
|
+
|
|
801
|
+
# Cache RIDs for future completions
|
|
802
|
+
for resource in resources:
|
|
803
|
+
if resource.get("rid"):
|
|
804
|
+
cache_rid(resource["rid"])
|
|
805
|
+
|
|
806
|
+
# Format output
|
|
807
|
+
if format == "json":
|
|
808
|
+
if output:
|
|
809
|
+
formatter.save_to_file(resources, output, "json")
|
|
810
|
+
else:
|
|
811
|
+
formatter.format_list(resources)
|
|
812
|
+
elif format == "csv":
|
|
813
|
+
if output:
|
|
814
|
+
formatter.save_to_file(resources, output, "csv")
|
|
815
|
+
else:
|
|
816
|
+
formatter.format_list(resources)
|
|
817
|
+
else:
|
|
818
|
+
_format_resources_table(resources)
|
|
819
|
+
|
|
820
|
+
if output:
|
|
821
|
+
formatter.print_success(f"Resources information saved to {output}")
|
|
822
|
+
|
|
823
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
824
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
825
|
+
raise typer.Exit(1)
|
|
826
|
+
except ValueError as e:
|
|
827
|
+
formatter.print_error(f"Invalid request: {e}")
|
|
828
|
+
raise typer.Exit(1)
|
|
829
|
+
except Exception as e:
|
|
830
|
+
formatter.print_error(f"Failed to get resources by path batch: {e}")
|
|
831
|
+
raise typer.Exit(1)
|
|
832
|
+
|
|
833
|
+
|
|
462
834
|
def _format_resource_table(resource: dict):
|
|
463
835
|
"""Format resource information as a table."""
|
|
464
836
|
table = Table(
|
|
@@ -520,6 +892,70 @@ def _format_metadata_table(metadata: dict):
|
|
|
520
892
|
console.print(table)
|
|
521
893
|
|
|
522
894
|
|
|
895
|
+
def _format_markings_table(markings: List[dict]):
|
|
896
|
+
"""Format markings as a table."""
|
|
897
|
+
table = Table(title="Markings", show_header=True, header_style="bold cyan")
|
|
898
|
+
table.add_column("Marking ID")
|
|
899
|
+
table.add_column("Display Name")
|
|
900
|
+
table.add_column("Category")
|
|
901
|
+
table.add_column("Description")
|
|
902
|
+
|
|
903
|
+
for marking in markings:
|
|
904
|
+
table.add_row(
|
|
905
|
+
marking.get("marking_id", "N/A"),
|
|
906
|
+
marking.get("display_name", "N/A"),
|
|
907
|
+
marking.get("category_display_name", "N/A"),
|
|
908
|
+
marking.get("description", "N/A"),
|
|
909
|
+
)
|
|
910
|
+
|
|
911
|
+
console.print(table)
|
|
912
|
+
console.print(f"\nTotal: {len(markings)} markings")
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
def _format_access_requirements_table(requirements: dict):
|
|
916
|
+
"""Format access requirements as tables."""
|
|
917
|
+
organizations = requirements.get("organizations", [])
|
|
918
|
+
markings = requirements.get("markings", [])
|
|
919
|
+
|
|
920
|
+
if organizations:
|
|
921
|
+
org_table = Table(
|
|
922
|
+
title="Required Organizations", show_header=True, header_style="bold cyan"
|
|
923
|
+
)
|
|
924
|
+
org_table.add_column("Organization RID")
|
|
925
|
+
org_table.add_column("Display Name")
|
|
926
|
+
|
|
927
|
+
for org in organizations:
|
|
928
|
+
org_table.add_row(
|
|
929
|
+
org.get("organization_rid", "N/A"),
|
|
930
|
+
org.get("display_name", "N/A"),
|
|
931
|
+
)
|
|
932
|
+
|
|
933
|
+
console.print(org_table)
|
|
934
|
+
console.print(f"Total: {len(organizations)} organizations\n")
|
|
935
|
+
else:
|
|
936
|
+
console.print("[dim]No organization requirements[/dim]\n")
|
|
937
|
+
|
|
938
|
+
if markings:
|
|
939
|
+
marking_table = Table(
|
|
940
|
+
title="Required Markings", show_header=True, header_style="bold cyan"
|
|
941
|
+
)
|
|
942
|
+
marking_table.add_column("Marking ID")
|
|
943
|
+
marking_table.add_column("Display Name")
|
|
944
|
+
marking_table.add_column("Category")
|
|
945
|
+
|
|
946
|
+
for marking in markings:
|
|
947
|
+
marking_table.add_row(
|
|
948
|
+
marking.get("marking_id", "N/A"),
|
|
949
|
+
marking.get("display_name", "N/A"),
|
|
950
|
+
marking.get("category_display_name", "N/A"),
|
|
951
|
+
)
|
|
952
|
+
|
|
953
|
+
console.print(marking_table)
|
|
954
|
+
console.print(f"Total: {len(markings)} markings")
|
|
955
|
+
else:
|
|
956
|
+
console.print("[dim]No marking requirements[/dim]")
|
|
957
|
+
|
|
958
|
+
|
|
523
959
|
@app.callback()
|
|
524
960
|
def main():
|
|
525
961
|
"""
|
|
@@ -556,5 +992,21 @@ def main():
|
|
|
556
992
|
|
|
557
993
|
# Move resource to different folder
|
|
558
994
|
pltr resource move ri.compass.main.dataset.xyz123 --target-folder ri.compass.main.folder.new456
|
|
995
|
+
|
|
996
|
+
# Trash operations
|
|
997
|
+
pltr resource delete ri.compass.main.dataset.xyz123
|
|
998
|
+
pltr resource restore ri.compass.main.dataset.xyz123
|
|
999
|
+
pltr resource permanently-delete ri.compass.main.dataset.xyz123
|
|
1000
|
+
|
|
1001
|
+
# Markings operations
|
|
1002
|
+
pltr resource add-markings ri.compass.main.dataset.xyz123 -m marking-id-1 -m marking-id-2
|
|
1003
|
+
pltr resource remove-markings ri.compass.main.dataset.xyz123 -m marking-id-1
|
|
1004
|
+
pltr resource list-markings ri.compass.main.dataset.xyz123
|
|
1005
|
+
|
|
1006
|
+
# Access requirements
|
|
1007
|
+
pltr resource access-requirements ri.compass.main.dataset.xyz123
|
|
1008
|
+
|
|
1009
|
+
# Batch get by path
|
|
1010
|
+
pltr resource batch-get-by-path "/Org/Project/Dataset1" "/Org/Project/Dataset2"
|
|
559
1011
|
"""
|
|
560
1012
|
pass
|
pltr/commands/sql.py
CHANGED
|
@@ -42,8 +42,15 @@ def execute_query(
|
|
|
42
42
|
fallback_branches: Optional[str] = typer.Option(
|
|
43
43
|
None, "--fallback-branches", help="Comma-separated list of fallback branch IDs"
|
|
44
44
|
),
|
|
45
|
+
preview: bool = typer.Option(
|
|
46
|
+
True,
|
|
47
|
+
"--preview/--no-preview",
|
|
48
|
+
help="Enable preview mode (required for SQL API)",
|
|
49
|
+
),
|
|
45
50
|
) -> None:
|
|
46
|
-
"""Execute a SQL query and display results.
|
|
51
|
+
"""Execute a SQL query and display results.
|
|
52
|
+
|
|
53
|
+
Note: SQL queries are currently in preview and may be modified or removed at any time."""
|
|
47
54
|
console = Console()
|
|
48
55
|
formatter = OutputFormatter()
|
|
49
56
|
|
|
@@ -62,6 +69,7 @@ def execute_query(
|
|
|
62
69
|
fallback_branch_ids=fallback_branch_ids,
|
|
63
70
|
timeout=timeout,
|
|
64
71
|
format="table" if output_format in ["table", "csv"] else "json",
|
|
72
|
+
preview=preview,
|
|
65
73
|
)
|
|
66
74
|
|
|
67
75
|
# Extract results
|
|
@@ -92,8 +100,15 @@ def submit_query(
|
|
|
92
100
|
fallback_branches: Optional[str] = typer.Option(
|
|
93
101
|
None, "--fallback-branches", help="Comma-separated list of fallback branch IDs"
|
|
94
102
|
),
|
|
103
|
+
preview: bool = typer.Option(
|
|
104
|
+
True,
|
|
105
|
+
"--preview/--no-preview",
|
|
106
|
+
help="Enable preview mode (required for SQL API)",
|
|
107
|
+
),
|
|
95
108
|
) -> None:
|
|
96
|
-
"""Submit a SQL query without waiting for completion.
|
|
109
|
+
"""Submit a SQL query without waiting for completion.
|
|
110
|
+
|
|
111
|
+
Note: SQL queries are currently in preview and may be modified or removed at any time."""
|
|
97
112
|
console = Console()
|
|
98
113
|
formatter = OutputFormatter()
|
|
99
114
|
|
|
@@ -108,7 +123,7 @@ def submit_query(
|
|
|
108
123
|
|
|
109
124
|
with SpinnerProgressTracker().track_spinner("Submitting SQL query..."):
|
|
110
125
|
result = service.submit_query(
|
|
111
|
-
query=query, fallback_branch_ids=fallback_branch_ids
|
|
126
|
+
query=query, fallback_branch_ids=fallback_branch_ids, preview=preview
|
|
112
127
|
)
|
|
113
128
|
|
|
114
129
|
console.print("[green]Query submitted successfully[/green]")
|
|
@@ -136,6 +151,11 @@ def get_query_status(
|
|
|
136
151
|
profile: Optional[str] = typer.Option(
|
|
137
152
|
None, "--profile", help="Auth profile to use"
|
|
138
153
|
),
|
|
154
|
+
preview: bool = typer.Option(
|
|
155
|
+
True,
|
|
156
|
+
"--preview/--no-preview",
|
|
157
|
+
help="Enable preview mode (required for SQL API)",
|
|
158
|
+
),
|
|
139
159
|
) -> None:
|
|
140
160
|
"""Get the status of a submitted query."""
|
|
141
161
|
console = Console()
|
|
@@ -145,7 +165,7 @@ def get_query_status(
|
|
|
145
165
|
service = SqlService(profile=profile)
|
|
146
166
|
|
|
147
167
|
with SpinnerProgressTracker().track_spinner("Checking query status..."):
|
|
148
|
-
result = service.get_query_status(query_id)
|
|
168
|
+
result = service.get_query_status(query_id, preview=preview)
|
|
149
169
|
|
|
150
170
|
console.print(f"Query ID: [bold]{query_id}[/bold]")
|
|
151
171
|
|
|
@@ -183,6 +203,11 @@ def get_query_results(
|
|
|
183
203
|
output_file: Optional[Path] = typer.Option(
|
|
184
204
|
None, "--output", help="Save results to file"
|
|
185
205
|
),
|
|
206
|
+
preview: bool = typer.Option(
|
|
207
|
+
True,
|
|
208
|
+
"--preview/--no-preview",
|
|
209
|
+
help="Enable preview mode (required for SQL API)",
|
|
210
|
+
),
|
|
186
211
|
) -> None:
|
|
187
212
|
"""Get the results of a completed query."""
|
|
188
213
|
console = Console()
|
|
@@ -195,6 +220,7 @@ def get_query_results(
|
|
|
195
220
|
result = service.get_query_results(
|
|
196
221
|
query_id,
|
|
197
222
|
format="table" if output_format in ["table", "csv"] else "json",
|
|
223
|
+
preview=preview,
|
|
198
224
|
)
|
|
199
225
|
|
|
200
226
|
# Display or save results
|
|
@@ -217,6 +243,11 @@ def cancel_query(
|
|
|
217
243
|
profile: Optional[str] = typer.Option(
|
|
218
244
|
None, "--profile", help="Auth profile to use"
|
|
219
245
|
),
|
|
246
|
+
preview: bool = typer.Option(
|
|
247
|
+
True,
|
|
248
|
+
"--preview/--no-preview",
|
|
249
|
+
help="Enable preview mode (required for SQL API)",
|
|
250
|
+
),
|
|
220
251
|
) -> None:
|
|
221
252
|
"""Cancel a running query."""
|
|
222
253
|
console = Console()
|
|
@@ -226,7 +257,7 @@ def cancel_query(
|
|
|
226
257
|
service = SqlService(profile=profile)
|
|
227
258
|
|
|
228
259
|
with SpinnerProgressTracker().track_spinner("Canceling query..."):
|
|
229
|
-
result = service.cancel_query(query_id)
|
|
260
|
+
result = service.cancel_query(query_id, preview=preview)
|
|
230
261
|
|
|
231
262
|
console.print(f"Query ID: [bold]{query_id}[/bold]")
|
|
232
263
|
|
|
@@ -259,8 +290,15 @@ def export_query_results(
|
|
|
259
290
|
fallback_branches: Optional[str] = typer.Option(
|
|
260
291
|
None, "--fallback-branches", help="Comma-separated list of fallback branch IDs"
|
|
261
292
|
),
|
|
293
|
+
preview: bool = typer.Option(
|
|
294
|
+
True,
|
|
295
|
+
"--preview/--no-preview",
|
|
296
|
+
help="Enable preview mode (required for SQL API)",
|
|
297
|
+
),
|
|
262
298
|
) -> None:
|
|
263
|
-
"""Execute a SQL query and export results to a file.
|
|
299
|
+
"""Execute a SQL query and export results to a file.
|
|
300
|
+
|
|
301
|
+
Note: SQL queries are currently in preview and may be modified or removed at any time."""
|
|
264
302
|
console = Console()
|
|
265
303
|
formatter = OutputFormatter()
|
|
266
304
|
|
|
@@ -289,6 +327,7 @@ def export_query_results(
|
|
|
289
327
|
fallback_branch_ids=fallback_branch_ids,
|
|
290
328
|
timeout=timeout,
|
|
291
329
|
format="table" if output_format in ["table", "csv"] else "json",
|
|
330
|
+
preview=preview,
|
|
292
331
|
)
|
|
293
332
|
|
|
294
333
|
# Save results to file
|
|
@@ -321,6 +360,11 @@ def wait_for_query(
|
|
|
321
360
|
output_file: Optional[Path] = typer.Option(
|
|
322
361
|
None, "--output", help="Save results to file when completed"
|
|
323
362
|
),
|
|
363
|
+
preview: bool = typer.Option(
|
|
364
|
+
True,
|
|
365
|
+
"--preview/--no-preview",
|
|
366
|
+
help="Enable preview mode (required for SQL API)",
|
|
367
|
+
),
|
|
324
368
|
) -> None:
|
|
325
369
|
"""Wait for a query to complete and optionally display results."""
|
|
326
370
|
console = Console()
|
|
@@ -330,7 +374,9 @@ def wait_for_query(
|
|
|
330
374
|
service = SqlService(profile=profile)
|
|
331
375
|
|
|
332
376
|
with SpinnerProgressTracker().track_spinner("Waiting for query to complete..."):
|
|
333
|
-
status_result = service.wait_for_completion(
|
|
377
|
+
status_result = service.wait_for_completion(
|
|
378
|
+
query_id, timeout, preview=preview
|
|
379
|
+
)
|
|
334
380
|
|
|
335
381
|
console.print(f"Query ID: [bold]{query_id}[/bold]")
|
|
336
382
|
console.print(
|
|
@@ -343,6 +389,7 @@ def wait_for_query(
|
|
|
343
389
|
result = service.get_query_results(
|
|
344
390
|
query_id,
|
|
345
391
|
format="table" if output_format in ["table", "csv"] else "json",
|
|
392
|
+
preview=preview,
|
|
346
393
|
)
|
|
347
394
|
|
|
348
395
|
if output_file:
|