pltr-cli 0.3.0__py3-none-any.whl → 0.5.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/cli.py +10 -0
- pltr/commands/dataset.py +309 -0
- pltr/commands/folder.py +338 -0
- pltr/commands/mediasets.py +422 -0
- pltr/commands/orchestration.py +642 -0
- pltr/services/dataset.py +368 -10
- pltr/services/folder.py +167 -0
- pltr/services/mediasets.py +293 -0
- pltr/services/orchestration.py +457 -0
- pltr/utils/formatting.py +638 -0
- {pltr_cli-0.3.0.dist-info → pltr_cli-0.5.0.dist-info}/METADATA +139 -5
- {pltr_cli-0.3.0.dist-info → pltr_cli-0.5.0.dist-info}/RECORD +15 -11
- pltr/services/dataset_full.py +0 -302
- pltr/services/dataset_v2.py +0 -128
- {pltr_cli-0.3.0.dist-info → pltr_cli-0.5.0.dist-info}/WHEEL +0 -0
- {pltr_cli-0.3.0.dist-info → pltr_cli-0.5.0.dist-info}/entry_points.txt +0 -0
- {pltr_cli-0.3.0.dist-info → pltr_cli-0.5.0.dist-info}/licenses/LICENSE +0 -0
pltr/cli.py
CHANGED
|
@@ -10,12 +10,15 @@ from pltr.commands import (
|
|
|
10
10
|
configure,
|
|
11
11
|
verify,
|
|
12
12
|
dataset,
|
|
13
|
+
folder,
|
|
13
14
|
ontology,
|
|
15
|
+
orchestration,
|
|
14
16
|
sql,
|
|
15
17
|
admin,
|
|
16
18
|
shell,
|
|
17
19
|
completion,
|
|
18
20
|
alias,
|
|
21
|
+
mediasets,
|
|
19
22
|
)
|
|
20
23
|
|
|
21
24
|
app = typer.Typer(
|
|
@@ -28,8 +31,15 @@ app = typer.Typer(
|
|
|
28
31
|
app.add_typer(configure.app, name="configure", help="Manage authentication profiles")
|
|
29
32
|
app.add_typer(verify.app, name="verify", help="Verify authentication")
|
|
30
33
|
app.add_typer(dataset.app, name="dataset", help="Manage datasets")
|
|
34
|
+
app.add_typer(folder.app, name="folder", help="Manage folders")
|
|
31
35
|
app.add_typer(ontology.app, name="ontology", help="Ontology operations")
|
|
36
|
+
app.add_typer(
|
|
37
|
+
orchestration.app, name="orchestration", help="Manage builds, jobs, and schedules"
|
|
38
|
+
)
|
|
32
39
|
app.add_typer(sql.app, name="sql", help="Execute SQL queries")
|
|
40
|
+
app.add_typer(
|
|
41
|
+
mediasets.app, name="media-sets", help="Manage media sets and media content"
|
|
42
|
+
)
|
|
33
43
|
app.add_typer(
|
|
34
44
|
admin.app,
|
|
35
45
|
name="admin",
|
pltr/commands/dataset.py
CHANGED
|
@@ -18,6 +18,10 @@ from ..utils.completion import (
|
|
|
18
18
|
)
|
|
19
19
|
|
|
20
20
|
app = typer.Typer()
|
|
21
|
+
branches_app = typer.Typer()
|
|
22
|
+
files_app = typer.Typer()
|
|
23
|
+
transactions_app = typer.Typer()
|
|
24
|
+
views_app = typer.Typer()
|
|
21
25
|
console = Console()
|
|
22
26
|
formatter = OutputFormatter(console)
|
|
23
27
|
|
|
@@ -101,6 +105,311 @@ def create_dataset(
|
|
|
101
105
|
raise typer.Exit(1)
|
|
102
106
|
|
|
103
107
|
|
|
108
|
+
# Branch commands
|
|
109
|
+
@branches_app.command("list")
|
|
110
|
+
def list_branches(
|
|
111
|
+
dataset_rid: str = typer.Argument(
|
|
112
|
+
..., help="Dataset Resource Identifier", autocompletion=complete_rid
|
|
113
|
+
),
|
|
114
|
+
profile: Optional[str] = typer.Option(
|
|
115
|
+
None, "--profile", "-p", help="Profile name", autocompletion=complete_profile
|
|
116
|
+
),
|
|
117
|
+
format: str = typer.Option(
|
|
118
|
+
"table",
|
|
119
|
+
"--format",
|
|
120
|
+
"-f",
|
|
121
|
+
help="Output format (table, json, csv)",
|
|
122
|
+
autocompletion=complete_output_format,
|
|
123
|
+
),
|
|
124
|
+
output: Optional[str] = typer.Option(
|
|
125
|
+
None, "--output", "-o", help="Output file path"
|
|
126
|
+
),
|
|
127
|
+
):
|
|
128
|
+
"""List branches for a dataset."""
|
|
129
|
+
try:
|
|
130
|
+
cache_rid(dataset_rid)
|
|
131
|
+
service = DatasetService(profile=profile)
|
|
132
|
+
|
|
133
|
+
with SpinnerProgressTracker().track_spinner(
|
|
134
|
+
f"Fetching branches for {dataset_rid}..."
|
|
135
|
+
):
|
|
136
|
+
branches = service.get_branches(dataset_rid)
|
|
137
|
+
|
|
138
|
+
formatter.format_branches(branches, format, output)
|
|
139
|
+
|
|
140
|
+
if output:
|
|
141
|
+
formatter.print_success(f"Branches information saved to {output}")
|
|
142
|
+
|
|
143
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
144
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
145
|
+
raise typer.Exit(1)
|
|
146
|
+
except Exception as e:
|
|
147
|
+
formatter.print_error(f"Failed to get branches: {e}")
|
|
148
|
+
raise typer.Exit(1)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
@branches_app.command("create")
|
|
152
|
+
def create_branch(
|
|
153
|
+
dataset_rid: str = typer.Argument(
|
|
154
|
+
..., help="Dataset Resource Identifier", autocompletion=complete_rid
|
|
155
|
+
),
|
|
156
|
+
branch_name: str = typer.Argument(..., help="Branch name"),
|
|
157
|
+
parent_branch: str = typer.Option(
|
|
158
|
+
"master", "--parent", help="Parent branch to branch from"
|
|
159
|
+
),
|
|
160
|
+
profile: Optional[str] = typer.Option(
|
|
161
|
+
None, "--profile", "-p", help="Profile name", autocompletion=complete_profile
|
|
162
|
+
),
|
|
163
|
+
format: str = typer.Option(
|
|
164
|
+
"table",
|
|
165
|
+
"--format",
|
|
166
|
+
"-f",
|
|
167
|
+
help="Output format (table, json, csv)",
|
|
168
|
+
autocompletion=complete_output_format,
|
|
169
|
+
),
|
|
170
|
+
):
|
|
171
|
+
"""Create a new branch for a dataset."""
|
|
172
|
+
try:
|
|
173
|
+
cache_rid(dataset_rid)
|
|
174
|
+
service = DatasetService(profile=profile)
|
|
175
|
+
|
|
176
|
+
with SpinnerProgressTracker().track_spinner(
|
|
177
|
+
f"Creating branch '{branch_name}' from '{parent_branch}'..."
|
|
178
|
+
):
|
|
179
|
+
branch = service.create_branch(dataset_rid, branch_name, parent_branch)
|
|
180
|
+
|
|
181
|
+
formatter.print_success(f"Successfully created branch '{branch_name}'")
|
|
182
|
+
formatter.format_branch_detail(branch, format)
|
|
183
|
+
|
|
184
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
185
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
186
|
+
raise typer.Exit(1)
|
|
187
|
+
except Exception as e:
|
|
188
|
+
formatter.print_error(f"Failed to create branch: {e}")
|
|
189
|
+
raise typer.Exit(1)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
# Files commands
|
|
193
|
+
@files_app.command("list")
|
|
194
|
+
def list_files(
|
|
195
|
+
dataset_rid: str = typer.Argument(
|
|
196
|
+
..., help="Dataset Resource Identifier", autocompletion=complete_rid
|
|
197
|
+
),
|
|
198
|
+
branch: str = typer.Option("master", "--branch", help="Dataset branch"),
|
|
199
|
+
profile: Optional[str] = typer.Option(
|
|
200
|
+
None, "--profile", "-p", help="Profile name", autocompletion=complete_profile
|
|
201
|
+
),
|
|
202
|
+
format: str = typer.Option(
|
|
203
|
+
"table",
|
|
204
|
+
"--format",
|
|
205
|
+
"-f",
|
|
206
|
+
help="Output format (table, json, csv)",
|
|
207
|
+
autocompletion=complete_output_format,
|
|
208
|
+
),
|
|
209
|
+
output: Optional[str] = typer.Option(
|
|
210
|
+
None, "--output", "-o", help="Output file path"
|
|
211
|
+
),
|
|
212
|
+
):
|
|
213
|
+
"""List files in a dataset."""
|
|
214
|
+
try:
|
|
215
|
+
cache_rid(dataset_rid)
|
|
216
|
+
service = DatasetService(profile=profile)
|
|
217
|
+
|
|
218
|
+
with SpinnerProgressTracker().track_spinner(
|
|
219
|
+
f"Fetching files from {dataset_rid} (branch: {branch})..."
|
|
220
|
+
):
|
|
221
|
+
files = service.list_files(dataset_rid, branch)
|
|
222
|
+
|
|
223
|
+
formatter.format_files(files, format, output)
|
|
224
|
+
|
|
225
|
+
if output:
|
|
226
|
+
formatter.print_success(f"Files information saved to {output}")
|
|
227
|
+
|
|
228
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
229
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
230
|
+
raise typer.Exit(1)
|
|
231
|
+
except Exception as e:
|
|
232
|
+
formatter.print_error(f"Failed to list files: {e}")
|
|
233
|
+
raise typer.Exit(1)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
@files_app.command("get")
|
|
237
|
+
def get_file(
|
|
238
|
+
dataset_rid: str = typer.Argument(
|
|
239
|
+
..., help="Dataset Resource Identifier", autocompletion=complete_rid
|
|
240
|
+
),
|
|
241
|
+
file_path: str = typer.Argument(..., help="Path of file within dataset"),
|
|
242
|
+
output_path: str = typer.Argument(..., help="Local path to save the file"),
|
|
243
|
+
branch: str = typer.Option("master", "--branch", help="Dataset branch"),
|
|
244
|
+
profile: Optional[str] = typer.Option(
|
|
245
|
+
None, "--profile", "-p", help="Profile name", autocompletion=complete_profile
|
|
246
|
+
),
|
|
247
|
+
):
|
|
248
|
+
"""Download a file from a dataset."""
|
|
249
|
+
try:
|
|
250
|
+
cache_rid(dataset_rid)
|
|
251
|
+
service = DatasetService(profile=profile)
|
|
252
|
+
|
|
253
|
+
with SpinnerProgressTracker().track_spinner(
|
|
254
|
+
f"Downloading {file_path} from {dataset_rid}..."
|
|
255
|
+
):
|
|
256
|
+
result = service.download_file(dataset_rid, file_path, output_path, branch)
|
|
257
|
+
|
|
258
|
+
formatter.print_success(f"File downloaded to {result['output_path']}")
|
|
259
|
+
formatter.print_info(f"Size: {result.get('size_bytes', 'unknown')} bytes")
|
|
260
|
+
|
|
261
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
262
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
263
|
+
raise typer.Exit(1)
|
|
264
|
+
except Exception as e:
|
|
265
|
+
formatter.print_error(f"Failed to download file: {e}")
|
|
266
|
+
raise typer.Exit(1)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
# Transaction commands
|
|
270
|
+
@transactions_app.command("list")
|
|
271
|
+
def list_transactions(
|
|
272
|
+
dataset_rid: str = typer.Argument(
|
|
273
|
+
..., help="Dataset Resource Identifier", autocompletion=complete_rid
|
|
274
|
+
),
|
|
275
|
+
branch: str = typer.Option("master", "--branch", help="Dataset branch"),
|
|
276
|
+
profile: Optional[str] = typer.Option(
|
|
277
|
+
None, "--profile", "-p", help="Profile name", autocompletion=complete_profile
|
|
278
|
+
),
|
|
279
|
+
format: str = typer.Option(
|
|
280
|
+
"table",
|
|
281
|
+
"--format",
|
|
282
|
+
"-f",
|
|
283
|
+
help="Output format (table, json, csv)",
|
|
284
|
+
autocompletion=complete_output_format,
|
|
285
|
+
),
|
|
286
|
+
output: Optional[str] = typer.Option(
|
|
287
|
+
None, "--output", "-o", help="Output file path"
|
|
288
|
+
),
|
|
289
|
+
):
|
|
290
|
+
"""List transactions for a dataset branch."""
|
|
291
|
+
try:
|
|
292
|
+
cache_rid(dataset_rid)
|
|
293
|
+
service = DatasetService(profile=profile)
|
|
294
|
+
|
|
295
|
+
with SpinnerProgressTracker().track_spinner(
|
|
296
|
+
f"Fetching transactions for {dataset_rid} (branch: {branch})..."
|
|
297
|
+
):
|
|
298
|
+
transactions = service.get_transactions(dataset_rid, branch)
|
|
299
|
+
|
|
300
|
+
formatter.format_transactions(transactions, format, output)
|
|
301
|
+
|
|
302
|
+
if output:
|
|
303
|
+
formatter.print_success(f"Transactions information saved to {output}")
|
|
304
|
+
|
|
305
|
+
except NotImplementedError as e:
|
|
306
|
+
formatter.print_warning(f"Feature not available: {e}")
|
|
307
|
+
raise typer.Exit(0)
|
|
308
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
309
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
310
|
+
raise typer.Exit(1)
|
|
311
|
+
except Exception as e:
|
|
312
|
+
formatter.print_error(f"Failed to list transactions: {e}")
|
|
313
|
+
raise typer.Exit(1)
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
# Views commands
|
|
317
|
+
@views_app.command("list")
|
|
318
|
+
def list_views(
|
|
319
|
+
dataset_rid: str = typer.Argument(
|
|
320
|
+
..., help="Dataset Resource Identifier", autocompletion=complete_rid
|
|
321
|
+
),
|
|
322
|
+
profile: Optional[str] = typer.Option(
|
|
323
|
+
None, "--profile", "-p", help="Profile name", autocompletion=complete_profile
|
|
324
|
+
),
|
|
325
|
+
format: str = typer.Option(
|
|
326
|
+
"table",
|
|
327
|
+
"--format",
|
|
328
|
+
"-f",
|
|
329
|
+
help="Output format (table, json, csv)",
|
|
330
|
+
autocompletion=complete_output_format,
|
|
331
|
+
),
|
|
332
|
+
output: Optional[str] = typer.Option(
|
|
333
|
+
None, "--output", "-o", help="Output file path"
|
|
334
|
+
),
|
|
335
|
+
):
|
|
336
|
+
"""List views for a dataset."""
|
|
337
|
+
try:
|
|
338
|
+
cache_rid(dataset_rid)
|
|
339
|
+
service = DatasetService(profile=profile)
|
|
340
|
+
|
|
341
|
+
with SpinnerProgressTracker().track_spinner(
|
|
342
|
+
f"Fetching views for {dataset_rid}..."
|
|
343
|
+
):
|
|
344
|
+
views = service.get_views(dataset_rid)
|
|
345
|
+
|
|
346
|
+
formatter.format_views(views, format, output)
|
|
347
|
+
|
|
348
|
+
if output:
|
|
349
|
+
formatter.print_success(f"Views information saved to {output}")
|
|
350
|
+
|
|
351
|
+
except NotImplementedError as e:
|
|
352
|
+
formatter.print_warning(f"Feature not available: {e}")
|
|
353
|
+
raise typer.Exit(0)
|
|
354
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
355
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
356
|
+
raise typer.Exit(1)
|
|
357
|
+
except Exception as e:
|
|
358
|
+
formatter.print_error(f"Failed to list views: {e}")
|
|
359
|
+
raise typer.Exit(1)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
@views_app.command("create")
|
|
363
|
+
def create_view(
|
|
364
|
+
dataset_rid: str = typer.Argument(
|
|
365
|
+
..., help="Dataset Resource Identifier", autocompletion=complete_rid
|
|
366
|
+
),
|
|
367
|
+
view_name: str = typer.Argument(..., help="View name"),
|
|
368
|
+
description: Optional[str] = typer.Option(
|
|
369
|
+
None, "--description", help="View description"
|
|
370
|
+
),
|
|
371
|
+
profile: Optional[str] = typer.Option(
|
|
372
|
+
None, "--profile", "-p", help="Profile name", autocompletion=complete_profile
|
|
373
|
+
),
|
|
374
|
+
format: str = typer.Option(
|
|
375
|
+
"table",
|
|
376
|
+
"--format",
|
|
377
|
+
"-f",
|
|
378
|
+
help="Output format (table, json, csv)",
|
|
379
|
+
autocompletion=complete_output_format,
|
|
380
|
+
),
|
|
381
|
+
):
|
|
382
|
+
"""Create a new view for a dataset."""
|
|
383
|
+
try:
|
|
384
|
+
cache_rid(dataset_rid)
|
|
385
|
+
service = DatasetService(profile=profile)
|
|
386
|
+
|
|
387
|
+
with SpinnerProgressTracker().track_spinner(
|
|
388
|
+
f"Creating view '{view_name}' for {dataset_rid}..."
|
|
389
|
+
):
|
|
390
|
+
view = service.create_view(dataset_rid, view_name, description)
|
|
391
|
+
|
|
392
|
+
formatter.print_success(f"Successfully created view '{view_name}'")
|
|
393
|
+
formatter.format_view_detail(view, format)
|
|
394
|
+
|
|
395
|
+
except NotImplementedError as e:
|
|
396
|
+
formatter.print_warning(f"Feature not available: {e}")
|
|
397
|
+
raise typer.Exit(0)
|
|
398
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
399
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
400
|
+
raise typer.Exit(1)
|
|
401
|
+
except Exception as e:
|
|
402
|
+
formatter.print_error(f"Failed to create view: {e}")
|
|
403
|
+
raise typer.Exit(1)
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
# Add subcommands to main app
|
|
407
|
+
app.add_typer(branches_app, name="branches")
|
|
408
|
+
app.add_typer(files_app, name="files")
|
|
409
|
+
app.add_typer(transactions_app, name="transactions")
|
|
410
|
+
app.add_typer(views_app, name="views")
|
|
411
|
+
|
|
412
|
+
|
|
104
413
|
@app.callback()
|
|
105
414
|
def main():
|
|
106
415
|
"""
|
pltr/commands/folder.py
ADDED
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Folder management commands for Foundry filesystem.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
from typing import Optional, List
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
from rich.table import Table
|
|
9
|
+
|
|
10
|
+
from ..services.folder import FolderService
|
|
11
|
+
from ..utils.formatting import OutputFormatter
|
|
12
|
+
from ..utils.progress import SpinnerProgressTracker
|
|
13
|
+
from ..auth.base import ProfileNotFoundError, MissingCredentialsError
|
|
14
|
+
from ..utils.completion import (
|
|
15
|
+
complete_rid,
|
|
16
|
+
complete_profile,
|
|
17
|
+
complete_output_format,
|
|
18
|
+
cache_rid,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
app = typer.Typer()
|
|
22
|
+
console = Console()
|
|
23
|
+
formatter = OutputFormatter(console)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@app.command("create")
|
|
27
|
+
def create_folder(
|
|
28
|
+
name: str = typer.Argument(..., help="Folder display name"),
|
|
29
|
+
parent_folder: str = typer.Option(
|
|
30
|
+
"ri.compass.main.folder.0",
|
|
31
|
+
"--parent-folder",
|
|
32
|
+
"-p",
|
|
33
|
+
help="Parent folder RID (default: root folder)",
|
|
34
|
+
autocompletion=complete_rid,
|
|
35
|
+
),
|
|
36
|
+
profile: Optional[str] = typer.Option(
|
|
37
|
+
None, "--profile", help="Profile name", autocompletion=complete_profile
|
|
38
|
+
),
|
|
39
|
+
format: str = typer.Option(
|
|
40
|
+
"table",
|
|
41
|
+
"--format",
|
|
42
|
+
"-f",
|
|
43
|
+
help="Output format (table, json, csv)",
|
|
44
|
+
autocompletion=complete_output_format,
|
|
45
|
+
),
|
|
46
|
+
):
|
|
47
|
+
"""Create a new folder in Foundry."""
|
|
48
|
+
try:
|
|
49
|
+
service = FolderService(profile=profile)
|
|
50
|
+
|
|
51
|
+
with SpinnerProgressTracker().track_spinner(f"Creating folder '{name}'..."):
|
|
52
|
+
folder = service.create_folder(
|
|
53
|
+
display_name=name, parent_folder_rid=parent_folder
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# Cache the RID for future completions
|
|
57
|
+
if folder.get("rid"):
|
|
58
|
+
cache_rid(folder["rid"])
|
|
59
|
+
|
|
60
|
+
formatter.print_success(f"Successfully created folder '{name}'")
|
|
61
|
+
formatter.print_info(f"Folder RID: {folder.get('rid', 'unknown')}")
|
|
62
|
+
|
|
63
|
+
# Format output
|
|
64
|
+
if format == "json":
|
|
65
|
+
formatter.format_dict(folder)
|
|
66
|
+
elif format == "csv":
|
|
67
|
+
formatter.format_list([folder])
|
|
68
|
+
else:
|
|
69
|
+
_format_folder_table(folder)
|
|
70
|
+
|
|
71
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
72
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
73
|
+
raise typer.Exit(1)
|
|
74
|
+
except Exception as e:
|
|
75
|
+
formatter.print_error(f"Failed to create folder: {e}")
|
|
76
|
+
raise typer.Exit(1)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@app.command("get")
|
|
80
|
+
def get_folder(
|
|
81
|
+
folder_rid: str = typer.Argument(
|
|
82
|
+
..., help="Folder Resource Identifier", autocompletion=complete_rid
|
|
83
|
+
),
|
|
84
|
+
profile: Optional[str] = typer.Option(
|
|
85
|
+
None, "--profile", help="Profile name", autocompletion=complete_profile
|
|
86
|
+
),
|
|
87
|
+
format: str = typer.Option(
|
|
88
|
+
"table",
|
|
89
|
+
"--format",
|
|
90
|
+
"-f",
|
|
91
|
+
help="Output format (table, json, csv)",
|
|
92
|
+
autocompletion=complete_output_format,
|
|
93
|
+
),
|
|
94
|
+
output: Optional[str] = typer.Option(
|
|
95
|
+
None, "--output", "-o", help="Output file path"
|
|
96
|
+
),
|
|
97
|
+
):
|
|
98
|
+
"""Get detailed information about a specific folder."""
|
|
99
|
+
try:
|
|
100
|
+
# Cache the RID for future completions
|
|
101
|
+
cache_rid(folder_rid)
|
|
102
|
+
|
|
103
|
+
service = FolderService(profile=profile)
|
|
104
|
+
|
|
105
|
+
with SpinnerProgressTracker().track_spinner(f"Fetching folder {folder_rid}..."):
|
|
106
|
+
folder = service.get_folder(folder_rid)
|
|
107
|
+
|
|
108
|
+
# Format output
|
|
109
|
+
if format == "json":
|
|
110
|
+
if output:
|
|
111
|
+
formatter.save_to_file(folder, output, "json")
|
|
112
|
+
else:
|
|
113
|
+
formatter.format_dict(folder)
|
|
114
|
+
elif format == "csv":
|
|
115
|
+
if output:
|
|
116
|
+
formatter.save_to_file([folder], output, "csv")
|
|
117
|
+
else:
|
|
118
|
+
formatter.format_list([folder])
|
|
119
|
+
else:
|
|
120
|
+
_format_folder_table(folder)
|
|
121
|
+
|
|
122
|
+
if output:
|
|
123
|
+
formatter.print_success(f"Folder information saved to {output}")
|
|
124
|
+
|
|
125
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
126
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
127
|
+
raise typer.Exit(1)
|
|
128
|
+
except Exception as e:
|
|
129
|
+
formatter.print_error(f"Failed to get folder: {e}")
|
|
130
|
+
raise typer.Exit(1)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@app.command("list")
|
|
134
|
+
def list_children(
|
|
135
|
+
folder_rid: str = typer.Argument(
|
|
136
|
+
...,
|
|
137
|
+
help="Folder Resource Identifier (use 'ri.compass.main.folder.0' for root)",
|
|
138
|
+
autocompletion=complete_rid,
|
|
139
|
+
),
|
|
140
|
+
profile: Optional[str] = typer.Option(
|
|
141
|
+
None, "--profile", help="Profile name", autocompletion=complete_profile
|
|
142
|
+
),
|
|
143
|
+
format: str = typer.Option(
|
|
144
|
+
"table",
|
|
145
|
+
"--format",
|
|
146
|
+
"-f",
|
|
147
|
+
help="Output format (table, json, csv)",
|
|
148
|
+
autocompletion=complete_output_format,
|
|
149
|
+
),
|
|
150
|
+
output: Optional[str] = typer.Option(
|
|
151
|
+
None, "--output", "-o", help="Output file path"
|
|
152
|
+
),
|
|
153
|
+
page_size: Optional[int] = typer.Option(
|
|
154
|
+
None, "--page-size", help="Number of items per page"
|
|
155
|
+
),
|
|
156
|
+
):
|
|
157
|
+
"""List all child resources of a folder."""
|
|
158
|
+
try:
|
|
159
|
+
# Cache the RID for future completions
|
|
160
|
+
cache_rid(folder_rid)
|
|
161
|
+
|
|
162
|
+
service = FolderService(profile=profile)
|
|
163
|
+
|
|
164
|
+
with SpinnerProgressTracker().track_spinner(
|
|
165
|
+
f"Listing children of folder {folder_rid}..."
|
|
166
|
+
):
|
|
167
|
+
children = service.list_children(folder_rid, page_size=page_size)
|
|
168
|
+
|
|
169
|
+
if not children:
|
|
170
|
+
formatter.print_info("No children found in this folder.")
|
|
171
|
+
return
|
|
172
|
+
|
|
173
|
+
# Format output
|
|
174
|
+
if format == "json":
|
|
175
|
+
if output:
|
|
176
|
+
formatter.save_to_file(children, output, "json")
|
|
177
|
+
else:
|
|
178
|
+
formatter.format_list(children)
|
|
179
|
+
elif format == "csv":
|
|
180
|
+
if output:
|
|
181
|
+
formatter.save_to_file(children, output, "csv")
|
|
182
|
+
else:
|
|
183
|
+
formatter.format_list(children)
|
|
184
|
+
else:
|
|
185
|
+
_format_children_table(children)
|
|
186
|
+
|
|
187
|
+
if output:
|
|
188
|
+
formatter.print_success(f"Folder children saved to {output}")
|
|
189
|
+
|
|
190
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
191
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
192
|
+
raise typer.Exit(1)
|
|
193
|
+
except Exception as e:
|
|
194
|
+
formatter.print_error(f"Failed to list folder children: {e}")
|
|
195
|
+
raise typer.Exit(1)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
@app.command("batch-get")
|
|
199
|
+
def get_folders_batch(
|
|
200
|
+
folder_rids: List[str] = typer.Argument(
|
|
201
|
+
..., help="Folder Resource Identifiers (space-separated)"
|
|
202
|
+
),
|
|
203
|
+
profile: Optional[str] = typer.Option(
|
|
204
|
+
None, "--profile", help="Profile name", autocompletion=complete_profile
|
|
205
|
+
),
|
|
206
|
+
format: str = typer.Option(
|
|
207
|
+
"table",
|
|
208
|
+
"--format",
|
|
209
|
+
"-f",
|
|
210
|
+
help="Output format (table, json, csv)",
|
|
211
|
+
autocompletion=complete_output_format,
|
|
212
|
+
),
|
|
213
|
+
output: Optional[str] = typer.Option(
|
|
214
|
+
None, "--output", "-o", help="Output file path"
|
|
215
|
+
),
|
|
216
|
+
):
|
|
217
|
+
"""Get multiple folders in a single request (max 1000)."""
|
|
218
|
+
try:
|
|
219
|
+
service = FolderService(profile=profile)
|
|
220
|
+
|
|
221
|
+
with SpinnerProgressTracker().track_spinner(
|
|
222
|
+
f"Fetching {len(folder_rids)} folders..."
|
|
223
|
+
):
|
|
224
|
+
folders = service.get_folders_batch(folder_rids)
|
|
225
|
+
|
|
226
|
+
# Cache RIDs for future completions
|
|
227
|
+
for folder in folders:
|
|
228
|
+
if folder.get("rid"):
|
|
229
|
+
cache_rid(folder["rid"])
|
|
230
|
+
|
|
231
|
+
# Format output
|
|
232
|
+
if format == "json":
|
|
233
|
+
if output:
|
|
234
|
+
formatter.save_to_file(folders, output, "json")
|
|
235
|
+
else:
|
|
236
|
+
formatter.format_list(folders)
|
|
237
|
+
elif format == "csv":
|
|
238
|
+
if output:
|
|
239
|
+
formatter.save_to_file(folders, output, "csv")
|
|
240
|
+
else:
|
|
241
|
+
formatter.format_list(folders)
|
|
242
|
+
else:
|
|
243
|
+
_format_folders_batch_table(folders)
|
|
244
|
+
|
|
245
|
+
if output:
|
|
246
|
+
formatter.print_success(f"Folders information saved to {output}")
|
|
247
|
+
|
|
248
|
+
except (ProfileNotFoundError, MissingCredentialsError) as e:
|
|
249
|
+
formatter.print_error(f"Authentication error: {e}")
|
|
250
|
+
raise typer.Exit(1)
|
|
251
|
+
except ValueError as e:
|
|
252
|
+
formatter.print_error(f"Invalid request: {e}")
|
|
253
|
+
raise typer.Exit(1)
|
|
254
|
+
except Exception as e:
|
|
255
|
+
formatter.print_error(f"Failed to get folders batch: {e}")
|
|
256
|
+
raise typer.Exit(1)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def _format_folder_table(folder: dict):
|
|
260
|
+
"""Format folder information as a table."""
|
|
261
|
+
table = Table(
|
|
262
|
+
title="Folder Information", show_header=True, header_style="bold cyan"
|
|
263
|
+
)
|
|
264
|
+
table.add_column("Property", style="cyan")
|
|
265
|
+
table.add_column("Value")
|
|
266
|
+
|
|
267
|
+
table.add_row("RID", folder.get("rid", "N/A"))
|
|
268
|
+
table.add_row("Display Name", folder.get("display_name", "N/A"))
|
|
269
|
+
table.add_row("Description", folder.get("description", "N/A"))
|
|
270
|
+
table.add_row("Parent Folder", folder.get("parent_folder_rid", "N/A"))
|
|
271
|
+
table.add_row("Created", folder.get("created", "N/A"))
|
|
272
|
+
table.add_row("Modified", folder.get("modified", "N/A"))
|
|
273
|
+
|
|
274
|
+
console.print(table)
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def _format_children_table(children: List[dict]):
|
|
278
|
+
"""Format folder children as a table."""
|
|
279
|
+
table = Table(title="Folder Children", show_header=True, header_style="bold cyan")
|
|
280
|
+
table.add_column("Type", style="cyan")
|
|
281
|
+
table.add_column("Display Name")
|
|
282
|
+
table.add_column("RID")
|
|
283
|
+
|
|
284
|
+
for child in children:
|
|
285
|
+
table.add_row(
|
|
286
|
+
child.get("type", "unknown"),
|
|
287
|
+
child.get("display_name", child.get("name", "N/A")),
|
|
288
|
+
child.get("rid", "N/A"),
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
console.print(table)
|
|
292
|
+
console.print(f"\nTotal: {len(children)} items")
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def _format_folders_batch_table(folders: List[dict]):
|
|
296
|
+
"""Format multiple folders as a table."""
|
|
297
|
+
table = Table(title="Folders", show_header=True, header_style="bold cyan")
|
|
298
|
+
table.add_column("Display Name")
|
|
299
|
+
table.add_column("RID")
|
|
300
|
+
table.add_column("Parent Folder")
|
|
301
|
+
table.add_column("Description")
|
|
302
|
+
|
|
303
|
+
for folder in folders:
|
|
304
|
+
table.add_row(
|
|
305
|
+
folder.get("display_name", "N/A"),
|
|
306
|
+
folder.get("rid", "N/A"),
|
|
307
|
+
folder.get("parent_folder_rid", "N/A"),
|
|
308
|
+
folder.get("description", "N/A") or "",
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
console.print(table)
|
|
312
|
+
console.print(f"\nTotal: {len(folders)} folders")
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
@app.callback()
|
|
316
|
+
def main():
|
|
317
|
+
"""
|
|
318
|
+
Folder operations using foundry-platform-sdk.
|
|
319
|
+
|
|
320
|
+
Manage folders in the Foundry filesystem. Create, retrieve, and list
|
|
321
|
+
folder contents using Resource Identifiers (RIDs).
|
|
322
|
+
|
|
323
|
+
The root folder RID is: ri.compass.main.folder.0
|
|
324
|
+
|
|
325
|
+
Examples:
|
|
326
|
+
# Create a folder in root
|
|
327
|
+
pltr folder create "My Folder"
|
|
328
|
+
|
|
329
|
+
# Create a folder in a specific parent
|
|
330
|
+
pltr folder create "Sub Folder" --parent-folder ri.compass.main.folder.xyz123
|
|
331
|
+
|
|
332
|
+
# List root folder contents
|
|
333
|
+
pltr folder list ri.compass.main.folder.0
|
|
334
|
+
|
|
335
|
+
# Get folder information
|
|
336
|
+
pltr folder get ri.compass.main.folder.xyz123
|
|
337
|
+
"""
|
|
338
|
+
pass
|