pltr-cli 0.3.0__py3-none-any.whl → 0.4.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 +2 -0
- pltr/commands/folder.py +338 -0
- pltr/services/folder.py +167 -0
- {pltr_cli-0.3.0.dist-info → pltr_cli-0.4.0.dist-info}/METADATA +10 -3
- {pltr_cli-0.3.0.dist-info → pltr_cli-0.4.0.dist-info}/RECORD +8 -6
- {pltr_cli-0.3.0.dist-info → pltr_cli-0.4.0.dist-info}/WHEEL +0 -0
- {pltr_cli-0.3.0.dist-info → pltr_cli-0.4.0.dist-info}/entry_points.txt +0 -0
- {pltr_cli-0.3.0.dist-info → pltr_cli-0.4.0.dist-info}/licenses/LICENSE +0 -0
pltr/cli.py
CHANGED
|
@@ -10,6 +10,7 @@ from pltr.commands import (
|
|
|
10
10
|
configure,
|
|
11
11
|
verify,
|
|
12
12
|
dataset,
|
|
13
|
+
folder,
|
|
13
14
|
ontology,
|
|
14
15
|
sql,
|
|
15
16
|
admin,
|
|
@@ -28,6 +29,7 @@ app = typer.Typer(
|
|
|
28
29
|
app.add_typer(configure.app, name="configure", help="Manage authentication profiles")
|
|
29
30
|
app.add_typer(verify.app, name="verify", help="Verify authentication")
|
|
30
31
|
app.add_typer(dataset.app, name="dataset", help="Manage datasets")
|
|
32
|
+
app.add_typer(folder.app, name="folder", help="Manage folders")
|
|
31
33
|
app.add_typer(ontology.app, name="ontology", help="Ontology operations")
|
|
32
34
|
app.add_typer(sql.app, name="sql", help="Execute SQL queries")
|
|
33
35
|
app.add_typer(
|
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
|
pltr/services/folder.py
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Folder service wrapper for Foundry SDK filesystem API.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Any, Optional, Dict, List
|
|
6
|
+
|
|
7
|
+
from .base import BaseService
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FolderService(BaseService):
|
|
11
|
+
"""Service wrapper for Foundry folder operations using filesystem API."""
|
|
12
|
+
|
|
13
|
+
def _get_service(self) -> Any:
|
|
14
|
+
"""Get the Foundry filesystem service."""
|
|
15
|
+
return self.client.filesystem
|
|
16
|
+
|
|
17
|
+
def create_folder(
|
|
18
|
+
self, display_name: str, parent_folder_rid: str
|
|
19
|
+
) -> Dict[str, Any]:
|
|
20
|
+
"""
|
|
21
|
+
Create a new folder.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
display_name: Folder display name
|
|
25
|
+
parent_folder_rid: Parent folder RID (use 'ri.compass.main.folder.0' for root)
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
Created folder information
|
|
29
|
+
"""
|
|
30
|
+
try:
|
|
31
|
+
folder = self.service.Folder.create(
|
|
32
|
+
display_name=display_name,
|
|
33
|
+
parent_folder_rid=parent_folder_rid,
|
|
34
|
+
preview=True,
|
|
35
|
+
)
|
|
36
|
+
return self._format_folder_info(folder)
|
|
37
|
+
except Exception as e:
|
|
38
|
+
raise RuntimeError(f"Failed to create folder '{display_name}': {e}")
|
|
39
|
+
|
|
40
|
+
def get_folder(self, folder_rid: str) -> Dict[str, Any]:
|
|
41
|
+
"""
|
|
42
|
+
Get information about a specific folder.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
folder_rid: Folder Resource Identifier
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
Folder information dictionary
|
|
49
|
+
"""
|
|
50
|
+
try:
|
|
51
|
+
folder = self.service.Folder.get(folder_rid, preview=True)
|
|
52
|
+
return self._format_folder_info(folder)
|
|
53
|
+
except Exception as e:
|
|
54
|
+
raise RuntimeError(f"Failed to get folder {folder_rid}: {e}")
|
|
55
|
+
|
|
56
|
+
def list_children(
|
|
57
|
+
self,
|
|
58
|
+
folder_rid: str,
|
|
59
|
+
page_size: Optional[int] = None,
|
|
60
|
+
page_token: Optional[str] = None,
|
|
61
|
+
) -> List[Dict[str, Any]]:
|
|
62
|
+
"""
|
|
63
|
+
List all child resources of a folder.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
folder_rid: Folder Resource Identifier
|
|
67
|
+
page_size: Number of items per page (optional)
|
|
68
|
+
page_token: Pagination token (optional)
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
List of child resources
|
|
72
|
+
"""
|
|
73
|
+
try:
|
|
74
|
+
children = []
|
|
75
|
+
# The children method returns an iterator
|
|
76
|
+
for child in self.service.Folder.children(
|
|
77
|
+
folder_rid, page_size=page_size, page_token=page_token, preview=True
|
|
78
|
+
):
|
|
79
|
+
children.append(self._format_resource_info(child))
|
|
80
|
+
return children
|
|
81
|
+
except Exception as e:
|
|
82
|
+
raise RuntimeError(f"Failed to list children of folder {folder_rid}: {e}")
|
|
83
|
+
|
|
84
|
+
def get_folders_batch(self, folder_rids: List[str]) -> List[Dict[str, Any]]:
|
|
85
|
+
"""
|
|
86
|
+
Get multiple folders in a single request.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
folder_rids: List of folder RIDs (max 1000)
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
List of folder information dictionaries
|
|
93
|
+
"""
|
|
94
|
+
if len(folder_rids) > 1000:
|
|
95
|
+
raise ValueError("Maximum batch size is 1000 folders")
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
response = self.service.Folder.get_batch(body=folder_rids, preview=True)
|
|
99
|
+
folders = []
|
|
100
|
+
for folder in response.folders:
|
|
101
|
+
folders.append(self._format_folder_info(folder))
|
|
102
|
+
return folders
|
|
103
|
+
except Exception as e:
|
|
104
|
+
raise RuntimeError(f"Failed to get folders batch: {e}")
|
|
105
|
+
|
|
106
|
+
def _format_folder_info(self, folder: Any) -> Dict[str, Any]:
|
|
107
|
+
"""
|
|
108
|
+
Format folder information for consistent output.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
folder: Folder object from Foundry SDK
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
Formatted folder information dictionary
|
|
115
|
+
"""
|
|
116
|
+
return {
|
|
117
|
+
"rid": getattr(folder, "rid", None),
|
|
118
|
+
"display_name": getattr(folder, "display_name", None),
|
|
119
|
+
"description": getattr(folder, "description", None),
|
|
120
|
+
"created": self._format_timestamp(getattr(folder, "created", None)),
|
|
121
|
+
"modified": self._format_timestamp(getattr(folder, "modified", None)),
|
|
122
|
+
"parent_folder_rid": getattr(folder, "parent_folder_rid", None),
|
|
123
|
+
"type": "folder",
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
def _format_resource_info(self, resource: Any) -> Dict[str, Any]:
|
|
127
|
+
"""
|
|
128
|
+
Format resource information (can be folder, dataset, etc.).
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
resource: Resource object from Foundry SDK
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
Formatted resource information dictionary
|
|
135
|
+
"""
|
|
136
|
+
resource_type = getattr(resource, "type", "unknown")
|
|
137
|
+
base_info = {
|
|
138
|
+
"rid": getattr(resource, "rid", None),
|
|
139
|
+
"display_name": getattr(resource, "display_name", None),
|
|
140
|
+
"type": resource_type,
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
# Add type-specific fields
|
|
144
|
+
if resource_type == "folder":
|
|
145
|
+
base_info["description"] = getattr(resource, "description", None)
|
|
146
|
+
elif resource_type == "dataset":
|
|
147
|
+
base_info["name"] = getattr(resource, "name", None)
|
|
148
|
+
|
|
149
|
+
return base_info
|
|
150
|
+
|
|
151
|
+
def _format_timestamp(self, timestamp: Any) -> Optional[str]:
|
|
152
|
+
"""
|
|
153
|
+
Format timestamp for display.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
timestamp: Timestamp object from SDK
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
Formatted timestamp string or None
|
|
160
|
+
"""
|
|
161
|
+
if timestamp is None:
|
|
162
|
+
return None
|
|
163
|
+
|
|
164
|
+
# Handle different timestamp formats from the SDK
|
|
165
|
+
if hasattr(timestamp, "time"):
|
|
166
|
+
return str(timestamp.time)
|
|
167
|
+
return str(timestamp)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pltr-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Command-line interface for Palantir Foundry APIs
|
|
5
5
|
Project-URL: Homepage, https://github.com/anjor/pltr-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/anjor/pltr-cli
|
|
@@ -37,7 +37,7 @@ Description-Content-Type: text/markdown
|
|
|
37
37
|
|
|
38
38
|
# pltr-cli
|
|
39
39
|
|
|
40
|
-
A comprehensive command-line interface for Palantir Foundry APIs, providing
|
|
40
|
+
A comprehensive command-line interface for Palantir Foundry APIs, providing 70+ commands for data analysis, ontology operations, SQL queries, folder management, and administrative tasks.
|
|
41
41
|
|
|
42
42
|
## Overview
|
|
43
43
|
|
|
@@ -47,6 +47,7 @@ A comprehensive command-line interface for Palantir Foundry APIs, providing 65+
|
|
|
47
47
|
|
|
48
48
|
- 🔐 **Secure Authentication**: Token and OAuth2 support with encrypted credential storage
|
|
49
49
|
- 📊 **Dataset Operations**: Get dataset information and create new datasets (RID-based API)
|
|
50
|
+
- 📁 **Folder Management**: Create, explore, and manage Foundry filesystem structure
|
|
50
51
|
- 🎯 **Comprehensive Ontology Access**: 13 commands for objects, actions, and queries
|
|
51
52
|
- 📝 **Full SQL Support**: Execute, submit, monitor, and export query results
|
|
52
53
|
- 👥 **Admin Operations**: User, group, role, and organization management (16 commands)
|
|
@@ -109,6 +110,12 @@ pltr admin user current
|
|
|
109
110
|
# List available ontologies
|
|
110
111
|
pltr ontology list
|
|
111
112
|
|
|
113
|
+
# Create a new folder
|
|
114
|
+
pltr folder create "My Project"
|
|
115
|
+
|
|
116
|
+
# List root folder contents
|
|
117
|
+
pltr folder list ri.compass.main.folder.0
|
|
118
|
+
|
|
112
119
|
# Execute a simple SQL query
|
|
113
120
|
pltr sql execute "SELECT 1 as test"
|
|
114
121
|
|
|
@@ -133,7 +140,7 @@ pltr-cli provides comprehensive documentation to help you get the most out of th
|
|
|
133
140
|
### 📖 User Guides
|
|
134
141
|
- **[Quick Start Guide](docs/user-guide/quick-start.md)** - Get up and running in 5 minutes
|
|
135
142
|
- **[Authentication Setup](docs/user-guide/authentication.md)** - Complete guide to token and OAuth2 setup
|
|
136
|
-
- **[Command Reference](docs/user-guide/commands.md)** - Complete reference for all
|
|
143
|
+
- **[Command Reference](docs/user-guide/commands.md)** - Complete reference for all 70+ commands
|
|
137
144
|
- **[Common Workflows](docs/user-guide/workflows.md)** - Real-world data analysis patterns
|
|
138
145
|
- **[Troubleshooting](docs/user-guide/troubleshooting.md)** - Solutions to common issues
|
|
139
146
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
pltr/__init__.py,sha256=kUR5RAFc7HCeiqdlX36dZOHkUI5wI6V_43RpEcD8b-0,22
|
|
2
2
|
pltr/__main__.py,sha256=HWJ49UoAYBQCf8kjuySPmBTuUjTZrOx-y6PzMTyS1KE,879
|
|
3
|
-
pltr/cli.py,sha256=
|
|
3
|
+
pltr/cli.py,sha256=cogkxi-J2hKrWKzjRFy6GLvcsPfrE_r_pAG6EMmuJ8s,1955
|
|
4
4
|
pltr/auth/__init__.py,sha256=G0V-Rh25FaJsH2nhrf146XQQG_ApdbyPJNuHJC25kgk,38
|
|
5
5
|
pltr/auth/base.py,sha256=LvmCwS7A0q0CITcym8udPzdACL52_jSGusiaeCTOaE8,981
|
|
6
6
|
pltr/auth/manager.py,sha256=ZqlGefr1a8MGx0g7kkQhpmiuVp0XTg3f43yMBCk-IRo,4305
|
|
@@ -13,6 +13,7 @@ pltr/commands/alias.py,sha256=r9xMsQNrGvaixSlspzoO2IXQ44LFXuZM4itt8vC0dRc,6862
|
|
|
13
13
|
pltr/commands/completion.py,sha256=YTxaRL4-rDs5n7aXf3ogFsxbHVJUBo_HiBbd0fbBPZ0,10870
|
|
14
14
|
pltr/commands/configure.py,sha256=oYj-VlOEj3MDwtB2RC4bYOYzI_sXTanPnz7y1GmMTqY,4800
|
|
15
15
|
pltr/commands/dataset.py,sha256=BCYfaBpLji5wasOiH_jOqO-JC9ScfJhodox9kl9W2Cw,3609
|
|
16
|
+
pltr/commands/folder.py,sha256=IAPPA3Smk1IWqThneEtZ08Zp79vDKVUabSkL_nDvUWk,10679
|
|
16
17
|
pltr/commands/ontology.py,sha256=zUgSrmv8xi26SQK7GsM3qusgR9Wuka0GyzE7L8DkduE,18317
|
|
17
18
|
pltr/commands/shell.py,sha256=QLF7TEGpaau9i0A9s3VjnegvtHde-SLRqI4suJFT4WI,3622
|
|
18
19
|
pltr/commands/sql.py,sha256=wol0Rlvi_RplCFbOg4LCa3VXsOqmRZdFFVv7V6iVkh8,12602
|
|
@@ -27,6 +28,7 @@ pltr/services/base.py,sha256=R2G781FI-sXtjUyLd91bVnmLb4cYZI3G8U5ndR9NLA4,1593
|
|
|
27
28
|
pltr/services/dataset.py,sha256=W3zoh-9YIJ6HBsDijejVEngKvpudFoZinYtHDmAXCOc,2785
|
|
28
29
|
pltr/services/dataset_full.py,sha256=FyMiwOSyX1cUrYXaK0T_1iq5G_X0e5iZTibJHuEmMeE,9869
|
|
29
30
|
pltr/services/dataset_v2.py,sha256=_uhcVJ91w_Y07glceqHceccAwPWr6q1TWSIqcP1FU8I,4259
|
|
31
|
+
pltr/services/folder.py,sha256=mWElyvn-wXPB5sv8Ik_dLeW5JM6jZg3g9KKBk6UcrlQ,5389
|
|
30
32
|
pltr/services/ontology.py,sha256=iW7qRK8ptlw-u4eAwLNC-mdzLoLZzh7SRqJyok2c3GU,14883
|
|
31
33
|
pltr/services/sql.py,sha256=19cscjlzN8WE1s8_ctiRcrOvMzCfmWRj49vjJ8Gs5Q4,11286
|
|
32
34
|
pltr/utils/__init__.py,sha256=DF7TigL1XbKVGM5VjgU8_8AGIszofkdO80oCzLGGnTE,38
|
|
@@ -34,8 +36,8 @@ pltr/utils/alias_resolver.py,sha256=DIF7P1UnUU8kqocJfIDEWjYq4s8_0KfqRZBbECeZEh8,
|
|
|
34
36
|
pltr/utils/completion.py,sha256=bjeqjleEfB2YcQFpcxvF0GoQ763F6KBbULSZC4FWY_g,4980
|
|
35
37
|
pltr/utils/formatting.py,sha256=Ptv7obiB7uWNf5YTiY4rUAKmabO5UGnwLocSfLplrZ0,18552
|
|
36
38
|
pltr/utils/progress.py,sha256=BKYbiLO61uhQbibabU7pxvvbAWMRLRmqk4pZldBQK_g,9053
|
|
37
|
-
pltr_cli-0.
|
|
38
|
-
pltr_cli-0.
|
|
39
|
-
pltr_cli-0.
|
|
40
|
-
pltr_cli-0.
|
|
41
|
-
pltr_cli-0.
|
|
39
|
+
pltr_cli-0.4.0.dist-info/METADATA,sha256=RDHEVijMZLcjzM8fBjaNm8DQsY0PIK8339CbDK64s-s,9096
|
|
40
|
+
pltr_cli-0.4.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
41
|
+
pltr_cli-0.4.0.dist-info/entry_points.txt,sha256=8tvEcW04kA_oAE2Dwwu-Og9efjl4ESJvs4AzlP2KBdQ,38
|
|
42
|
+
pltr_cli-0.4.0.dist-info/licenses/LICENSE,sha256=6VUFd_ytnOBD2O1tmkKrA-smigi9QEhYr_tge4h4z8Y,1070
|
|
43
|
+
pltr_cli-0.4.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|