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.
@@ -0,0 +1,82 @@
1
+ """
2
+ Third-party applications management commands for Foundry.
3
+ """
4
+
5
+ import typer
6
+ from typing import Optional
7
+ from rich.console import Console
8
+
9
+ from ..services.third_party_applications import ThirdPartyApplicationsService
10
+ from ..utils.formatting import OutputFormatter
11
+ from ..utils.progress import SpinnerProgressTracker
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
+ )
19
+
20
+ app = typer.Typer(help="Manage third-party applications in Foundry")
21
+ console = Console()
22
+ formatter = OutputFormatter(console)
23
+
24
+
25
+ @app.command("get")
26
+ def get_application(
27
+ application_rid: str = typer.Argument(
28
+ ...,
29
+ help="Third-party application Resource Identifier",
30
+ autocompletion=complete_rid,
31
+ ),
32
+ profile: Optional[str] = typer.Option(
33
+ None,
34
+ "--profile",
35
+ "-p",
36
+ help="Profile name",
37
+ 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
+ output: Optional[str] = typer.Option(
47
+ None, "--output", "-o", help="Output file path"
48
+ ),
49
+ preview: bool = typer.Option(
50
+ False,
51
+ "--preview",
52
+ help="Enable preview mode",
53
+ ),
54
+ ):
55
+ """Get detailed information about a third-party application."""
56
+ try:
57
+ # Cache the RID for future completions
58
+ cache_rid(application_rid)
59
+
60
+ service = ThirdPartyApplicationsService(profile=profile)
61
+
62
+ with SpinnerProgressTracker().track_spinner(
63
+ f"Fetching third-party application {application_rid}..."
64
+ ):
65
+ application = service.get_application(application_rid, preview=preview)
66
+
67
+ # Format output
68
+ if output:
69
+ formatter.save_to_file(application, output, format)
70
+ formatter.print_success(f"Application information saved to {output}")
71
+ else:
72
+ formatter.display(application, format)
73
+
74
+ except (ProfileNotFoundError, MissingCredentialsError) as e:
75
+ formatter.print_error(f"Authentication error: {e}")
76
+ raise typer.Exit(1)
77
+ except ValueError as e:
78
+ formatter.print_error(f"Invalid request: {e}")
79
+ raise typer.Exit(1)
80
+ except Exception as e:
81
+ formatter.print_error(f"Failed to get third-party application: {e}")
82
+ raise typer.Exit(1)
pltr/services/admin.py CHANGED
@@ -3,10 +3,12 @@ Admin service wrapper for Foundry SDK admin operations.
3
3
  Provides a high-level interface for user, group, role, and organization management.
4
4
  """
5
5
 
6
- from typing import Any, Dict, Optional
6
+ from typing import Any, Dict, List, Optional, Callable
7
7
  import json
8
8
 
9
9
  from .base import BaseService
10
+ from ..utils.pagination import PaginationConfig, PaginationResult
11
+ from ..config.settings import Settings
10
12
 
11
13
 
12
14
  class AdminService(BaseService):
@@ -23,6 +25,8 @@ class AdminService(BaseService):
23
25
  """
24
26
  List all users in the organization.
25
27
 
28
+ DEPRECATED: Use list_users_paginated() instead for better pagination support.
29
+
26
30
  Args:
27
31
  page_size: Maximum number of users to return per page
28
32
  page_token: Token for pagination (from previous response)
@@ -38,6 +42,42 @@ class AdminService(BaseService):
38
42
  except Exception as e:
39
43
  raise RuntimeError(f"Failed to list users: {str(e)}")
40
44
 
45
+ def list_users_paginated(
46
+ self,
47
+ config: PaginationConfig,
48
+ progress_callback: Optional[Callable[[int, int], None]] = None,
49
+ ) -> PaginationResult:
50
+ """
51
+ List users with full pagination control.
52
+
53
+ Args:
54
+ config: Pagination configuration (page_size, max_pages, etc.)
55
+ progress_callback: Optional callback(page_num, items_count)
56
+
57
+ Returns:
58
+ PaginationResult with users and metadata
59
+
60
+ Example:
61
+ >>> config = PaginationConfig(page_size=50, max_pages=2)
62
+ >>> result = service.list_users_paginated(config)
63
+ >>> print(f"Fetched {result.metadata.items_fetched} users")
64
+ """
65
+ try:
66
+ settings = Settings()
67
+
68
+ def fetch_page(page_token: Optional[str]) -> Dict[str, Any]:
69
+ """Fetch a single page of users."""
70
+ response = self.service.User.list(
71
+ page_size=config.page_size or settings.get("page_size", 20),
72
+ page_token=page_token,
73
+ )
74
+ return self._serialize_response(response)
75
+
76
+ # Use response pagination handler
77
+ return self._paginate_response(fetch_page, config, progress_callback)
78
+ except Exception as e:
79
+ raise RuntimeError(f"Failed to list users: {str(e)}")
80
+
41
81
  def get_user(self, user_id: str) -> Dict[str, Any]:
42
82
  """
43
83
  Get a specific user by ID.
@@ -127,6 +167,43 @@ class AdminService(BaseService):
127
167
  except Exception as e:
128
168
  raise RuntimeError(f"Failed to revoke tokens for user {user_id}: {str(e)}")
129
169
 
170
+ def delete_user(self, user_id: str) -> Dict[str, Any]:
171
+ """
172
+ Delete a specific user.
173
+
174
+ Args:
175
+ user_id: The user ID or RID
176
+
177
+ Returns:
178
+ Dictionary containing operation result
179
+ """
180
+ try:
181
+ self.service.User.delete(user_id)
182
+ return {
183
+ "success": True,
184
+ "message": f"User {user_id} deleted successfully",
185
+ }
186
+ except Exception as e:
187
+ raise RuntimeError(f"Failed to delete user {user_id}: {str(e)}")
188
+
189
+ def get_batch_users(self, user_ids: List[str]) -> Dict[str, Any]:
190
+ """
191
+ Batch retrieve multiple users (up to 500).
192
+
193
+ Args:
194
+ user_ids: List of user IDs or RIDs
195
+
196
+ Returns:
197
+ Dictionary containing user information
198
+ """
199
+ if len(user_ids) > 500:
200
+ raise ValueError("Maximum batch size is 500 users")
201
+ try:
202
+ response = self.service.User.get_batch(body=user_ids)
203
+ return self._serialize_response(response)
204
+ except Exception as e:
205
+ raise RuntimeError(f"Failed to get users batch: {str(e)}")
206
+
130
207
  # Group Management Methods
131
208
  def list_groups(
132
209
  self, page_size: Optional[int] = None, page_token: Optional[str] = None
@@ -239,6 +316,136 @@ class AdminService(BaseService):
239
316
  except Exception as e:
240
317
  raise RuntimeError(f"Failed to delete group {group_id}: {str(e)}")
241
318
 
319
+ def get_batch_groups(self, group_ids: List[str]) -> Dict[str, Any]:
320
+ """
321
+ Batch retrieve multiple groups (up to 500).
322
+
323
+ Args:
324
+ group_ids: List of group IDs or RIDs
325
+
326
+ Returns:
327
+ Dictionary containing group information
328
+ """
329
+ if len(group_ids) > 500:
330
+ raise ValueError("Maximum batch size is 500 groups")
331
+ try:
332
+ response = self.service.Group.get_batch(body=group_ids)
333
+ return self._serialize_response(response)
334
+ except Exception as e:
335
+ raise RuntimeError(f"Failed to get groups batch: {str(e)}")
336
+
337
+ # Marking Management Methods
338
+ def list_markings(
339
+ self, page_size: Optional[int] = None, page_token: Optional[str] = None
340
+ ) -> Dict[str, Any]:
341
+ """
342
+ List all markings.
343
+
344
+ Args:
345
+ page_size: Maximum number of markings to return per page
346
+ page_token: Token for pagination (from previous response)
347
+
348
+ Returns:
349
+ Dictionary containing marking list and pagination info
350
+ """
351
+ try:
352
+ response = self.service.Marking.list(
353
+ page_size=page_size, page_token=page_token, preview=True
354
+ )
355
+ return self._serialize_response(response)
356
+ except Exception as e:
357
+ raise RuntimeError(f"Failed to list markings: {str(e)}")
358
+
359
+ def get_marking(self, marking_id: str) -> Dict[str, Any]:
360
+ """
361
+ Get a specific marking by ID.
362
+
363
+ Args:
364
+ marking_id: The marking ID
365
+
366
+ Returns:
367
+ Dictionary containing marking information
368
+ """
369
+ try:
370
+ response = self.service.Marking.get(marking_id, preview=True)
371
+ return self._serialize_response(response)
372
+ except Exception as e:
373
+ raise RuntimeError(f"Failed to get marking {marking_id}: {str(e)}")
374
+
375
+ def get_batch_markings(self, marking_ids: List[str]) -> Dict[str, Any]:
376
+ """
377
+ Batch retrieve multiple markings (up to 500).
378
+
379
+ Args:
380
+ marking_ids: List of marking IDs
381
+
382
+ Returns:
383
+ Dictionary containing marking information
384
+ """
385
+ if len(marking_ids) > 500:
386
+ raise ValueError("Maximum batch size is 500 markings")
387
+ try:
388
+ response = self.service.Marking.get_batch(body=marking_ids, preview=True)
389
+ return self._serialize_response(response)
390
+ except Exception as e:
391
+ raise RuntimeError(f"Failed to get markings batch: {str(e)}")
392
+
393
+ def create_marking(
394
+ self,
395
+ name: str,
396
+ description: Optional[str] = None,
397
+ category_id: Optional[str] = None,
398
+ ) -> Dict[str, Any]:
399
+ """
400
+ Create a new marking.
401
+
402
+ Args:
403
+ name: The marking name
404
+ description: Optional marking description
405
+ category_id: Optional category ID for the marking
406
+
407
+ Returns:
408
+ Dictionary containing created marking information
409
+ """
410
+ try:
411
+ create_params: Dict[str, Any] = {"name": name, "preview": True}
412
+ if description:
413
+ create_params["description"] = description
414
+ if category_id:
415
+ create_params["category_id"] = category_id
416
+
417
+ response = self.service.Marking.create(**create_params)
418
+ return self._serialize_response(response)
419
+ except Exception as e:
420
+ raise RuntimeError(f"Failed to create marking '{name}': {str(e)}")
421
+
422
+ def replace_marking(
423
+ self,
424
+ marking_id: str,
425
+ name: str,
426
+ description: Optional[str] = None,
427
+ ) -> Dict[str, Any]:
428
+ """
429
+ Replace/update an existing marking.
430
+
431
+ Args:
432
+ marking_id: The marking ID
433
+ name: The new marking name
434
+ description: Optional new marking description
435
+
436
+ Returns:
437
+ Dictionary containing updated marking information
438
+ """
439
+ try:
440
+ replace_params: Dict[str, Any] = {"name": name, "preview": True}
441
+ if description:
442
+ replace_params["description"] = description
443
+
444
+ response = self.service.Marking.replace(marking_id, **replace_params)
445
+ return self._serialize_response(response)
446
+ except Exception as e:
447
+ raise RuntimeError(f"Failed to replace marking {marking_id}: {str(e)}")
448
+
242
449
  # Organization Management Methods
243
450
  def get_organization(self, organization_id: str) -> Dict[str, Any]:
244
451
  """
@@ -258,6 +465,98 @@ class AdminService(BaseService):
258
465
  f"Failed to get organization {organization_id}: {str(e)}"
259
466
  )
260
467
 
468
+ def create_organization(
469
+ self,
470
+ name: str,
471
+ enrollment_rid: str,
472
+ admin_ids: Optional[List[str]] = None,
473
+ ) -> Dict[str, Any]:
474
+ """
475
+ Create a new organization.
476
+
477
+ Args:
478
+ name: The organization name
479
+ enrollment_rid: The enrollment RID
480
+ admin_ids: Optional list of admin user IDs
481
+
482
+ Returns:
483
+ Dictionary containing created organization information
484
+ """
485
+ try:
486
+ create_params: Dict[str, Any] = {
487
+ "name": name,
488
+ "enrollment_rid": enrollment_rid,
489
+ "preview": True,
490
+ }
491
+ if admin_ids:
492
+ create_params["admin_ids"] = admin_ids
493
+
494
+ response = self.service.Organization.create(**create_params)
495
+ return self._serialize_response(response)
496
+ except Exception as e:
497
+ raise RuntimeError(f"Failed to create organization '{name}': {str(e)}")
498
+
499
+ def replace_organization(
500
+ self,
501
+ organization_rid: str,
502
+ name: str,
503
+ description: Optional[str] = None,
504
+ ) -> Dict[str, Any]:
505
+ """
506
+ Replace/update an existing organization.
507
+
508
+ Args:
509
+ organization_rid: The organization RID
510
+ name: The new organization name
511
+ description: Optional new organization description
512
+
513
+ Returns:
514
+ Dictionary containing updated organization information
515
+ """
516
+ try:
517
+ replace_params: Dict[str, Any] = {"name": name, "preview": True}
518
+ if description:
519
+ replace_params["description"] = description
520
+
521
+ response = self.service.Organization.replace(
522
+ organization_rid, **replace_params
523
+ )
524
+ return self._serialize_response(response)
525
+ except Exception as e:
526
+ raise RuntimeError(
527
+ f"Failed to replace organization {organization_rid}: {str(e)}"
528
+ )
529
+
530
+ def list_available_roles(
531
+ self,
532
+ organization_rid: str,
533
+ page_size: Optional[int] = None,
534
+ page_token: Optional[str] = None,
535
+ ) -> Dict[str, Any]:
536
+ """
537
+ List available roles for an organization.
538
+
539
+ Args:
540
+ organization_rid: The organization RID
541
+ page_size: Maximum number of roles to return per page
542
+ page_token: Token for pagination (from previous response)
543
+
544
+ Returns:
545
+ Dictionary containing role list and pagination info
546
+ """
547
+ try:
548
+ response = self.service.Organization.list_available_roles(
549
+ organization_rid,
550
+ page_size=page_size,
551
+ page_token=page_token,
552
+ preview=True,
553
+ )
554
+ return self._serialize_response(response)
555
+ except Exception as e:
556
+ raise RuntimeError(
557
+ f"Failed to list available roles for organization {organization_rid}: {str(e)}"
558
+ )
559
+
261
560
  # Role Management Methods
262
561
  def get_role(self, role_id: str) -> Dict[str, Any]:
263
562
  """
@@ -275,6 +574,24 @@ class AdminService(BaseService):
275
574
  except Exception as e:
276
575
  raise RuntimeError(f"Failed to get role {role_id}: {str(e)}")
277
576
 
577
+ def get_batch_roles(self, role_ids: List[str]) -> Dict[str, Any]:
578
+ """
579
+ Batch retrieve multiple roles (up to 500).
580
+
581
+ Args:
582
+ role_ids: List of role IDs or RIDs
583
+
584
+ Returns:
585
+ Dictionary containing role information
586
+ """
587
+ if len(role_ids) > 500:
588
+ raise ValueError("Maximum batch size is 500 roles")
589
+ try:
590
+ response = self.service.Role.get_batch(body=role_ids, preview=True)
591
+ return self._serialize_response(response)
592
+ except Exception as e:
593
+ raise RuntimeError(f"Failed to get roles batch: {str(e)}")
594
+
278
595
  def _serialize_response(self, response: Any) -> Dict[str, Any]:
279
596
  """
280
597
  Convert response object to serializable dictionary.
@@ -0,0 +1,147 @@
1
+ """
2
+ AIP Agents service wrapper for Foundry SDK.
3
+ Provides access to AIP Agent operations including agent details, sessions, and versions.
4
+ """
5
+
6
+ from typing import Any, Dict, Optional
7
+ from .base import BaseService
8
+ from ..utils.pagination import PaginationConfig, PaginationResult
9
+
10
+
11
+ class AipAgentsService(BaseService):
12
+ """Service wrapper for Foundry AIP Agents operations."""
13
+
14
+ def _get_service(self) -> Any:
15
+ """Get the Foundry AIP agents service."""
16
+ return self.client.aip_agents
17
+
18
+ # ===== Agent Operations =====
19
+
20
+ def get_agent(
21
+ self, agent_rid: str, version: Optional[str] = None, preview: bool = True
22
+ ) -> Dict[str, Any]:
23
+ """
24
+ Get details for an AIP Agent.
25
+
26
+ Args:
27
+ agent_rid: Agent Resource Identifier
28
+ Format: ri.foundry.main.agent.<id>
29
+ version: Optional agent version string (e.g., "1.0")
30
+ If not specified, returns latest published version
31
+ preview: Enable preview mode (default: True)
32
+
33
+ Returns:
34
+ Agent information dictionary containing:
35
+ - rid: Agent resource identifier
36
+ - version: Agent version
37
+ - metadata: Agent metadata (displayName, description, etc.)
38
+ - parameters: Application variables/parameters
39
+
40
+ Raises:
41
+ RuntimeError: If the operation fails
42
+
43
+ Example:
44
+ >>> service = AipAgentsService()
45
+ >>> agent = service.get_agent("ri.foundry.main.agent.abc123")
46
+ >>> print(agent['metadata']['displayName'])
47
+ """
48
+ try:
49
+ agent = self.service.Agent.get(agent_rid, version=version, preview=preview)
50
+ return self._serialize_response(agent)
51
+ except Exception as e:
52
+ raise RuntimeError(f"Failed to get agent {agent_rid}: {e}")
53
+
54
+ # ===== Session Operations =====
55
+
56
+ def list_sessions(
57
+ self, agent_rid: str, config: PaginationConfig, preview: bool = True
58
+ ) -> PaginationResult:
59
+ """
60
+ List all conversation sessions for an agent created by the calling user.
61
+
62
+ Note: Only lists sessions created by this client, not sessions created
63
+ in AIP Agent Studio.
64
+
65
+ Args:
66
+ agent_rid: Agent Resource Identifier
67
+ config: Pagination configuration
68
+ preview: Enable preview mode (default: True)
69
+
70
+ Returns:
71
+ PaginationResult with sessions and metadata
72
+
73
+ Example:
74
+ >>> config = PaginationConfig(page_size=20, max_pages=2)
75
+ >>> result = service.list_sessions(agent_rid, config)
76
+ >>> print(f"Found {result.metadata.items_fetched} sessions")
77
+ """
78
+ try:
79
+ iterator = self.service.Agent.Session.list(
80
+ agent_rid, page_size=config.page_size, preview=preview
81
+ )
82
+ return self._paginate_iterator(iterator, config)
83
+ except Exception as e:
84
+ raise RuntimeError(f"Failed to list sessions for agent {agent_rid}: {e}")
85
+
86
+ def get_session(
87
+ self, agent_rid: str, session_rid: str, preview: bool = True
88
+ ) -> Dict[str, Any]:
89
+ """
90
+ Get details of a specific conversation session.
91
+
92
+ Args:
93
+ agent_rid: Agent Resource Identifier
94
+ session_rid: Session Resource Identifier
95
+ preview: Enable preview mode (default: True)
96
+
97
+ Returns:
98
+ Session information dictionary containing:
99
+ - rid: Session resource identifier
100
+ - agent_rid: Associated agent RID
101
+ - agent_version: Agent version used in session
102
+ - metadata: Session metadata (e.g., title)
103
+
104
+ Raises:
105
+ RuntimeError: If the operation fails
106
+ """
107
+ try:
108
+ session = self.service.Agent.Session.get(
109
+ agent_rid, session_rid, preview=preview
110
+ )
111
+ return self._serialize_response(session)
112
+ except Exception as e:
113
+ raise RuntimeError(
114
+ f"Failed to get session {session_rid} for agent {agent_rid}: {e}"
115
+ )
116
+
117
+ # ===== Version Operations =====
118
+
119
+ def list_versions(
120
+ self, agent_rid: str, config: PaginationConfig, preview: bool = True
121
+ ) -> PaginationResult:
122
+ """
123
+ List all versions for an AIP Agent.
124
+
125
+ Versions are returned in descending order (most recent first).
126
+
127
+ Args:
128
+ agent_rid: Agent Resource Identifier
129
+ config: Pagination configuration
130
+ preview: Enable preview mode (default: True)
131
+
132
+ Returns:
133
+ PaginationResult with agent versions and metadata
134
+
135
+ Example:
136
+ >>> config = PaginationConfig(page_size=10, fetch_all=True)
137
+ >>> result = service.list_versions(agent_rid, config)
138
+ >>> for version in result.data:
139
+ ... print(f"Version {version['string']}")
140
+ """
141
+ try:
142
+ iterator = self.service.Agent.AgentVersion.list(
143
+ agent_rid, page_size=config.page_size, preview=preview
144
+ )
145
+ return self._paginate_iterator(iterator, config)
146
+ except Exception as e:
147
+ raise RuntimeError(f"Failed to list versions for agent {agent_rid}: {e}")