pltr-cli 0.1.1__py3-none-any.whl → 0.2.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/__main__.py +28 -0
- pltr/cli.py +19 -1
- pltr/commands/admin.py +530 -0
- pltr/commands/completion.py +383 -0
- pltr/commands/dataset.py +20 -3
- pltr/commands/ontology.py +508 -0
- pltr/commands/shell.py +126 -0
- pltr/commands/sql.py +358 -0
- pltr/commands/verify.py +2 -1
- pltr/services/__init__.py +4 -0
- pltr/services/admin.py +314 -0
- pltr/services/ontology.py +443 -0
- pltr/services/sql.py +340 -0
- pltr/utils/completion.py +170 -0
- pltr/utils/formatting.py +208 -0
- pltr/utils/progress.py +1 -1
- pltr_cli-0.2.0.dist-info/METADATA +280 -0
- pltr_cli-0.2.0.dist-info/RECORD +38 -0
- pltr_cli-0.1.1.dist-info/METADATA +0 -203
- pltr_cli-0.1.1.dist-info/RECORD +0 -28
- {pltr_cli-0.1.1.dist-info → pltr_cli-0.2.0.dist-info}/WHEEL +0 -0
- {pltr_cli-0.1.1.dist-info → pltr_cli-0.2.0.dist-info}/entry_points.txt +0 -0
- {pltr_cli-0.1.1.dist-info → pltr_cli-0.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
"""Shell completion commands for pltr CLI."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
from rich.panel import Panel
|
|
10
|
+
from rich.syntax import Syntax
|
|
11
|
+
|
|
12
|
+
console = Console()
|
|
13
|
+
app = typer.Typer(help="Manage shell completions for pltr CLI")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_shell_from_env() -> Optional[str]:
|
|
17
|
+
"""Detect the current shell from environment."""
|
|
18
|
+
shell_path = os.environ.get("SHELL", "")
|
|
19
|
+
if "bash" in shell_path:
|
|
20
|
+
return "bash"
|
|
21
|
+
elif "zsh" in shell_path:
|
|
22
|
+
return "zsh"
|
|
23
|
+
elif "fish" in shell_path:
|
|
24
|
+
return "fish"
|
|
25
|
+
return None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@app.command()
|
|
29
|
+
def install(
|
|
30
|
+
shell: Optional[str] = typer.Option(
|
|
31
|
+
None,
|
|
32
|
+
"--shell",
|
|
33
|
+
"-s",
|
|
34
|
+
help="Shell type (bash, zsh, fish). Auto-detected if not specified.",
|
|
35
|
+
),
|
|
36
|
+
path: Optional[Path] = typer.Option(
|
|
37
|
+
None,
|
|
38
|
+
"--path",
|
|
39
|
+
"-p",
|
|
40
|
+
help="Custom path to install completion file.",
|
|
41
|
+
),
|
|
42
|
+
):
|
|
43
|
+
"""Install shell completions for pltr CLI.
|
|
44
|
+
|
|
45
|
+
This command will install shell completions for the specified shell
|
|
46
|
+
(or auto-detect from your environment). After installation, restart
|
|
47
|
+
your shell or source the appropriate file to enable completions.
|
|
48
|
+
|
|
49
|
+
Examples:
|
|
50
|
+
pltr completion install
|
|
51
|
+
pltr completion install --shell bash
|
|
52
|
+
pltr completion install --shell zsh --path ~/.config/custom/completions
|
|
53
|
+
"""
|
|
54
|
+
# Auto-detect shell if not specified
|
|
55
|
+
if shell is None:
|
|
56
|
+
shell = get_shell_from_env()
|
|
57
|
+
if shell is None:
|
|
58
|
+
console.print(
|
|
59
|
+
"[red]Could not detect shell type. Please specify with --shell option.[/red]"
|
|
60
|
+
)
|
|
61
|
+
console.print("Supported shells: bash, zsh, fish")
|
|
62
|
+
raise typer.Exit(1)
|
|
63
|
+
console.print(f"[cyan]Auto-detected shell: {shell}[/cyan]")
|
|
64
|
+
|
|
65
|
+
shell = shell.lower()
|
|
66
|
+
if shell not in ["bash", "zsh", "fish"]:
|
|
67
|
+
console.print(f"[red]Unsupported shell: {shell}[/red]")
|
|
68
|
+
console.print("Supported shells: bash, zsh, fish")
|
|
69
|
+
raise typer.Exit(1)
|
|
70
|
+
|
|
71
|
+
# Generate completion script
|
|
72
|
+
completion_script = generate_completion_script(shell)
|
|
73
|
+
|
|
74
|
+
# Determine installation path
|
|
75
|
+
if path is None:
|
|
76
|
+
path = get_default_completion_path(shell)
|
|
77
|
+
|
|
78
|
+
# Ensure directory exists
|
|
79
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
80
|
+
|
|
81
|
+
# Write completion file
|
|
82
|
+
try:
|
|
83
|
+
path.write_text(completion_script)
|
|
84
|
+
console.print(f"[green]✓[/green] Completion file written to: {path}")
|
|
85
|
+
except Exception as e:
|
|
86
|
+
console.print(f"[red]Failed to write completion file: {e}[/red]")
|
|
87
|
+
raise typer.Exit(1)
|
|
88
|
+
|
|
89
|
+
# Show instructions for activation
|
|
90
|
+
show_activation_instructions(shell, path)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@app.command()
|
|
94
|
+
def show(
|
|
95
|
+
shell: Optional[str] = typer.Option(
|
|
96
|
+
None,
|
|
97
|
+
"--shell",
|
|
98
|
+
"-s",
|
|
99
|
+
help="Shell type (bash, zsh, fish). Auto-detected if not specified.",
|
|
100
|
+
),
|
|
101
|
+
):
|
|
102
|
+
"""Show the completion script for the specified shell.
|
|
103
|
+
|
|
104
|
+
This displays the completion script without installing it,
|
|
105
|
+
useful for manual installation or debugging.
|
|
106
|
+
"""
|
|
107
|
+
# Auto-detect shell if not specified
|
|
108
|
+
if shell is None:
|
|
109
|
+
shell = get_shell_from_env()
|
|
110
|
+
if shell is None:
|
|
111
|
+
console.print(
|
|
112
|
+
"[red]Could not detect shell type. Please specify with --shell option.[/red]"
|
|
113
|
+
)
|
|
114
|
+
console.print("Supported shells: bash, zsh, fish")
|
|
115
|
+
raise typer.Exit(1)
|
|
116
|
+
|
|
117
|
+
shell = shell.lower()
|
|
118
|
+
if shell not in ["bash", "zsh", "fish"]:
|
|
119
|
+
console.print(f"[red]Unsupported shell: {shell}[/red]")
|
|
120
|
+
console.print("Supported shells: bash, zsh, fish")
|
|
121
|
+
raise typer.Exit(1)
|
|
122
|
+
|
|
123
|
+
# Generate and display completion script
|
|
124
|
+
completion_script = generate_completion_script(shell)
|
|
125
|
+
syntax = Syntax(completion_script, "bash", theme="monokai", line_numbers=True)
|
|
126
|
+
|
|
127
|
+
panel = Panel(
|
|
128
|
+
syntax,
|
|
129
|
+
title=f"{shell.capitalize()} Completion Script",
|
|
130
|
+
border_style="cyan",
|
|
131
|
+
)
|
|
132
|
+
console.print(panel)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def generate_completion_script(shell: str) -> str:
|
|
136
|
+
"""Generate completion script for the specified shell."""
|
|
137
|
+
if shell == "bash":
|
|
138
|
+
return generate_bash_completion()
|
|
139
|
+
elif shell == "zsh":
|
|
140
|
+
return generate_zsh_completion()
|
|
141
|
+
elif shell == "fish":
|
|
142
|
+
return generate_fish_completion()
|
|
143
|
+
else:
|
|
144
|
+
raise ValueError(f"Unsupported shell: {shell}")
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def generate_bash_completion() -> str:
|
|
148
|
+
"""Generate Bash completion script."""
|
|
149
|
+
return """# pltr bash completion script
|
|
150
|
+
# Generated by pltr completion install
|
|
151
|
+
|
|
152
|
+
_pltr_completion() {
|
|
153
|
+
local IFS=$'\\n'
|
|
154
|
+
local response
|
|
155
|
+
|
|
156
|
+
response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD _PLTR_COMPLETE=bash_complete pltr)
|
|
157
|
+
|
|
158
|
+
for completion in $response; do
|
|
159
|
+
IFS=',' read type value <<< "$completion"
|
|
160
|
+
|
|
161
|
+
if [[ $type == 'dir' ]]; then
|
|
162
|
+
COMPREPLY+=("$value/")
|
|
163
|
+
compopt -o dirnames
|
|
164
|
+
elif [[ $type == 'file' ]]; then
|
|
165
|
+
COMPREPLY+=("$value")
|
|
166
|
+
compopt -o filenames
|
|
167
|
+
elif [[ $type == 'plain' ]]; then
|
|
168
|
+
COMPREPLY+=("$value")
|
|
169
|
+
fi
|
|
170
|
+
done
|
|
171
|
+
|
|
172
|
+
return 0
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
_pltr_completion_setup() {
|
|
176
|
+
complete -o nosort -F _pltr_completion pltr
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
_pltr_completion_setup
|
|
180
|
+
"""
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def generate_zsh_completion() -> str:
|
|
184
|
+
"""Generate Zsh completion script."""
|
|
185
|
+
return """#compdef pltr
|
|
186
|
+
# pltr zsh completion script
|
|
187
|
+
# Generated by pltr completion install
|
|
188
|
+
|
|
189
|
+
_pltr() {
|
|
190
|
+
local -a completions
|
|
191
|
+
local -a completions_with_descriptions
|
|
192
|
+
local -a response
|
|
193
|
+
(( ! $+commands[pltr] )) && return 1
|
|
194
|
+
|
|
195
|
+
response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) _PLTR_COMPLETE=zsh_complete pltr)}")
|
|
196
|
+
|
|
197
|
+
for type key descr in ${response}; do
|
|
198
|
+
if [[ "$type" == "plain" ]]; then
|
|
199
|
+
if [[ "$descr" == "_" ]]; then
|
|
200
|
+
completions+=("$key")
|
|
201
|
+
else
|
|
202
|
+
completions_with_descriptions+=("$key":"$descr")
|
|
203
|
+
fi
|
|
204
|
+
elif [[ "$type" == "dir" ]]; then
|
|
205
|
+
_path_files -/
|
|
206
|
+
elif [[ "$type" == "file" ]]; then
|
|
207
|
+
_path_files -f
|
|
208
|
+
fi
|
|
209
|
+
done
|
|
210
|
+
|
|
211
|
+
if [ -n "$completions_with_descriptions" ]; then
|
|
212
|
+
_describe -V unsorted completions_with_descriptions -U
|
|
213
|
+
fi
|
|
214
|
+
|
|
215
|
+
if [ -n "$completions" ]; then
|
|
216
|
+
compadd -U -V unsorted -a completions
|
|
217
|
+
fi
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if [[ $zsh_eval_context[-1] == loadautofunc ]]; then
|
|
221
|
+
_pltr "$@"
|
|
222
|
+
else
|
|
223
|
+
compdef _pltr pltr
|
|
224
|
+
fi
|
|
225
|
+
"""
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def generate_fish_completion() -> str:
|
|
229
|
+
"""Generate Fish completion script."""
|
|
230
|
+
return """# pltr fish completion script
|
|
231
|
+
# Generated by pltr completion install
|
|
232
|
+
|
|
233
|
+
function _pltr_completion
|
|
234
|
+
set -l response (env COMP_WORDS=(commandline -cp) COMP_CWORD=(commandline -t) _PLTR_COMPLETE=fish_complete pltr)
|
|
235
|
+
|
|
236
|
+
for completion in $response
|
|
237
|
+
set -l metadata (string split "," $completion)
|
|
238
|
+
|
|
239
|
+
if test $metadata[1] = "dir"
|
|
240
|
+
__fish_complete_directories $metadata[2]
|
|
241
|
+
else if test $metadata[1] = "file"
|
|
242
|
+
__fish_complete_path $metadata[2]
|
|
243
|
+
else if test $metadata[1] = "plain"
|
|
244
|
+
echo $metadata[2]
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
complete -c pltr -f -a "(_pltr_completion)"
|
|
250
|
+
"""
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def get_default_completion_path(shell: str) -> Path:
|
|
254
|
+
"""Get the default path for completion file installation."""
|
|
255
|
+
home = Path.home()
|
|
256
|
+
|
|
257
|
+
if shell == "bash":
|
|
258
|
+
# Try bash-completion paths
|
|
259
|
+
paths = [
|
|
260
|
+
home / ".local" / "share" / "bash-completion" / "completions" / "pltr",
|
|
261
|
+
home / ".bash_completion.d" / "pltr",
|
|
262
|
+
Path("/etc/bash_completion.d/pltr"),
|
|
263
|
+
]
|
|
264
|
+
# Use first writable path
|
|
265
|
+
for p in paths[:-1]: # Skip system path for user installs
|
|
266
|
+
if p.parent.exists() or not p.parent.parent.exists():
|
|
267
|
+
return p
|
|
268
|
+
return paths[0]
|
|
269
|
+
|
|
270
|
+
elif shell == "zsh":
|
|
271
|
+
# Zsh completion paths
|
|
272
|
+
return home / ".zfunc" / "_pltr"
|
|
273
|
+
|
|
274
|
+
elif shell == "fish":
|
|
275
|
+
# Fish completion path
|
|
276
|
+
return home / ".config" / "fish" / "completions" / "pltr.fish"
|
|
277
|
+
|
|
278
|
+
else:
|
|
279
|
+
raise ValueError(f"Unknown shell: {shell}")
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def show_activation_instructions(shell: str, path: Path):
|
|
283
|
+
"""Show instructions for activating completions."""
|
|
284
|
+
console.print("\n[yellow]Activation Instructions:[/yellow]")
|
|
285
|
+
|
|
286
|
+
if shell == "bash":
|
|
287
|
+
console.print(
|
|
288
|
+
Panel(
|
|
289
|
+
f"""To activate completions, add this to your ~/.bashrc:
|
|
290
|
+
|
|
291
|
+
[cyan]# Load pltr completions
|
|
292
|
+
if [ -f {path} ]; then
|
|
293
|
+
source {path}
|
|
294
|
+
fi[/cyan]
|
|
295
|
+
|
|
296
|
+
Then reload your shell:
|
|
297
|
+
[cyan]source ~/.bashrc[/cyan]
|
|
298
|
+
|
|
299
|
+
Or start a new terminal session.""",
|
|
300
|
+
title="Bash Activation",
|
|
301
|
+
border_style="green",
|
|
302
|
+
)
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
elif shell == "zsh":
|
|
306
|
+
console.print(
|
|
307
|
+
Panel(
|
|
308
|
+
f"""To activate completions, add this to your ~/.zshrc:
|
|
309
|
+
|
|
310
|
+
[cyan]# Add custom completion directory
|
|
311
|
+
fpath=({path.parent} $fpath)
|
|
312
|
+
|
|
313
|
+
# Initialize completions (if not already done)
|
|
314
|
+
autoload -Uz compinit && compinit[/cyan]
|
|
315
|
+
|
|
316
|
+
Then reload your shell:
|
|
317
|
+
[cyan]source ~/.zshrc[/cyan]
|
|
318
|
+
|
|
319
|
+
Or start a new terminal session.""",
|
|
320
|
+
title="Zsh Activation",
|
|
321
|
+
border_style="green",
|
|
322
|
+
)
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
elif shell == "fish":
|
|
326
|
+
console.print(
|
|
327
|
+
Panel(
|
|
328
|
+
f"""Completions should be automatically loaded from:
|
|
329
|
+
{path}
|
|
330
|
+
|
|
331
|
+
If not working, reload your shell:
|
|
332
|
+
[cyan]exec fish[/cyan]
|
|
333
|
+
|
|
334
|
+
Or start a new terminal session.""",
|
|
335
|
+
title="Fish Activation",
|
|
336
|
+
border_style="green",
|
|
337
|
+
)
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
@app.command()
|
|
342
|
+
def uninstall(
|
|
343
|
+
shell: Optional[str] = typer.Option(
|
|
344
|
+
None,
|
|
345
|
+
"--shell",
|
|
346
|
+
"-s",
|
|
347
|
+
help="Shell type (bash, zsh, fish). Auto-detected if not specified.",
|
|
348
|
+
),
|
|
349
|
+
):
|
|
350
|
+
"""Uninstall shell completions for pltr CLI."""
|
|
351
|
+
# Auto-detect shell if not specified
|
|
352
|
+
if shell is None:
|
|
353
|
+
shell = get_shell_from_env()
|
|
354
|
+
if shell is None:
|
|
355
|
+
console.print(
|
|
356
|
+
"[red]Could not detect shell type. Please specify with --shell option.[/red]"
|
|
357
|
+
)
|
|
358
|
+
raise typer.Exit(1)
|
|
359
|
+
|
|
360
|
+
shell = shell.lower()
|
|
361
|
+
if shell not in ["bash", "zsh", "fish"]:
|
|
362
|
+
console.print(f"[red]Unsupported shell: {shell}[/red]")
|
|
363
|
+
raise typer.Exit(1)
|
|
364
|
+
|
|
365
|
+
# Get default completion path
|
|
366
|
+
path = get_default_completion_path(shell)
|
|
367
|
+
|
|
368
|
+
if path.exists():
|
|
369
|
+
try:
|
|
370
|
+
path.unlink()
|
|
371
|
+
console.print(f"[green]✓[/green] Removed completion file: {path}")
|
|
372
|
+
console.print(
|
|
373
|
+
"\n[yellow]Remember to remove any sourcing commands from your shell config.[/yellow]"
|
|
374
|
+
)
|
|
375
|
+
except Exception as e:
|
|
376
|
+
console.print(f"[red]Failed to remove completion file: {e}[/red]")
|
|
377
|
+
raise typer.Exit(1)
|
|
378
|
+
else:
|
|
379
|
+
console.print(f"[yellow]No completion file found at: {path}[/yellow]")
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
if __name__ == "__main__":
|
|
383
|
+
app()
|
pltr/commands/dataset.py
CHANGED
|
@@ -10,6 +10,12 @@ from ..services.dataset import DatasetService
|
|
|
10
10
|
from ..utils.formatting import OutputFormatter
|
|
11
11
|
from ..utils.progress import SpinnerProgressTracker
|
|
12
12
|
from ..auth.base import ProfileNotFoundError, MissingCredentialsError
|
|
13
|
+
from ..utils.completion import (
|
|
14
|
+
complete_rid,
|
|
15
|
+
complete_profile,
|
|
16
|
+
complete_output_format,
|
|
17
|
+
cache_rid,
|
|
18
|
+
)
|
|
13
19
|
|
|
14
20
|
app = typer.Typer()
|
|
15
21
|
console = Console()
|
|
@@ -18,10 +24,18 @@ formatter = OutputFormatter(console)
|
|
|
18
24
|
|
|
19
25
|
@app.command("get")
|
|
20
26
|
def get_dataset(
|
|
21
|
-
dataset_rid: str = typer.Argument(
|
|
22
|
-
|
|
27
|
+
dataset_rid: str = typer.Argument(
|
|
28
|
+
..., help="Dataset Resource Identifier", autocompletion=complete_rid
|
|
29
|
+
),
|
|
30
|
+
profile: Optional[str] = typer.Option(
|
|
31
|
+
None, "--profile", "-p", help="Profile name", autocompletion=complete_profile
|
|
32
|
+
),
|
|
23
33
|
format: str = typer.Option(
|
|
24
|
-
"table",
|
|
34
|
+
"table",
|
|
35
|
+
"--format",
|
|
36
|
+
"-f",
|
|
37
|
+
help="Output format (table, json, csv)",
|
|
38
|
+
autocompletion=complete_output_format,
|
|
25
39
|
),
|
|
26
40
|
output: Optional[str] = typer.Option(
|
|
27
41
|
None, "--output", "-o", help="Output file path"
|
|
@@ -29,6 +43,9 @@ def get_dataset(
|
|
|
29
43
|
):
|
|
30
44
|
"""Get detailed information about a specific dataset."""
|
|
31
45
|
try:
|
|
46
|
+
# Cache the RID for future completions
|
|
47
|
+
cache_rid(dataset_rid)
|
|
48
|
+
|
|
32
49
|
service = DatasetService(profile=profile)
|
|
33
50
|
|
|
34
51
|
with SpinnerProgressTracker().track_spinner(
|