pltr-cli 0.4.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.
@@ -0,0 +1,457 @@
1
+ """
2
+ Orchestration service wrapper for Foundry SDK v2 API.
3
+ Provides operations for managing builds, jobs, and schedules.
4
+ """
5
+
6
+ from typing import Any, Optional, Dict, List
7
+
8
+ from .base import BaseService
9
+
10
+
11
+ class OrchestrationService(BaseService):
12
+ """Service wrapper for Foundry orchestration operations using v2 API."""
13
+
14
+ def _get_service(self) -> Any:
15
+ """Get the Foundry orchestration service."""
16
+ return self.client.orchestration
17
+
18
+ # Build operations
19
+ def get_build(self, build_rid: str) -> Dict[str, Any]:
20
+ """
21
+ Get information about a specific build.
22
+
23
+ Args:
24
+ build_rid: Build Resource Identifier
25
+
26
+ Returns:
27
+ Build information dictionary
28
+ """
29
+ try:
30
+ build = self.service.Build.get(build_rid)
31
+ return self._format_build_info(build)
32
+ except Exception as e:
33
+ raise RuntimeError(f"Failed to get build {build_rid}: {e}")
34
+
35
+ def create_build(
36
+ self,
37
+ target: Dict[str, Any],
38
+ fallback_branches: Optional[Dict[str, Any]] = None,
39
+ abort_on_failure: Optional[bool] = None,
40
+ branch_name: Optional[str] = None,
41
+ force_build: Optional[bool] = None,
42
+ notifications_enabled: Optional[bool] = None,
43
+ retry_backoff_duration: Optional[int] = None,
44
+ retry_count: Optional[int] = None,
45
+ ) -> Dict[str, Any]:
46
+ """
47
+ Create a new build.
48
+
49
+ Args:
50
+ target: Build target configuration
51
+ fallback_branches: Fallback branches configuration
52
+ abort_on_failure: Whether to abort on failure
53
+ branch_name: Branch name for the build
54
+ force_build: Force build even if no changes
55
+ notifications_enabled: Enable notifications
56
+ retry_backoff_duration: Retry backoff duration in milliseconds
57
+ retry_count: Number of retries
58
+
59
+ Returns:
60
+ Created build information
61
+ """
62
+ try:
63
+ kwargs: Dict[str, Any] = {
64
+ "target": target,
65
+ "fallback_branches": fallback_branches or {},
66
+ }
67
+
68
+ # Add optional parameters if provided
69
+ if abort_on_failure is not None:
70
+ kwargs["abort_on_failure"] = abort_on_failure
71
+ if branch_name is not None:
72
+ kwargs["branch_name"] = branch_name
73
+ if force_build is not None:
74
+ kwargs["force_build"] = force_build
75
+ if notifications_enabled is not None:
76
+ kwargs["notifications_enabled"] = notifications_enabled
77
+ if retry_backoff_duration is not None:
78
+ kwargs["retry_backoff_duration"] = retry_backoff_duration
79
+ if retry_count is not None:
80
+ kwargs["retry_count"] = retry_count
81
+
82
+ build = self.service.Build.create(**kwargs)
83
+ return self._format_build_info(build)
84
+ except Exception as e:
85
+ raise RuntimeError(f"Failed to create build: {e}")
86
+
87
+ def cancel_build(self, build_rid: str) -> None:
88
+ """
89
+ Cancel a build.
90
+
91
+ Args:
92
+ build_rid: Build Resource Identifier
93
+ """
94
+ try:
95
+ self.service.Build.cancel(build_rid)
96
+ except Exception as e:
97
+ raise RuntimeError(f"Failed to cancel build {build_rid}: {e}")
98
+
99
+ def get_build_jobs(
100
+ self,
101
+ build_rid: str,
102
+ page_size: Optional[int] = None,
103
+ page_token: Optional[str] = None,
104
+ ) -> Dict[str, Any]:
105
+ """
106
+ Get jobs in a build.
107
+
108
+ Args:
109
+ build_rid: Build Resource Identifier
110
+ page_size: Number of results per page
111
+ page_token: Token for pagination
112
+
113
+ Returns:
114
+ Jobs list with pagination info
115
+ """
116
+ try:
117
+ kwargs: Dict[str, Any] = {"build_rid": build_rid}
118
+ if page_size is not None:
119
+ kwargs["page_size"] = page_size
120
+ if page_token is not None:
121
+ kwargs["page_token"] = page_token
122
+
123
+ response = self.service.Build.jobs(**kwargs)
124
+ return self._format_jobs_response(response)
125
+ except Exception as e:
126
+ raise RuntimeError(f"Failed to get jobs for build {build_rid}: {e}")
127
+
128
+ def search_builds(
129
+ self,
130
+ page_size: Optional[int] = None,
131
+ page_token: Optional[str] = None,
132
+ **search_params,
133
+ ) -> Dict[str, Any]:
134
+ """
135
+ Search for builds.
136
+
137
+ Args:
138
+ page_size: Number of results per page
139
+ page_token: Token for pagination
140
+ **search_params: Additional search parameters
141
+
142
+ Returns:
143
+ Search results with pagination info
144
+ """
145
+ try:
146
+ kwargs: Dict[str, Any] = {}
147
+ if page_size is not None:
148
+ kwargs["page_size"] = page_size
149
+ if page_token is not None:
150
+ kwargs["page_token"] = page_token
151
+ kwargs.update(search_params)
152
+
153
+ response = self.service.Build.search(**kwargs)
154
+ return self._format_builds_search_response(response)
155
+ except Exception as e:
156
+ raise RuntimeError(f"Failed to search builds: {e}")
157
+
158
+ # Job operations
159
+ def get_job(self, job_rid: str) -> Dict[str, Any]:
160
+ """
161
+ Get information about a specific job.
162
+
163
+ Args:
164
+ job_rid: Job Resource Identifier
165
+
166
+ Returns:
167
+ Job information dictionary
168
+ """
169
+ try:
170
+ job = self.service.Job.get(job_rid)
171
+ return self._format_job_info(job)
172
+ except Exception as e:
173
+ raise RuntimeError(f"Failed to get job {job_rid}: {e}")
174
+
175
+ def get_jobs_batch(self, job_rids: List[str]) -> Dict[str, Any]:
176
+ """
177
+ Get multiple jobs in batch.
178
+
179
+ Args:
180
+ job_rids: List of Job Resource Identifiers (max 500)
181
+
182
+ Returns:
183
+ Batch response with job information
184
+ """
185
+ try:
186
+ if len(job_rids) > 500:
187
+ raise ValueError("Maximum batch size is 500 jobs")
188
+
189
+ body = [{"rid": rid} for rid in job_rids]
190
+ response = self.service.Job.get_batch(body)
191
+ return self._format_jobs_batch_response(response)
192
+ except Exception as e:
193
+ raise RuntimeError(f"Failed to get jobs batch: {e}")
194
+
195
+ # Schedule operations
196
+ def get_schedule(
197
+ self, schedule_rid: str, preview: Optional[bool] = None
198
+ ) -> Dict[str, Any]:
199
+ """
200
+ Get information about a specific schedule.
201
+
202
+ Args:
203
+ schedule_rid: Schedule Resource Identifier
204
+ preview: Enable preview mode
205
+
206
+ Returns:
207
+ Schedule information dictionary
208
+ """
209
+ try:
210
+ kwargs: Dict[str, Any] = {"schedule_rid": schedule_rid}
211
+ if preview is not None:
212
+ kwargs["preview"] = preview
213
+
214
+ schedule = self.service.Schedule.get(**kwargs)
215
+ return self._format_schedule_info(schedule)
216
+ except Exception as e:
217
+ raise RuntimeError(f"Failed to get schedule {schedule_rid}: {e}")
218
+
219
+ def create_schedule(
220
+ self,
221
+ action: Dict[str, Any],
222
+ description: Optional[str] = None,
223
+ display_name: Optional[str] = None,
224
+ trigger: Optional[Dict[str, Any]] = None,
225
+ scope_mode: Optional[str] = None,
226
+ preview: Optional[bool] = None,
227
+ ) -> Dict[str, Any]:
228
+ """
229
+ Create a new schedule.
230
+
231
+ Args:
232
+ action: Schedule action configuration
233
+ description: Schedule description
234
+ display_name: Display name for the schedule
235
+ trigger: Trigger configuration
236
+ scope_mode: Scope mode for the schedule
237
+ preview: Enable preview mode
238
+
239
+ Returns:
240
+ Created schedule information
241
+ """
242
+ try:
243
+ kwargs: Dict[str, Any] = {"action": action}
244
+
245
+ if description is not None:
246
+ kwargs["description"] = description
247
+ if display_name is not None:
248
+ kwargs["display_name"] = display_name
249
+ if trigger is not None:
250
+ kwargs["trigger"] = trigger
251
+ if scope_mode is not None:
252
+ kwargs["scope_mode"] = scope_mode
253
+ if preview is not None:
254
+ kwargs["preview"] = preview
255
+
256
+ schedule = self.service.Schedule.create(**kwargs)
257
+ return self._format_schedule_info(schedule)
258
+ except Exception as e:
259
+ raise RuntimeError(f"Failed to create schedule: {e}")
260
+
261
+ def delete_schedule(self, schedule_rid: str) -> None:
262
+ """
263
+ Delete a schedule.
264
+
265
+ Args:
266
+ schedule_rid: Schedule Resource Identifier
267
+ """
268
+ try:
269
+ self.service.Schedule.delete(schedule_rid)
270
+ except Exception as e:
271
+ raise RuntimeError(f"Failed to delete schedule {schedule_rid}: {e}")
272
+
273
+ def pause_schedule(self, schedule_rid: str) -> None:
274
+ """
275
+ Pause a schedule.
276
+
277
+ Args:
278
+ schedule_rid: Schedule Resource Identifier
279
+ """
280
+ try:
281
+ self.service.Schedule.pause(schedule_rid)
282
+ except Exception as e:
283
+ raise RuntimeError(f"Failed to pause schedule {schedule_rid}: {e}")
284
+
285
+ def unpause_schedule(self, schedule_rid: str) -> None:
286
+ """
287
+ Unpause a schedule.
288
+
289
+ Args:
290
+ schedule_rid: Schedule Resource Identifier
291
+ """
292
+ try:
293
+ self.service.Schedule.unpause(schedule_rid)
294
+ except Exception as e:
295
+ raise RuntimeError(f"Failed to unpause schedule {schedule_rid}: {e}")
296
+
297
+ def run_schedule(self, schedule_rid: str) -> None:
298
+ """
299
+ Execute a schedule immediately.
300
+
301
+ Args:
302
+ schedule_rid: Schedule Resource Identifier
303
+ """
304
+ try:
305
+ self.service.Schedule.run(schedule_rid)
306
+ except Exception as e:
307
+ raise RuntimeError(f"Failed to run schedule {schedule_rid}: {e}")
308
+
309
+ def replace_schedule(
310
+ self,
311
+ schedule_rid: str,
312
+ action: Dict[str, Any],
313
+ description: Optional[str] = None,
314
+ display_name: Optional[str] = None,
315
+ trigger: Optional[Dict[str, Any]] = None,
316
+ scope_mode: Optional[str] = None,
317
+ preview: Optional[bool] = None,
318
+ ) -> Dict[str, Any]:
319
+ """
320
+ Replace an existing schedule.
321
+
322
+ Args:
323
+ schedule_rid: Schedule Resource Identifier
324
+ action: Schedule action configuration
325
+ description: Schedule description
326
+ display_name: Display name for the schedule
327
+ trigger: Trigger configuration
328
+ scope_mode: Scope mode for the schedule
329
+ preview: Enable preview mode
330
+
331
+ Returns:
332
+ Updated schedule information
333
+ """
334
+ try:
335
+ kwargs: Dict[str, Any] = {
336
+ "schedule_rid": schedule_rid,
337
+ "action": action,
338
+ }
339
+
340
+ if description is not None:
341
+ kwargs["description"] = description
342
+ if display_name is not None:
343
+ kwargs["display_name"] = display_name
344
+ if trigger is not None:
345
+ kwargs["trigger"] = trigger
346
+ if scope_mode is not None:
347
+ kwargs["scope_mode"] = scope_mode
348
+ if preview is not None:
349
+ kwargs["preview"] = preview
350
+
351
+ schedule = self.service.Schedule.replace(**kwargs)
352
+ return self._format_schedule_info(schedule)
353
+ except Exception as e:
354
+ raise RuntimeError(f"Failed to replace schedule {schedule_rid}: {e}")
355
+
356
+ # Formatting methods
357
+ def _format_build_info(self, build: Any) -> Dict[str, Any]:
358
+ """Format build information for consistent output."""
359
+ info = {}
360
+
361
+ # Extract available attributes
362
+ for attr in [
363
+ "rid",
364
+ "status",
365
+ "created_time",
366
+ "started_time",
367
+ "finished_time",
368
+ "created_by",
369
+ "branch_name",
370
+ "commit_hash",
371
+ ]:
372
+ if hasattr(build, attr):
373
+ info[attr] = getattr(build, attr)
374
+
375
+ return info
376
+
377
+ def _format_job_info(self, job: Any) -> Dict[str, Any]:
378
+ """Format job information for consistent output."""
379
+ info = {}
380
+
381
+ # Extract available attributes
382
+ for attr in [
383
+ "rid",
384
+ "status",
385
+ "created_time",
386
+ "started_time",
387
+ "finished_time",
388
+ "job_type",
389
+ "build_rid",
390
+ ]:
391
+ if hasattr(job, attr):
392
+ info[attr] = getattr(job, attr)
393
+
394
+ return info
395
+
396
+ def _format_schedule_info(self, schedule: Any) -> Dict[str, Any]:
397
+ """Format schedule information for consistent output."""
398
+ info = {}
399
+
400
+ # Extract available attributes
401
+ for attr in [
402
+ "rid",
403
+ "display_name",
404
+ "description",
405
+ "paused",
406
+ "created_time",
407
+ "created_by",
408
+ "modified_time",
409
+ "modified_by",
410
+ ]:
411
+ if hasattr(schedule, attr):
412
+ info[attr] = getattr(schedule, attr)
413
+
414
+ # Handle nested objects
415
+ if hasattr(schedule, "trigger"):
416
+ info["trigger"] = str(schedule.trigger)
417
+ if hasattr(schedule, "action"):
418
+ info["action"] = str(schedule.action)
419
+
420
+ return info
421
+
422
+ def _format_jobs_response(self, response: Any) -> Dict[str, Any]:
423
+ """Format jobs list response."""
424
+ result: Dict[str, Any] = {"jobs": []}
425
+
426
+ if hasattr(response, "data"):
427
+ result["jobs"] = [self._format_job_info(job) for job in response.data]
428
+
429
+ if hasattr(response, "next_page_token"):
430
+ result["next_page_token"] = response.next_page_token
431
+
432
+ return result
433
+
434
+ def _format_builds_search_response(self, response: Any) -> Dict[str, Any]:
435
+ """Format builds search response."""
436
+ result: Dict[str, Any] = {"builds": []}
437
+
438
+ if hasattr(response, "data"):
439
+ result["builds"] = [
440
+ self._format_build_info(build) for build in response.data
441
+ ]
442
+
443
+ if hasattr(response, "next_page_token"):
444
+ result["next_page_token"] = response.next_page_token
445
+
446
+ return result
447
+
448
+ def _format_jobs_batch_response(self, response: Any) -> Dict[str, Any]:
449
+ """Format jobs batch response."""
450
+ result: Dict[str, Any] = {"jobs": []}
451
+
452
+ if hasattr(response, "data"):
453
+ for item in response.data:
454
+ if hasattr(item, "data"):
455
+ result["jobs"].append(self._format_job_info(item.data))
456
+
457
+ return result