uipath 2.1.131__py3-none-any.whl → 2.1.132__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.

Potentially problematic release.


This version of uipath might be problematic. Click here for more details.

@@ -0,0 +1,38 @@
1
+ """Service command groups for UiPath CLI.
2
+
3
+ All services are explicitly imported to ensure:
4
+ - File renames break loudly (import error) not silently
5
+ - Clear dependency graph
6
+ - Fast startup (no auto-discovery overhead)
7
+ - Debuggable registration
8
+ """
9
+
10
+ from .cli_buckets import buckets
11
+
12
+ __all__ = ["buckets", "register_service_commands"]
13
+
14
+
15
+ def register_service_commands(cli_group):
16
+ """Register all service command groups with the root CLI.
17
+
18
+ This function maintains explicitness while reducing registration boilerplate.
19
+ Benefits:
20
+ - File renames break loudly (import error) not silently
21
+ - Clear list of all registered services
22
+ - Easy to comment out services during development
23
+
24
+ Args:
25
+ cli_group: The root Click group to register services with
26
+
27
+ Returns:
28
+ The cli_group for method chaining
29
+
30
+ Industry Precedent:
31
+ AWS CLI, Azure CLI, and gcloud all use explicit registration.
32
+ """
33
+ services = [buckets]
34
+
35
+ for service in services:
36
+ cli_group.add_command(service)
37
+
38
+ return cli_group
@@ -0,0 +1,53 @@
1
+ """Metadata configuration for Buckets service CLI.
2
+
3
+ This module defines the ServiceMetadata for the buckets service, which is used
4
+ by ServiceCLIGenerator to auto-generate standard CRUD commands.
5
+
6
+ The buckets service was the first service migrated to the Service CLI Generator
7
+ architecture and serves as the reference implementation for future migrations.
8
+ """
9
+
10
+ from uipath._cli._utils._service_metadata import (
11
+ CreateParameter,
12
+ DeleteCommandConfig,
13
+ ExistsCommandConfig,
14
+ ServiceMetadata,
15
+ )
16
+ from uipath._cli._utils._service_protocol import validate_service_protocol
17
+
18
+ __all__ = ["BUCKETS_METADATA"]
19
+
20
+
21
+ BUCKETS_METADATA = ServiceMetadata(
22
+ service_name="buckets",
23
+ service_attr="buckets",
24
+ resource_type="Bucket",
25
+ resource_plural="Buckets",
26
+ create_params={
27
+ "description": CreateParameter(
28
+ type="str",
29
+ required=False,
30
+ help="Bucket description",
31
+ default=None,
32
+ ),
33
+ },
34
+ delete_cmd=DeleteCommandConfig(
35
+ confirmation_required=True,
36
+ dry_run_supported=True,
37
+ confirmation_prompt=None,
38
+ ),
39
+ exists_cmd=ExistsCommandConfig(
40
+ identifier_arg_name="name",
41
+ return_format="dict",
42
+ ),
43
+ )
44
+
45
+ BUCKETS_METADATA.validate_types()
46
+
47
+ try:
48
+ from uipath.sdk import SDK # type: ignore[import-not-found]
49
+
50
+ sdk = SDK()
51
+ validate_service_protocol(sdk.client.buckets, "buckets")
52
+ except Exception:
53
+ pass
@@ -0,0 +1,526 @@
1
+ """Buckets service commands for UiPath CLI.
2
+
3
+ Buckets are cloud storage containers for files used by automation processes.
4
+ Similar to AWS S3 or Azure Blob Storage.
5
+
6
+ This module uses the Service CLI Generator to auto-generate standard CRUD commands
7
+ for bucket management, with custom implementations for file operations.
8
+
9
+ Architecture:
10
+ - Auto-generated commands: list, create, delete, exists (via ServiceCLIGenerator)
11
+ - Overridden command: retrieve (custom --name/--key dual-option support)
12
+ - Manual nested group: files (with 6 custom file operation commands)
13
+ """
14
+ # ruff: noqa: D301 - Using regular """ strings (not r""") for Click \b formatting
15
+
16
+ from itertools import islice
17
+
18
+ import click
19
+
20
+ from .._utils._service_base import (
21
+ ServiceCommandBase,
22
+ common_service_options,
23
+ handle_not_found_error,
24
+ service_command,
25
+ )
26
+ from .._utils._service_cli_generator import ServiceCLIGenerator
27
+ from ._buckets_metadata import BUCKETS_METADATA
28
+
29
+ _cli = click.Group()
30
+ generator = ServiceCLIGenerator(BUCKETS_METADATA)
31
+ buckets = generator.register(_cli)
32
+ buckets.help = """Manage UiPath storage buckets and files.
33
+
34
+ Buckets are cloud storage containers for files used by automation processes.
35
+
36
+ \b
37
+ Bucket Operations:
38
+ list - List all buckets
39
+ create - Create a new bucket
40
+ delete - Delete a bucket
41
+ retrieve - Get bucket details
42
+ exists - Check if bucket exists
43
+
44
+ \b
45
+ File Operations (use 'buckets files' subcommand):
46
+ files list - List files in a bucket
47
+ files search - Search files using glob patterns
48
+ files upload - Upload a file to a bucket
49
+ files download - Download a file from a bucket
50
+ files delete - Delete a file from a bucket
51
+ files exists - Check if a file exists
52
+
53
+ \b
54
+ Examples:
55
+ \b
56
+ # Bucket operations with explicit folder
57
+ uipath buckets list --folder-path "Shared"
58
+ uipath buckets create my-bucket --description "Data storage"
59
+ uipath buckets exists my-bucket
60
+ uipath buckets delete my-bucket --confirm
61
+ \b
62
+ # Using environment variable for folder context
63
+ export UIPATH_FOLDER_PATH="Shared"
64
+ uipath buckets list
65
+ uipath buckets create my-bucket --description "Data storage"
66
+ \b
67
+ # File operations
68
+ uipath buckets files list my-bucket
69
+ uipath buckets files search my-bucket "*.pdf"
70
+ uipath buckets files upload my-bucket ./data.csv remote/data.csv
71
+ uipath buckets files download my-bucket data.csv ./local.csv
72
+ uipath buckets files delete my-bucket old-data.csv --confirm
73
+ uipath buckets files exists my-bucket data.csv
74
+ """
75
+
76
+
77
+ @click.command()
78
+ @click.option("--name", help="Bucket name")
79
+ @click.option("--key", help="Bucket key (UUID)")
80
+ @common_service_options
81
+ @service_command
82
+ def retrieve(ctx, name, key, folder_path, folder_key, format, output):
83
+ """Retrieve a bucket by name or key.
84
+
85
+ \b
86
+ Examples:
87
+ uipath buckets retrieve --name "my-bucket"
88
+ uipath buckets retrieve --key "abc-123-def-456" --format json
89
+ """
90
+ from httpx import HTTPStatusError
91
+
92
+ if not name and not key:
93
+ raise click.UsageError("Either --name or --key must be provided")
94
+
95
+ if name and key:
96
+ raise click.UsageError("Provide either --name or --key, not both")
97
+
98
+ client = ServiceCommandBase.get_client(ctx)
99
+
100
+ try:
101
+ bucket = client.buckets.retrieve(
102
+ name=name,
103
+ key=key,
104
+ folder_path=folder_path,
105
+ folder_key=folder_key,
106
+ )
107
+ except LookupError:
108
+ handle_not_found_error("Bucket", name or key)
109
+ except HTTPStatusError as e:
110
+ if e.response.status_code == 404:
111
+ handle_not_found_error("Bucket", name or key, e)
112
+ raise
113
+
114
+ return bucket
115
+
116
+
117
+ generator.override_command(buckets, "retrieve", retrieve)
118
+
119
+
120
+ @click.command()
121
+ @click.argument("name")
122
+ @click.option("--confirm", is_flag=True, help="Skip confirmation prompt")
123
+ @click.option(
124
+ "--dry-run", is_flag=True, help="Show what would be deleted without deleting"
125
+ )
126
+ @common_service_options
127
+ @service_command
128
+ def delete(ctx, name, confirm, dry_run, folder_path, folder_key, format, output):
129
+ """Delete a bucket.
130
+
131
+ \b
132
+ Examples:
133
+ uipath buckets delete my-bucket --confirm
134
+ uipath buckets delete my-bucket --dry-run
135
+ """
136
+ from httpx import HTTPStatusError
137
+
138
+ client = ServiceCommandBase.get_client(ctx)
139
+
140
+ # First retrieve to verify bucket exists
141
+ try:
142
+ client.buckets.retrieve(
143
+ name=name,
144
+ folder_path=folder_path,
145
+ folder_key=folder_key,
146
+ )
147
+ except LookupError:
148
+ handle_not_found_error("Bucket", name)
149
+ except HTTPStatusError as e:
150
+ if e.response.status_code == 404:
151
+ handle_not_found_error("Bucket", name, e)
152
+ raise
153
+
154
+ # Handle dry-run
155
+ if dry_run:
156
+ click.echo(f"Would delete bucket '{name}'", err=True)
157
+ return
158
+
159
+ # Handle confirmation
160
+ if not confirm:
161
+ if not click.confirm(f"Delete bucket '{name}'?"):
162
+ click.echo("Deletion cancelled.")
163
+ return
164
+
165
+ # Perform delete
166
+ client.buckets.delete(
167
+ name=name,
168
+ folder_path=folder_path,
169
+ folder_key=folder_key,
170
+ )
171
+
172
+ click.echo(f"Deleted bucket '{name}'", err=True)
173
+
174
+
175
+ generator.override_command(buckets, "delete", delete)
176
+
177
+
178
+ @click.group()
179
+ def files():
180
+ """Manage files within buckets.
181
+
182
+ \b
183
+ Examples:
184
+ \b
185
+ # List files in a bucket
186
+ uipath buckets files list my-bucket
187
+ \b
188
+ # Search for files with glob pattern
189
+ uipath buckets files search my-bucket "*.pdf"
190
+ \b
191
+ # Upload a file
192
+ uipath buckets files upload my-bucket ./data.csv remote/data.csv
193
+ \b
194
+ # Download a file
195
+ uipath buckets files download my-bucket data.csv ./local.csv
196
+ \b
197
+ # Delete a file
198
+ uipath buckets files delete my-bucket old-data.csv --confirm
199
+ \b
200
+ # Check if file exists
201
+ uipath buckets files exists my-bucket data.csv
202
+ """
203
+ pass
204
+
205
+
206
+ @files.command(name="list")
207
+ @click.argument("bucket_name")
208
+ @click.option("--prefix", default="", help="Filter files by prefix")
209
+ @click.option(
210
+ "--limit",
211
+ type=click.IntRange(min=0),
212
+ help="Maximum number of files to return",
213
+ )
214
+ @click.option(
215
+ "--offset",
216
+ type=click.IntRange(min=0),
217
+ default=0,
218
+ help="Number of files to skip",
219
+ )
220
+ @click.option(
221
+ "--all", "fetch_all", is_flag=True, help="Fetch all files (auto-paginate)"
222
+ )
223
+ @common_service_options
224
+ @service_command
225
+ def list_files(
226
+ ctx,
227
+ bucket_name,
228
+ prefix,
229
+ limit,
230
+ offset,
231
+ fetch_all,
232
+ folder_path,
233
+ folder_key,
234
+ format,
235
+ output,
236
+ ):
237
+ """List files in a bucket.
238
+
239
+ \b
240
+ Arguments:
241
+ BUCKET_NAME: Name of the bucket
242
+
243
+ \b
244
+ Examples:
245
+ uipath buckets files list my-bucket
246
+ uipath buckets files list my-bucket --prefix "data/"
247
+ uipath buckets files list reports --limit 10 --format json
248
+ uipath buckets files list my-bucket --all
249
+ """
250
+ from httpx import HTTPStatusError
251
+
252
+ client = ServiceCommandBase.get_client(ctx)
253
+
254
+ try:
255
+ files_iterator = client.buckets.list_files(
256
+ name=bucket_name,
257
+ prefix=prefix,
258
+ folder_path=folder_path,
259
+ folder_key=folder_key,
260
+ )
261
+
262
+ if not fetch_all and limit == 0:
263
+ return []
264
+
265
+ start = offset
266
+ stop = None if fetch_all or limit is None else start + limit
267
+ return list(islice(files_iterator, start, stop))
268
+ except LookupError:
269
+ handle_not_found_error("Bucket", bucket_name)
270
+ except HTTPStatusError as e:
271
+ if e.response.status_code == 404:
272
+ handle_not_found_error("Bucket", bucket_name, e)
273
+ raise
274
+
275
+
276
+ @files.command(name="search")
277
+ @click.argument("bucket_name")
278
+ @click.argument("pattern")
279
+ @click.option("--prefix", default="", help="Directory path to search in")
280
+ @click.option(
281
+ "--recursive/--no-recursive",
282
+ default=False,
283
+ help="Search subdirectories recursively",
284
+ )
285
+ @click.option(
286
+ "--limit",
287
+ type=click.IntRange(min=0),
288
+ help="Maximum number of files to return",
289
+ )
290
+ @common_service_options
291
+ @service_command
292
+ def search_files(
293
+ ctx,
294
+ bucket_name,
295
+ pattern,
296
+ prefix,
297
+ recursive,
298
+ limit,
299
+ folder_path,
300
+ folder_key,
301
+ format,
302
+ output,
303
+ ):
304
+ """Search for files using glob patterns.
305
+
306
+ Uses the GetFiles API which supports glob patterns like *.pdf or data_*.csv.
307
+
308
+ \b
309
+ Arguments:
310
+ BUCKET_NAME: Name of the bucket
311
+ PATTERN: Glob pattern to match files (e.g., "*.pdf", "data_*.csv")
312
+
313
+ \b
314
+ Examples:
315
+ uipath buckets files search my-bucket "*.pdf"
316
+ uipath buckets files search reports "*.csv" --recursive
317
+ uipath buckets files search my-bucket "data_*.json" --prefix "archive/"
318
+ """
319
+ from httpx import HTTPStatusError
320
+
321
+ client = ServiceCommandBase.get_client(ctx)
322
+
323
+ try:
324
+ files_iterator = client.buckets.get_files(
325
+ name=bucket_name,
326
+ prefix=prefix,
327
+ recursive=recursive,
328
+ file_name_glob=pattern,
329
+ folder_path=folder_path,
330
+ folder_key=folder_key,
331
+ )
332
+
333
+ files = (
334
+ list(files_iterator)
335
+ if limit is None
336
+ else list(islice(files_iterator, limit))
337
+ )
338
+ return files
339
+ except LookupError:
340
+ handle_not_found_error("Bucket", bucket_name)
341
+ except HTTPStatusError as e:
342
+ if e.response.status_code == 404:
343
+ handle_not_found_error("Bucket", bucket_name, e)
344
+ raise
345
+
346
+
347
+ @files.command(name="upload")
348
+ @click.argument("bucket_name")
349
+ @click.argument("local_path", type=click.Path(exists=True))
350
+ @click.argument("remote_path")
351
+ @common_service_options
352
+ @service_command
353
+ def upload_file(
354
+ ctx, bucket_name, local_path, remote_path, folder_path, folder_key, format, output
355
+ ):
356
+ """Upload a file to a bucket.
357
+
358
+ \b
359
+ Arguments:
360
+ BUCKET_NAME: Name of the bucket
361
+ LOCAL_PATH: Local file to upload
362
+ REMOTE_PATH: Destination path in bucket
363
+
364
+ \b
365
+ Examples:
366
+ uipath buckets files upload my-bucket ./data.csv remote/data.csv
367
+ uipath buckets files upload reports ./report.pdf monthly/report.pdf
368
+ """
369
+ client = ServiceCommandBase.get_client(ctx)
370
+
371
+ click.echo(f"Uploading {local_path}...", err=True)
372
+ client.buckets.upload(
373
+ name=bucket_name,
374
+ source_path=local_path,
375
+ blob_file_path=remote_path,
376
+ folder_path=folder_path,
377
+ folder_key=folder_key,
378
+ )
379
+
380
+ click.echo(f"Uploaded to {remote_path}", err=True)
381
+
382
+
383
+ @files.command(name="download")
384
+ @click.argument("bucket_name")
385
+ @click.argument("remote_path")
386
+ @click.argument("local_path", type=click.Path())
387
+ @common_service_options
388
+ @service_command
389
+ def download_file(
390
+ ctx, bucket_name, remote_path, local_path, folder_path, folder_key, format, output
391
+ ):
392
+ """Download a file from a bucket.
393
+
394
+ \b
395
+ Arguments:
396
+ BUCKET_NAME: Name of the bucket
397
+ REMOTE_PATH: Path to file in bucket
398
+ LOCAL_PATH: Local destination path
399
+
400
+ \b
401
+ Examples:
402
+ uipath buckets files download my-bucket data.csv ./downloads/data.csv
403
+ uipath buckets files download reports monthly/report.pdf ./report.pdf
404
+ """
405
+ client = ServiceCommandBase.get_client(ctx)
406
+
407
+ click.echo(f"Downloading {remote_path}...", err=True)
408
+ client.buckets.download(
409
+ name=bucket_name,
410
+ blob_file_path=remote_path,
411
+ destination_path=local_path,
412
+ folder_path=folder_path,
413
+ folder_key=folder_key,
414
+ )
415
+
416
+ click.echo(f"Downloaded to {local_path}", err=True)
417
+
418
+
419
+ @files.command(name="delete")
420
+ @click.argument("bucket_name")
421
+ @click.argument("file_path")
422
+ @click.option("--confirm", is_flag=True, help="Skip confirmation prompt")
423
+ @click.option("--dry-run", is_flag=True, help="Show what would be deleted")
424
+ @common_service_options
425
+ @service_command
426
+ def delete_file(
427
+ ctx,
428
+ bucket_name,
429
+ file_path,
430
+ confirm,
431
+ dry_run,
432
+ folder_path,
433
+ folder_key,
434
+ format,
435
+ output,
436
+ ):
437
+ """Delete a file from a bucket.
438
+
439
+ \b
440
+ Arguments:
441
+ BUCKET_NAME: Name of the bucket
442
+ FILE_PATH: Path to file in bucket
443
+
444
+ \b
445
+ Examples:
446
+ uipath buckets files delete my-bucket old-data.csv --confirm
447
+ uipath buckets files delete reports archive/old.pdf --dry-run
448
+ """
449
+ from httpx import HTTPStatusError
450
+
451
+ client = ServiceCommandBase.get_client(ctx)
452
+
453
+ if dry_run:
454
+ click.echo(
455
+ f"Would delete file: {file_path} from bucket {bucket_name}", err=True
456
+ )
457
+ return
458
+
459
+ if not confirm:
460
+ if not click.confirm(f"Delete file '{file_path}' from bucket '{bucket_name}'?"):
461
+ click.echo("Aborted", err=True)
462
+ return
463
+
464
+ try:
465
+ client.buckets.delete_file(
466
+ name=bucket_name,
467
+ blob_file_path=file_path,
468
+ folder_path=folder_path,
469
+ folder_key=folder_key,
470
+ )
471
+ click.echo(f"Deleted file '{file_path}' from bucket '{bucket_name}'", err=True)
472
+ except LookupError:
473
+ handle_not_found_error("Bucket", bucket_name)
474
+ except HTTPStatusError as e:
475
+ if e.response.status_code == 404:
476
+ handle_not_found_error("File or Bucket", f"{bucket_name}/{file_path}", e)
477
+ raise
478
+
479
+
480
+ @files.command(name="exists")
481
+ @click.argument("bucket_name")
482
+ @click.argument("file_path")
483
+ @common_service_options
484
+ @service_command
485
+ def file_exists(ctx, bucket_name, file_path, folder_path, folder_key, format, output):
486
+ """Check if a file exists in a bucket.
487
+
488
+ \b
489
+ Arguments:
490
+ BUCKET_NAME: Name of the bucket
491
+ FILE_PATH: Path to file in bucket
492
+
493
+ \b
494
+ Examples:
495
+ uipath buckets files exists my-bucket data.csv
496
+ uipath buckets files exists reports monthly/report.pdf
497
+ """
498
+ from httpx import HTTPStatusError
499
+
500
+ client = ServiceCommandBase.get_client(ctx)
501
+
502
+ try:
503
+ file_exists_result = client.buckets.exists_file(
504
+ name=bucket_name,
505
+ blob_file_path=file_path,
506
+ folder_path=folder_path,
507
+ folder_key=folder_key,
508
+ )
509
+
510
+ if file_exists_result:
511
+ click.echo(f"File '{file_path}' exists in bucket '{bucket_name}'", err=True)
512
+ return {"exists": True, "bucket": bucket_name, "file": file_path}
513
+ else:
514
+ click.echo(
515
+ f"File '{file_path}' does not exist in bucket '{bucket_name}'", err=True
516
+ )
517
+ return {"exists": False, "bucket": bucket_name, "file": file_path}
518
+ except LookupError:
519
+ handle_not_found_error("Bucket", bucket_name)
520
+ except HTTPStatusError as e:
521
+ if e.response.status_code == 404:
522
+ handle_not_found_error("Bucket", bucket_name, e)
523
+ raise
524
+
525
+
526
+ generator.add_nested_group(buckets, "files", files)