uipath 2.1.3__py3-none-any.whl → 2.1.5__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,546 @@
1
+ # type: ignore
2
+ """CLI command for pushing local project files to UiPath StudioWeb solution.
3
+
4
+ This module provides functionality to push local project files to a UiPath StudioWeb solution.
5
+ It handles:
6
+ - File uploads and updates
7
+ - File deletions for removed local files
8
+ - Optional UV lock file management
9
+ - Project structure pushing
10
+
11
+ The push process ensures that the remote project structure matches the local files,
12
+ taking into account:
13
+ - Entry point files from uipath.json
14
+ - Project configuration from pyproject.toml
15
+ - Optional UV lock file for dependency management
16
+ """
17
+
18
+ import json
19
+ import os
20
+ from datetime import datetime, timezone
21
+ from typing import Any, Dict, Optional, Set, Tuple
22
+ from urllib.parse import urlparse
23
+
24
+ import click
25
+ import httpx
26
+ import jwt
27
+ from dotenv import load_dotenv
28
+
29
+ from .._utils._ssl_context import get_httpx_client_kwargs
30
+ from ..telemetry import track
31
+ from ._utils._common import get_env_vars
32
+ from ._utils._console import ConsoleLogger
33
+ from ._utils._constants import (
34
+ AGENT_INITIAL_CODE_VERSION,
35
+ AGENT_STORAGE_VERSION,
36
+ AGENT_TARGET_RUNTIME,
37
+ AGENT_VERSION,
38
+ )
39
+ from ._utils._project_files import (
40
+ ensure_config_file,
41
+ files_to_include,
42
+ get_project_config,
43
+ read_toml_project,
44
+ validate_config,
45
+ )
46
+ from ._utils._studio_project import ProjectFile, ProjectFolder, ProjectStructure
47
+ from ._utils._uv_helpers import handle_uv_operations
48
+
49
+ console = ConsoleLogger()
50
+ load_dotenv(override=True)
51
+
52
+
53
+ def get_author_from_token_or_toml(directory: str) -> str:
54
+ """Extract preferred_username from JWT token or fall back to pyproject.toml author.
55
+
56
+ Args:
57
+ directory: Project directory containing pyproject.toml
58
+
59
+ Returns:
60
+ str: Author name from JWT preferred_username or pyproject.toml authors field
61
+ """
62
+ # Try to get author from JWT token first
63
+ token = os.getenv("UIPATH_ACCESS_TOKEN")
64
+ if token:
65
+ try:
66
+ decoded_token = jwt.decode(token, options={"verify_signature": False})
67
+ preferred_username = decoded_token.get("preferred_username")
68
+ if preferred_username:
69
+ return preferred_username
70
+ except Exception:
71
+ # If JWT decoding fails, fall back to toml
72
+ pass
73
+
74
+ toml_data = read_toml_project(os.path.join(directory, "pyproject.toml"))
75
+ return toml_data.get("authors", "").strip()
76
+
77
+
78
+ def get_org_scoped_url(base_url: str) -> str:
79
+ parsed = urlparse(base_url)
80
+ org_name, *_ = parsed.path.strip("/").split("/")
81
+
82
+ # Construct the new scoped URL (scheme + domain + org_name)
83
+ org_scoped_url = f"{parsed.scheme}://{parsed.netloc}/{org_name}"
84
+ return org_scoped_url
85
+
86
+
87
+ def get_project_structure(
88
+ project_id: str,
89
+ base_url: str,
90
+ token: str,
91
+ client: httpx.Client,
92
+ ) -> ProjectStructure:
93
+ """Retrieve the project's file structure from UiPath Cloud.
94
+
95
+ Makes an API call to fetch the complete file structure of a project,
96
+ including all files and folders. The response is validated against
97
+ the ProjectStructure model.
98
+
99
+ Args:
100
+ project_id: The ID of the project
101
+ base_url: The base URL for the API
102
+ token: Authentication token
103
+ client: HTTP client to use for requests
104
+
105
+ Returns:
106
+ ProjectStructure: The complete project structure
107
+
108
+ Raises:
109
+ httpx.HTTPError: If the API request fails
110
+ """
111
+ url = get_org_scoped_url(base_url)
112
+ headers = {"Authorization": f"Bearer {token}"}
113
+ url = f"{url}/studio_/backend/api/Project/{project_id}/FileOperations/Structure"
114
+
115
+ response = client.get(url, headers=headers)
116
+ response.raise_for_status()
117
+ return ProjectStructure.model_validate(response.json())
118
+
119
+
120
+ def collect_all_files(
121
+ folder: ProjectFolder, files_dict: Dict[str, ProjectFile]
122
+ ) -> None:
123
+ """Recursively collect all files from a folder and its subfolders.
124
+
125
+ Traverses the folder structure recursively and adds all files to the
126
+ provided dictionary, using the file name as the key.
127
+ """
128
+ # Add files from current folder
129
+ for file in folder.files:
130
+ files_dict[file.name] = file
131
+
132
+ # Recursively process subfolders
133
+ for subfolder in folder.folders:
134
+ collect_all_files(subfolder, files_dict)
135
+
136
+
137
+ def get_folder_by_name(
138
+ structure: ProjectStructure, folder_name: str
139
+ ) -> Optional[ProjectFolder]:
140
+ """Get a folder from the project structure by name.
141
+
142
+ Args:
143
+ structure: The project structure
144
+ folder_name: Name of the folder to find
145
+
146
+ Returns:
147
+ Optional[ProjectFolder]: The found folder or None
148
+ """
149
+ for folder in structure.folders:
150
+ if folder.name == folder_name:
151
+ return folder
152
+ return None
153
+
154
+
155
+ def get_all_remote_files(
156
+ structure: ProjectStructure, source_code_folder: Optional[ProjectFolder] = None
157
+ ) -> Tuple[Dict[str, ProjectFile], Dict[str, ProjectFile]]:
158
+ """Get all files from the project structure indexed by name.
159
+
160
+ Creates two flat dictionaries of files in the project:
161
+ 1. Root level files
162
+ 2. Files in the source_code folder (if exists)
163
+
164
+ Args:
165
+ structure: The project structure
166
+ source_code_folder: Optional source_code folder to collect files from
167
+
168
+ Returns:
169
+ Tuple[Dict[str, ProjectFile], Dict[str, ProjectFile]]:
170
+ (root_files, source_code_files)
171
+ """
172
+ root_files: Dict[str, ProjectFile] = {}
173
+ source_code_files: Dict[str, ProjectFile] = {}
174
+
175
+ # Add files from root level
176
+ for file in structure.files:
177
+ root_files[file.name] = file
178
+
179
+ # Add files from source_code folder if it exists
180
+ if source_code_folder:
181
+ collect_all_files(source_code_folder, source_code_files)
182
+
183
+ return root_files, source_code_files
184
+
185
+
186
+ def delete_remote_file(
187
+ project_id: str, file_id: str, base_url: str, token: str, client: httpx.Client
188
+ ) -> None:
189
+ """Delete a file from the remote project.
190
+
191
+ Makes an API call to delete a specific file from the UiPath Cloud project.
192
+
193
+ Args:
194
+ project_id: The ID of the project
195
+ file_id: The ID of the file to delete
196
+ base_url: The base URL for the API
197
+ token: Authentication token
198
+ client: HTTP client to use for the request
199
+
200
+ Raises:
201
+ httpx.HTTPError: If the API request fails
202
+ """
203
+ url = get_org_scoped_url(base_url)
204
+ headers = {"Authorization": f"Bearer {token}"}
205
+ url = f"{url}/studio_/backend/api/Project/{project_id}/FileOperations/Delete/{file_id}"
206
+
207
+ response = client.delete(url, headers=headers)
208
+ response.raise_for_status()
209
+
210
+
211
+ def update_agent_json(
212
+ project_id: str,
213
+ base_url: str,
214
+ token: str,
215
+ directory: str,
216
+ client: httpx.Client,
217
+ processed_files: Optional[Set[str]] = None,
218
+ agent_json_file: Optional[ProjectFile] = None,
219
+ ) -> None:
220
+ """Update agent.json file with metadata from uipath.json.
221
+
222
+ This function:
223
+ 1. Downloads existing agent.json if it exists
224
+ 2. Updates metadata based on uipath.json content
225
+ 3. Increments code version
226
+ 4. Updates author from JWT or pyproject.toml
227
+ 5. Uploads updated agent.json
228
+
229
+ Args:
230
+ project_id: The ID of the project
231
+ base_url: The base URL for the API
232
+ token: Authentication token
233
+ directory: Project root directory
234
+ client: HTTP client to use for requests
235
+ processed_files: Optional set to track processed files
236
+ agent_json_file: Optional existing agent.json file
237
+
238
+ Raises:
239
+ httpx.HTTPError: If API requests fail
240
+ FileNotFoundError: If required files are missing
241
+ json.JSONDecodeError: If JSON parsing fails
242
+ """
243
+ url = get_org_scoped_url(base_url)
244
+ headers = {"Authorization": f"Bearer {token}"}
245
+
246
+ # Read uipath.json
247
+ with open(os.path.join(directory, "uipath.json"), "r") as f:
248
+ uipath_config = json.load(f)
249
+
250
+ try:
251
+ entrypoints = [
252
+ {"input": entry_point["input"], "output": entry_point["output"]}
253
+ for entry_point in uipath_config["entryPoints"]
254
+ ]
255
+ except (FileNotFoundError, KeyError) as e:
256
+ console.error(
257
+ f"Unable to extract entrypoints from configuration file. Please run 'uipath init' : {str(e)}",
258
+ )
259
+
260
+ author = get_author_from_token_or_toml(directory)
261
+
262
+ # Initialize agent.json structure
263
+ agent_json = {
264
+ "version": AGENT_VERSION,
265
+ "metadata": {
266
+ "storageVersion": AGENT_STORAGE_VERSION,
267
+ "targetRuntime": AGENT_TARGET_RUNTIME,
268
+ "isConversational": False,
269
+ "codeVersion": AGENT_INITIAL_CODE_VERSION,
270
+ "author": author,
271
+ "pushDate": datetime.now(timezone.utc).isoformat(),
272
+ },
273
+ "entryPoints": entrypoints,
274
+ "bindings": uipath_config.get("bindings", {"version": "2.0", "resources": []}),
275
+ }
276
+
277
+ base_api_url = f"{url}/studio_/backend/api/Project/{project_id}/FileOperations"
278
+ if agent_json_file:
279
+ # Download existing agent.json
280
+ file_url = f"{base_api_url}/File/{agent_json_file.id}"
281
+ response = client.get(file_url, headers=headers)
282
+ response.raise_for_status()
283
+
284
+ try:
285
+ existing_agent = response.json()
286
+ # Get current version and increment patch version
287
+ version_parts = existing_agent["metadata"]["codeVersion"].split(".")
288
+ if len(version_parts) >= 3:
289
+ version_parts[-1] = str(int(version_parts[-1]) + 1)
290
+ agent_json["metadata"]["codeVersion"] = ".".join(version_parts)
291
+ else:
292
+ # If version format is invalid, start from initial version + 1
293
+ agent_json["metadata"]["codeVersion"] = (
294
+ AGENT_INITIAL_CODE_VERSION[:-1] + "1"
295
+ )
296
+ except (json.JSONDecodeError, KeyError, ValueError):
297
+ console.warning(
298
+ "Could not parse existing agent.json, using default version"
299
+ )
300
+
301
+ # Upload updated agent.json
302
+ files_data = {"file": ("agent.json", json.dumps(agent_json), "application/json")}
303
+
304
+ # if agent.json already exists update it, otherwise upload it
305
+ if agent_json_file:
306
+ url = f"{base_api_url}/File/{agent_json_file.id}"
307
+ response = client.put(url, files=files_data, headers=headers)
308
+ else:
309
+ url = f"{base_api_url}/File"
310
+ response = client.post(url, files=files_data, headers=headers)
311
+
312
+ response.raise_for_status()
313
+ console.success(f"Updated {click.style('agent.json', fg='cyan')}")
314
+
315
+ # Mark agent.json as processed to prevent deletion
316
+ if processed_files is not None:
317
+ processed_files.add("agent.json")
318
+
319
+
320
+ def create_project_folder(
321
+ project_id: str,
322
+ folder_name: str,
323
+ base_url: str,
324
+ token: str,
325
+ client: httpx.Client,
326
+ ) -> ProjectFolder:
327
+ """Create a new folder in the project.
328
+
329
+ Args:
330
+ project_id: The ID of the project
331
+ folder_name: Name of the folder to create
332
+ base_url: The base URL for the API
333
+ token: Authentication token
334
+ client: HTTP client to use for requests
335
+
336
+ Returns:
337
+ ProjectFolder: The created folder object
338
+
339
+ Raises:
340
+ httpx.HTTPError: If the API request fails
341
+ """
342
+ url = get_org_scoped_url(base_url)
343
+ headers = {"Authorization": f"Bearer {token}"}
344
+ url = f"{url}/studio_/backend/api/Project/{project_id}/FileOperations/Folder"
345
+
346
+ data = {"name": folder_name}
347
+ response = client.post(url, json=data, headers=headers)
348
+ response.raise_for_status()
349
+ return ProjectFolder(name="source_code", id=response.content.decode("utf-8"))
350
+
351
+
352
+ def upload_source_files_to_project(
353
+ project_id: str,
354
+ config_data: dict[Any, str],
355
+ directory: str,
356
+ base_url: str,
357
+ token: str,
358
+ include_uv_lock: bool = True,
359
+ ) -> None:
360
+ """Upload source files to UiPath project.
361
+
362
+ This function handles the pushing of local files to the remote project:
363
+ - Updates existing files that have changed
364
+ - Uploads new files that don't exist remotely
365
+ - Deletes remote files that no longer exist locally
366
+ - Optionally includes the UV lock file
367
+ """
368
+ files = [
369
+ file.file_path.replace("./", "", 1)
370
+ for file in files_to_include(config_data, directory)
371
+ ]
372
+ if include_uv_lock:
373
+ files.append("uv.lock")
374
+
375
+ url = get_org_scoped_url(base_url)
376
+ headers = {"Authorization": f"Bearer {token}"}
377
+ base_api_url = f"{url}/studio_/backend/api/Project/{project_id}/FileOperations"
378
+
379
+ with httpx.Client(**get_httpx_client_kwargs()) as client:
380
+ # get existing project structure
381
+ try:
382
+ structure = get_project_structure(project_id, base_url, token, client)
383
+ source_code_folder = get_folder_by_name(structure, "source_code")
384
+ root_files, source_code_files = get_all_remote_files(
385
+ structure, source_code_folder
386
+ )
387
+ except Exception as e:
388
+ console.error(f"Failed to get project structure: {str(e)}")
389
+ raise
390
+
391
+ # keep track of processed files to identify which ones to delete later
392
+ processed_root_files: Set[str] = set()
393
+ processed_source_files: Set[str] = set()
394
+
395
+ # Create source_code folder if it doesn't exist
396
+ if not source_code_folder:
397
+ try:
398
+ source_code_folder = create_project_folder(
399
+ project_id, "source_code", base_url, token, client
400
+ )
401
+ console.success(
402
+ f"Created {click.style('source_code', fg='cyan')} folder"
403
+ )
404
+ source_code_files = {} # Initialize empty dict for new folder
405
+ except httpx.HTTPStatusError as http_err:
406
+ if http_err.response.status_code == 423:
407
+ console.error(
408
+ "Resource is locked. Unable to create 'source_code' folder."
409
+ )
410
+ raise
411
+
412
+ except Exception as e:
413
+ console.error(f"Failed to create 'source_code' folder: {str(e)}")
414
+ raise
415
+
416
+ # Update agent.json first at root level
417
+ try:
418
+ update_agent_json(
419
+ project_id,
420
+ base_url,
421
+ token,
422
+ directory,
423
+ client,
424
+ processed_root_files,
425
+ root_files.get("agent.json", None),
426
+ )
427
+ except Exception as e:
428
+ console.error(f"Failed to update agent.json: {str(e)}")
429
+ raise
430
+
431
+ # Continue with rest of files in source_code folder
432
+ for file_path in files:
433
+ try:
434
+ abs_path = os.path.abspath(os.path.join(directory, file_path))
435
+ if not os.path.exists(abs_path):
436
+ console.warning(
437
+ f"File not found: {click.style(abs_path, fg='cyan')}"
438
+ )
439
+ continue
440
+
441
+ file_name = os.path.basename(file_path)
442
+
443
+ # Skip agent.json as it's already handled
444
+ if file_name == "agent.json":
445
+ continue
446
+
447
+ remote_file = source_code_files.get(file_name)
448
+ processed_source_files.add(file_name)
449
+
450
+ with open(abs_path, "rb") as f:
451
+ files_data = {"file": (file_name, f, "application/octet-stream")}
452
+ form_data = {"parentId": source_code_folder.id}
453
+
454
+ if remote_file:
455
+ # File exists in source_code folder, use PUT to update
456
+ url = f"{base_api_url}/File/{remote_file.id}"
457
+ response = client.put(url, files=files_data, headers=headers)
458
+ action = "Updated"
459
+ else:
460
+ # File doesn't exist, use POST to create in source_code folder
461
+ url = f"{base_api_url}/File"
462
+ response = client.post(
463
+ url, files=files_data, data=form_data, headers=headers
464
+ )
465
+ action = "Uploaded"
466
+
467
+ response.raise_for_status()
468
+ console.success(f"{action} {click.style(file_path, fg='cyan')}")
469
+
470
+ except Exception as e:
471
+ console.error(
472
+ f"Failed to upload {click.style(file_path, fg='cyan')}: {str(e)}"
473
+ )
474
+ raise
475
+
476
+ # Delete files that no longer exist locally
477
+ if source_code_files:
478
+ for file_name, remote_file in source_code_files.items():
479
+ if file_name not in processed_source_files:
480
+ try:
481
+ delete_remote_file(
482
+ project_id, remote_file.id, base_url, token, client
483
+ )
484
+ console.success(
485
+ f"Deleted remote file {click.style(file_name, fg='cyan')}"
486
+ )
487
+ except Exception as e:
488
+ console.error(
489
+ f"Failed to delete remote file {click.style(file_name, fg='cyan')}: {str(e)}"
490
+ )
491
+ raise
492
+
493
+
494
+ @click.command()
495
+ @click.argument("root", type=str, default="./")
496
+ @click.option(
497
+ "--nolock",
498
+ is_flag=True,
499
+ help="Skip running uv lock and exclude uv.lock from the package",
500
+ )
501
+ @track
502
+ def push(root: str, nolock: bool) -> None:
503
+ """Push local project files to Studio Web Project.
504
+
505
+ This command pushes the local project files to a UiPath Studio Web project.
506
+ It ensures that the remote project structure matches the local files by:
507
+ - Updating existing files that have changed
508
+ - Uploading new files
509
+ - Deleting remote files that no longer exist locally
510
+ - Optionally managing the UV lock file
511
+
512
+ Args:
513
+ root: The root directory of the project
514
+ nolock: Whether to skip UV lock operations and exclude uv.lock from push
515
+
516
+ Environment Variables:
517
+ UIPATH_PROJECT_ID: Required. The ID of the UiPath Cloud project
518
+
519
+ Example:
520
+ $ uipath push
521
+ $ uipath push --nolock
522
+ """
523
+ ensure_config_file(root)
524
+ config = get_project_config(root)
525
+ validate_config(config)
526
+
527
+ if not os.getenv("UIPATH_PROJECT_ID", False):
528
+ console.error("UIPATH_PROJECT_ID environment variable not found.")
529
+ [base_url, token] = get_env_vars()
530
+
531
+ with console.spinner("Pushing coded UiPath project to Studio Web..."):
532
+ try:
533
+ # Handle uv operations before packaging, unless nolock is specified
534
+ if not nolock:
535
+ handle_uv_operations(root)
536
+
537
+ upload_source_files_to_project(
538
+ os.getenv("UIPATH_PROJECT_ID"),
539
+ config,
540
+ root,
541
+ base_url,
542
+ token,
543
+ include_uv_lock=not nolock,
544
+ )
545
+ except Exception:
546
+ console.error("Failed to push UiPath project")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: uipath
3
- Version: 2.1.3
3
+ Version: 2.1.5
4
4
  Summary: Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools.
5
5
  Project-URL: Homepage, https://uipath.com
6
6
  Project-URL: Repository, https://github.com/UiPath/uipath-python
@@ -5,25 +5,26 @@ uipath/_folder_context.py,sha256=UMMoU1VWEfYHAZW3Td2SIFYhw5dYsmaaKFhW_JEm6oc,192
5
5
  uipath/_uipath.py,sha256=ZfEcqpY7NRSm6rB2OPgyVXBl9DCnn750ikq8VzzTO_s,4146
6
6
  uipath/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  uipath/_cli/README.md,sha256=GLtCfbeIKZKNnGTCsfSVqRQ27V1btT1i2bSAyW_xZl4,474
8
- uipath/_cli/__init__.py,sha256=vGz3vJHkUvgK9_lKdzqiwwHkge1TCALRiOzGGwyr-8E,1885
9
- uipath/_cli/cli_auth.py,sha256=kWk0tznOxmU6xwhJgUAMipTevH2iTIotcNiIwmPlpYI,6507
8
+ uipath/_cli/__init__.py,sha256=VKcdFaQtoGiyPhxBCx74EMz-sGC3957D21g1DMGXJ7w,1958
9
+ uipath/_cli/cli_auth.py,sha256=RUSBHfmqhBtITrx52FeXMlVCuNyo8vrjTdjEhmM1Khw,6734
10
10
  uipath/_cli/cli_deploy.py,sha256=KPCmQ0c_NYD5JofSDao5r6QYxHshVCRxlWDVnQvlp5w,645
11
11
  uipath/_cli/cli_init.py,sha256=SmB7VplpXRSa5sgqgzojNsZDw0zfsEi2TfkMx3eQpTo,5132
12
12
  uipath/_cli/cli_invoke.py,sha256=FurosrZNGlmANIrplKWhw3EQ1b46ph5Z2rPwVaYJgmc,4001
13
13
  uipath/_cli/cli_new.py,sha256=9378NYUBc9j-qKVXV7oja-jahfJhXBg8zKVyaon7ctY,2102
14
- uipath/_cli/cli_pack.py,sha256=P7tX3CJg2fzoLhPMHbr6m1fKXWRv2QkyIGgNM1MajT0,20978
14
+ uipath/_cli/cli_pack.py,sha256=D1sIk91Ka1_dMWAOFuHemeqwUvlgPZKDuvfasoTyAE0,10557
15
15
  uipath/_cli/cli_publish.py,sha256=QT17JTClAyLve6ZjB-WvQaJ-j4DdmNneV_eDRyXjeeQ,6578
16
+ uipath/_cli/cli_push.py,sha256=YfATg8auLii0IUQJLWPSA_M_iHNylNE2aIQUtDBMdzQ,18836
16
17
  uipath/_cli/cli_run.py,sha256=cTZYWJkGk2ruk6RRJBXII9J6VjpgGmysv_KlKI1JMHo,6446
17
18
  uipath/_cli/middlewares.py,sha256=CN-QqV69zZPI-hvizvEIb-zTcNh9WjsZIYCF3_nHSio,4915
18
19
  uipath/_cli/spinner.py,sha256=bS-U_HA5yne11ejUERu7CQoXmWdabUD2bm62EfEdV8M,1107
19
- uipath/_cli/_auth/_auth_server.py,sha256=p93_EvJpdoLLkiVmLygHRKo9ru1-PZOEAaEhNFN3j6c,6424
20
+ uipath/_cli/_auth/_auth_server.py,sha256=Wx3TaK5QvGzaJytp2cnYO3NFVIvTsNqxfVMwBquEyQs,7162
20
21
  uipath/_cli/_auth/_client_credentials.py,sha256=eENVb54-uzEqi7bC5VNjsiULW4fSfs-sK0kgUjRKorA,5412
21
22
  uipath/_cli/_auth/_models.py,sha256=sYMCfvmprIqnZxStlD_Dxx2bcxgn0Ri4D7uwemwkcNg,948
22
23
  uipath/_cli/_auth/_oidc_utils.py,sha256=WaX9jDlXrlX6yD8i8gsocV8ngjaT72Xd1tvsZMmSbco,2127
23
24
  uipath/_cli/_auth/_portal_service.py,sha256=iAxEDEY7OcEbIUSKNZnURAuNsimNmU90NLHkkTLqREY,8079
24
25
  uipath/_cli/_auth/_utils.py,sha256=9nb76xe5XmDZ0TAncp-_1SKqL6FdwRi9eS3C2noN1lY,1591
25
- uipath/_cli/_auth/auth_config.json,sha256=xwh6paXwW3TDIsz2UHP_q3TxmBW-njFXh1q4Nd0knUA,411
26
- uipath/_cli/_auth/index.html,sha256=ML_xDOcKs0ETYucufJskiYfWSvdrD_E26C0Qd3qpGj8,6280
26
+ uipath/_cli/_auth/auth_config.json,sha256=YWGtKyDgLl57T4g0M0AYyhrLs_G-294yNB24lzBGtbA,429
27
+ uipath/_cli/_auth/index.html,sha256=_Q2OtqPfapG_6vumbQYqtb2PfFe0smk7TlGERKEBvB4,22518
27
28
  uipath/_cli/_auth/localhost.crt,sha256=oGl9oLLOiouHubAt39B4zEfylFvKEtbtr_43SIliXJc,1226
28
29
  uipath/_cli/_auth/localhost.key,sha256=X31VYXD8scZtmGA837dGX5l6G-LXHLo5ItWJhZXaz3c,1679
29
30
  uipath/_cli/_runtime/_contracts.py,sha256=j81Ou6Xz24K2UwEsxU-efvd775xKnZt08Rit94VZEYg,15251
@@ -38,13 +39,16 @@ uipath/_cli/_templates/main.py.template,sha256=QB62qX5HKDbW4lFskxj7h9uuxBITnTWqu
38
39
  uipath/_cli/_templates/package.nuspec.template,sha256=YZyLc-u_EsmIoKf42JsLQ55OGeFmb8VkIU2VF7DFbtw,359
39
40
  uipath/_cli/_utils/_common.py,sha256=wQ0a_lGj0bsuNvwxUfnLwg6T3IdatdfkrPcZMoufJNU,2058
40
41
  uipath/_cli/_utils/_console.py,sha256=rj4V3yeR1wnJzFTHnaE6wcY9OoJV-PiIQnLg_p62ClQ,6664
41
- uipath/_cli/_utils/_constants.py,sha256=9mRv_ZQoEPfvtTMipraQmYMJeCxcaLL7w8cYy4gJoQE,1225
42
+ uipath/_cli/_utils/_constants.py,sha256=AXeVidtHUFiODrkB2BCX_bqDL-bUzRg-Ieh1-2cCrGA,1374
42
43
  uipath/_cli/_utils/_debug.py,sha256=zamzIR4VgbdKADAE4gbmjxDsbgF7wvdr7C5Dqp744Oc,1739
43
44
  uipath/_cli/_utils/_folders.py,sha256=UVJcKPfPAVR5HF4AP6EXdlNVcfEF1v5pwGCpoAgBY34,1155
44
45
  uipath/_cli/_utils/_input_args.py,sha256=pyQhEcQXHdFHYTVNzvfWp439aii5StojoptnmCv5lfs,4094
45
46
  uipath/_cli/_utils/_parse_ast.py,sha256=A-QToBIf-oP7yP2DQTHO6blkk6ik5z_IeaIwtEWO4e0,19516
46
47
  uipath/_cli/_utils/_processes.py,sha256=q7DfEKHISDWf3pngci5za_z0Pbnf_shWiYEcTOTCiyk,1855
48
+ uipath/_cli/_utils/_project_files.py,sha256=noGulQh95d4aqwoa-moK2kXGpIG_1Wqy7rcNmNpjaWs,12192
49
+ uipath/_cli/_utils/_studio_project.py,sha256=_gED64JeVc0u2i0L0Exr-pfnArdlDVPJzAD738YLr24,4443
47
50
  uipath/_cli/_utils/_tracing.py,sha256=2igb03j3EHjF_A406UhtCKkPfudVfFPjUq5tXUEG4oo,1541
51
+ uipath/_cli/_utils/_uv_helpers.py,sha256=6SvoLnZPoKIxW0sjMvD1-ENV_HOXDYzH34GjBqwT138,3450
48
52
  uipath/_services/__init__.py,sha256=10xtw3ENC30yR9CCq_b94RMZ3YrUeyfHV33yWYUd8tU,896
49
53
  uipath/_services/_base_service.py,sha256=twcUCLS_V4D1kxcJt6lckd7rqsVRcy4mfHOflJpu1k0,5830
50
54
  uipath/_services/actions_service.py,sha256=LYKvG4VxNGQgZ46AzGK9kI1Txb-YmVvZj5ScPOue8Ls,15989
@@ -95,8 +99,8 @@ uipath/tracing/_traced.py,sha256=qeVDrds2OUnpdUIA0RhtF0kg2dlAZhyC1RRkI-qivTM,185
95
99
  uipath/tracing/_utils.py,sha256=ZeensQexnw69jVcsVrGyED7mPlAU-L1agDGm6_1A3oc,10388
96
100
  uipath/utils/__init__.py,sha256=VD-KXFpF_oWexFg6zyiWMkxl2HM4hYJMIUDZ1UEtGx0,105
97
101
  uipath/utils/_endpoints_manager.py,sha256=hiGEu6vyfQJoeiiql6w21TNiG6tADUfXlVBimxPU1-Q,4160
98
- uipath-2.1.3.dist-info/METADATA,sha256=c6ZrTqWnqHX5IxItucH3tjrPgEWysnmw7xFrFvBGXl0,6366
99
- uipath-2.1.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
100
- uipath-2.1.3.dist-info/entry_points.txt,sha256=9C2_29U6Oq1ExFu7usihR-dnfIVNSKc-0EFbh0rskB4,43
101
- uipath-2.1.3.dist-info/licenses/LICENSE,sha256=-KBavWXepyDjimmzH5fVAsi-6jNVpIKFc2kZs0Ri4ng,1058
102
- uipath-2.1.3.dist-info/RECORD,,
102
+ uipath-2.1.5.dist-info/METADATA,sha256=Px-dHMamoQ-J4yymxgv8LXjDzmLXyJvV8pGV8YrOKc4,6366
103
+ uipath-2.1.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
104
+ uipath-2.1.5.dist-info/entry_points.txt,sha256=9C2_29U6Oq1ExFu7usihR-dnfIVNSKc-0EFbh0rskB4,43
105
+ uipath-2.1.5.dist-info/licenses/LICENSE,sha256=-KBavWXepyDjimmzH5fVAsi-6jNVpIKFc2kZs0Ri4ng,1058
106
+ uipath-2.1.5.dist-info/RECORD,,
File without changes