uipath 2.0.20__tar.gz → 2.0.22__tar.gz
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.
- uipath-2.0.22/.github/workflows/publish-dev.yml +109 -0
- {uipath-2.0.20 → uipath-2.0.22}/PKG-INFO +2 -1
- {uipath-2.0.20 → uipath-2.0.22}/pyproject.toml +5 -1
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/__init__.py +12 -1
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_auth/_auth_server.py +3 -2
- uipath-2.0.22/src/uipath/_cli/_utils/_common.py +45 -0
- uipath-2.0.22/src/uipath/_cli/_utils/_folders.py +29 -0
- uipath-2.0.22/src/uipath/_cli/_utils/_processes.py +49 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/cli_auth.py +25 -15
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/cli_init.py +11 -8
- uipath-2.0.22/src/uipath/_cli/cli_invoke.py +105 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/cli_new.py +11 -5
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/cli_pack.py +30 -16
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/cli_publish.py +49 -36
- uipath-2.0.22/src/uipath/_cli/spinner.py +40 -0
- {uipath-2.0.20 → uipath-2.0.22}/uv.lock +3 -1
- uipath-2.0.20/src/uipath/_cli/_utils/_common.py +0 -24
- {uipath-2.0.20 → uipath-2.0.22}/.cursorrules +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/.editorconfig +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/.gitattributes +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/.github/workflows/build.yml +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/.github/workflows/cd.yml +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/.github/workflows/ci.yml +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/.github/workflows/commitlint.yml +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/.github/workflows/lint.yml +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/.github/workflows/test.yml +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/.gitignore +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/.pre-commit-config.yaml +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/.python-version +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/.vscode/extensions.json +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/.vscode/settings.json +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/CONTRIBUTING.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/LICENSE +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/README.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/docs/CONTRIBUTING.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/docs/actions.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/docs/assets/uipath-logo.svg +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/docs/assets.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/docs/buckets.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/docs/connections.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/docs/context_grounding.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/docs/getting_started_agent.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/docs/getting_started_cli.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/docs/getting_started_sdk.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/docs/index.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/docs/jobs.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/docs/processes.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/docs/queues.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/docs/sdk.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/justfile +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/mkdocs.yml +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/py.typed +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/__init__.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/README.md +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_auth/_models.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_auth/_oidc_utils.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_auth/_portal_service.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_auth/_utils.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_auth/auth_config.json +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_auth/index.html +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_auth/localhost.crt +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_auth/localhost.key +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_runtime/_contracts.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_runtime/_logging.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_runtime/_runtime.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_templates/.psmdcp.template +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_templates/.rels.template +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_templates/[Content_Types].xml.template +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_templates/main.py.template +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_templates/package.nuspec.template +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_utils/_input_args.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/_utils/_parse_ast.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/cli_deploy.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/cli_run.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_cli/middlewares.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_config.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_execution_context.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_folder_context.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_services/__init__.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_services/_base_service.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_services/actions_service.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_services/api_client.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_services/assets_service.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_services/buckets_service.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_services/connections_service.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_services/connections_service.pyi +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_services/context_grounding_service.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_services/folder_service.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_services/jobs_service.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_services/llm_gateway_service.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_services/processes_service.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_services/queues_service.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_uipath.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_utils/__init__.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_utils/_endpoint.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_utils/_infer_bindings.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_utils/_logs.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_utils/_request_override.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_utils/_request_spec.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_utils/_user_agent.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/_utils/constants.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/models/__init__.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/models/action_schema.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/models/actions.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/models/assets.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/models/connections.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/models/context_grounding.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/models/context_grounding_index.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/models/exceptions.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/models/interrupt_models.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/models/job.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/models/llm_gateway.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/models/processes.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/models/queues.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/py.typed +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/tracing/__init__.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/tracing/_otel_exporters.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/tracing/_traced.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/src/uipath/tracing/_utils.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/tests/__init__.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/tests/cli/test_init.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/tests/conftest.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/tests/sdk/services/test_llm_integration.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/tests/sdk/services/test_llm_service.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/tests/sdk/services/test_uipath_llm_integration.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/tests/sdk/test_config.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/tests/tracing/test_otel_exporters.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/tests/tracing/test_span_utils.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/tests/tracing/test_traced.py +0 -0
- {uipath-2.0.20 → uipath-2.0.22}/tests/tracing/test_tracing_manager.py +0 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
name: Publish Dev Build
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, synchronize, reopened, labeled]
|
|
6
|
+
secrets:
|
|
7
|
+
PYPI_TOKEN:
|
|
8
|
+
required: true
|
|
9
|
+
TESTPYPI_TOKEN:
|
|
10
|
+
required: true
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
publish-dev:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
|
|
17
|
+
# Only run if PR has the build:dev label
|
|
18
|
+
if: contains(github.event.pull_request.labels.*.name, 'build:dev')
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- uses: astral-sh/setup-uv@v5
|
|
24
|
+
|
|
25
|
+
- uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version-file: ".python-version"
|
|
28
|
+
|
|
29
|
+
- name: Setup venv
|
|
30
|
+
run: |
|
|
31
|
+
uv venv
|
|
32
|
+
uv sync --all-extras
|
|
33
|
+
|
|
34
|
+
- name: Set development version
|
|
35
|
+
shell: pwsh
|
|
36
|
+
env:
|
|
37
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
38
|
+
run: |
|
|
39
|
+
$pyprojcontent = Get-Content pyproject.toml -Raw
|
|
40
|
+
|
|
41
|
+
$PROJECT_NAME = ($pyprojcontent | Select-String -Pattern '(?m)^\[(project|tool\.poetry)\][^\[]*?name\s*=\s*"([^"]*)"' -AllMatches).Matches[0].Groups[2].Value
|
|
42
|
+
$CURRENT_VERSION = ($pyprojcontent | Select-String -Pattern '(?m)^\[(project|tool\.poetry)\][^\[]*?version\s*=\s*"([^"]*)"' -AllMatches).Matches[0].Groups[2].Value
|
|
43
|
+
$NIGHTLY_NAME = "$PROJECT_NAME-nightly"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# Get PR number and run number with proper padding
|
|
47
|
+
$PR_NUM = [int]"${{ github.event.pull_request.number }}"
|
|
48
|
+
$PADDED_PR = "{0:D5}" -f [int]"${{ github.event.pull_request.number }}"
|
|
49
|
+
$PADDED_RUN = "{0:D4}" -f [int]"${{ github.run_number }}"
|
|
50
|
+
$PADDED_NEXT_PR = "{0:D5}" -f ($PR_NUM + 1)
|
|
51
|
+
|
|
52
|
+
# Create version range strings for PR
|
|
53
|
+
$MIN_VERSION = "$CURRENT_VERSION.dev1$PADDED_PR" + "0000"
|
|
54
|
+
$MAX_VERSION = "$CURRENT_VERSION.dev1$PADDED_NEXT_PR" + "0000"
|
|
55
|
+
|
|
56
|
+
# Create unique dev version with PR number and run ID
|
|
57
|
+
$DEV_VERSION = "$CURRENT_VERSION.dev1$PADDED_PR$PADDED_RUN"
|
|
58
|
+
|
|
59
|
+
# Update version in pyproject.toml
|
|
60
|
+
(Get-Content pyproject.toml) -replace "version = `"$CURRENT_VERSION`"", "version = `"$DEV_VERSION`"" | Set-Content pyproject.toml
|
|
61
|
+
|
|
62
|
+
# Update project name in pyproject.toml
|
|
63
|
+
(Get-Content pyproject.toml) -replace "name = `"$PROJECT_NAME`"", "name = `"$NIGHTLY_NAME`"" | Set-Content pyproject.toml
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
Write-Output "Package version set to $DEV_VERSION"
|
|
67
|
+
|
|
68
|
+
$dependencyMessage = @"
|
|
69
|
+
- Add this package as a dependency in your pyproject.toml:
|
|
70
|
+
|
|
71
|
+
``````toml
|
|
72
|
+
[project]
|
|
73
|
+
dependencies = [
|
|
74
|
+
# Exact version:
|
|
75
|
+
"$NIGHTLY_NAME==$DEV_VERSION",
|
|
76
|
+
|
|
77
|
+
# Any version from PR
|
|
78
|
+
"$NIGHTLY_NAME>=$MIN_VERSION,<$MAX_VERSION"
|
|
79
|
+
]
|
|
80
|
+
``````
|
|
81
|
+
"@
|
|
82
|
+
Write-Output $dependencyMessage
|
|
83
|
+
|
|
84
|
+
# Post comment to GitHub PR
|
|
85
|
+
$owner = "${{ github.repository_owner }}"
|
|
86
|
+
$repo = "${{ github.repository }}".Split('/')[1]
|
|
87
|
+
$issueNumber = $PR_NUM
|
|
88
|
+
|
|
89
|
+
$body = @{
|
|
90
|
+
body = $dependencyMessage
|
|
91
|
+
} | ConvertTo-Json
|
|
92
|
+
|
|
93
|
+
# Create the comment using GitHub REST API
|
|
94
|
+
$uri = "https://api.github.com/repos/$owner/$repo/issues/$issueNumber/comments"
|
|
95
|
+
$headers = @{
|
|
96
|
+
Authorization = "token $env:GITHUB_TOKEN"
|
|
97
|
+
Accept = "application/vnd.github.v3+json"
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
Invoke-RestMethod -Uri $uri -Method Post -Body $body -Headers $headers -ContentType "application/json"
|
|
101
|
+
|
|
102
|
+
- name: Build package
|
|
103
|
+
run: uv build
|
|
104
|
+
|
|
105
|
+
- name: Publish
|
|
106
|
+
run: |
|
|
107
|
+
uv publish
|
|
108
|
+
env:
|
|
109
|
+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: uipath
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.22
|
|
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
|
|
@@ -21,6 +21,7 @@ Requires-Dist: pydantic>=2.11.1
|
|
|
21
21
|
Requires-Dist: pytest-asyncio>=0.25.3
|
|
22
22
|
Requires-Dist: python-dotenv>=1.0.1
|
|
23
23
|
Requires-Dist: requests>=2.32.3
|
|
24
|
+
Requires-Dist: rich>=13.0.0
|
|
24
25
|
Requires-Dist: tenacity>=9.0.0
|
|
25
26
|
Requires-Dist: tomli>=2.2.1
|
|
26
27
|
Requires-Dist: types-requests>=2.32.0.20250306
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "uipath"
|
|
3
|
-
version = "2.0.
|
|
3
|
+
version = "2.0.22"
|
|
4
4
|
description = "Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools."
|
|
5
5
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -16,6 +16,7 @@ dependencies = [
|
|
|
16
16
|
"tomli>=2.2.1",
|
|
17
17
|
"types-requests>=2.32.0.20250306",
|
|
18
18
|
"pathlib>=1.0.1",
|
|
19
|
+
"rich>=13.0.0",
|
|
19
20
|
]
|
|
20
21
|
classifiers = [
|
|
21
22
|
"Development Status :: 3 - Alpha",
|
|
@@ -60,6 +61,9 @@ dev = [
|
|
|
60
61
|
[project.optional-dependencies]
|
|
61
62
|
langchain = ["uipath-langchain>=0.0.88,<0.1.0"]
|
|
62
63
|
|
|
64
|
+
[tool.hatch.build.targets.wheel]
|
|
65
|
+
packages = ["src/uipath"]
|
|
66
|
+
|
|
63
67
|
[tool.ruff]
|
|
64
68
|
line-length = 88
|
|
65
69
|
indent-width = 4
|
|
@@ -6,15 +6,25 @@ import click
|
|
|
6
6
|
from .cli_auth import auth as auth # type: ignore
|
|
7
7
|
from .cli_deploy import deploy as deploy # type: ignore
|
|
8
8
|
from .cli_init import init as init # type: ignore
|
|
9
|
+
from .cli_invoke import invoke as invoke # type: ignore
|
|
9
10
|
from .cli_new import new as new # type: ignore
|
|
10
11
|
from .cli_pack import pack as pack # type: ignore
|
|
11
12
|
from .cli_publish import publish as publish # type: ignore
|
|
12
13
|
from .cli_run import run as run # type: ignore
|
|
13
14
|
|
|
14
15
|
|
|
16
|
+
def _get_safe_version() -> str:
|
|
17
|
+
"""Get the version of the uipath package."""
|
|
18
|
+
try:
|
|
19
|
+
version = importlib.metadata.version("uipath")
|
|
20
|
+
return version
|
|
21
|
+
except importlib.metadata.PackageNotFoundError:
|
|
22
|
+
return "unknown"
|
|
23
|
+
|
|
24
|
+
|
|
15
25
|
@click.group(invoke_without_command=True)
|
|
16
26
|
@click.version_option(
|
|
17
|
-
|
|
27
|
+
_get_safe_version(),
|
|
18
28
|
prog_name="uipath",
|
|
19
29
|
message="%(prog)s version %(version)s",
|
|
20
30
|
)
|
|
@@ -52,3 +62,4 @@ cli.add_command(publish)
|
|
|
52
62
|
cli.add_command(run)
|
|
53
63
|
cli.add_command(deploy)
|
|
54
64
|
cli.add_command(auth)
|
|
65
|
+
cli.add_command(invoke)
|
|
@@ -5,6 +5,7 @@ import socketserver
|
|
|
5
5
|
import ssl
|
|
6
6
|
import time
|
|
7
7
|
|
|
8
|
+
import click
|
|
8
9
|
from dotenv import load_dotenv
|
|
9
10
|
|
|
10
11
|
from ._oidc_utils import get_auth_config
|
|
@@ -38,7 +39,7 @@ def make_request_handler_class(state, code_verifier, token_callback, domain):
|
|
|
38
39
|
content_length = int(self.headers["Content-Length"])
|
|
39
40
|
post_data = self.rfile.read(content_length)
|
|
40
41
|
token_data = json.loads(post_data.decode("utf-8"))
|
|
41
|
-
|
|
42
|
+
click.echo("Received authentication information")
|
|
42
43
|
|
|
43
44
|
self.send_response(200)
|
|
44
45
|
self.end_headers()
|
|
@@ -179,7 +180,7 @@ class HTTPSServer:
|
|
|
179
180
|
while not self.should_shutdown:
|
|
180
181
|
self.httpd.handle_request()
|
|
181
182
|
except KeyboardInterrupt:
|
|
182
|
-
|
|
183
|
+
click.echo("Process interrupted by user")
|
|
183
184
|
finally:
|
|
184
185
|
self.stop()
|
|
185
186
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
|
|
6
|
+
from ..spinner import Spinner
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def environment_options(function):
|
|
10
|
+
function = click.option(
|
|
11
|
+
"--alpha",
|
|
12
|
+
"domain",
|
|
13
|
+
flag_value="alpha",
|
|
14
|
+
help="Use alpha environment",
|
|
15
|
+
)(function)
|
|
16
|
+
function = click.option(
|
|
17
|
+
"--staging",
|
|
18
|
+
"domain",
|
|
19
|
+
flag_value="staging",
|
|
20
|
+
help="Use staging environment",
|
|
21
|
+
)(function)
|
|
22
|
+
function = click.option(
|
|
23
|
+
"--cloud",
|
|
24
|
+
"domain",
|
|
25
|
+
flag_value="cloud",
|
|
26
|
+
default=True,
|
|
27
|
+
help="Use production environment",
|
|
28
|
+
)(function)
|
|
29
|
+
return function
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def get_env_vars(spinner: Optional[Spinner] = None) -> list[str | None]:
|
|
33
|
+
base_url = os.environ.get("UIPATH_URL")
|
|
34
|
+
token = os.environ.get("UIPATH_ACCESS_TOKEN")
|
|
35
|
+
|
|
36
|
+
if not all([base_url, token]):
|
|
37
|
+
if spinner:
|
|
38
|
+
spinner.stop()
|
|
39
|
+
click.echo(
|
|
40
|
+
"❌ Missing required environment variables. Please check your .env file contains:"
|
|
41
|
+
)
|
|
42
|
+
click.echo("UIPATH_URL, UIPATH_ACCESS_TOKEN")
|
|
43
|
+
click.get_current_context().exit(1)
|
|
44
|
+
|
|
45
|
+
return [base_url, token]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from typing import Optional, Tuple
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
import requests
|
|
5
|
+
|
|
6
|
+
from ..spinner import Spinner
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_personal_workspace_info(
|
|
10
|
+
base_url: str, token: str, spinner: Optional[Spinner] = None
|
|
11
|
+
) -> Tuple[str, str]:
|
|
12
|
+
user_url = f"{base_url}/orchestrator_/odata/Users/UiPath.Server.Configuration.OData.GetCurrentUserExtended?$expand=PersonalWorkspace"
|
|
13
|
+
user_response = requests.get(user_url, headers={"Authorization": f"Bearer {token}"})
|
|
14
|
+
|
|
15
|
+
if user_response.status_code != 200:
|
|
16
|
+
if spinner:
|
|
17
|
+
spinner.stop()
|
|
18
|
+
click.echo("❌ Failed to get user info. Please try reauthenticating.")
|
|
19
|
+
click.get_current_context().exit(1)
|
|
20
|
+
|
|
21
|
+
user_data = user_response.json()
|
|
22
|
+
feed_id = user_data.get("PersonalWorskpaceFeedId")
|
|
23
|
+
folder_id = user_data["PersonalWorkspace"].get("Id")
|
|
24
|
+
if not (feed_id and folder_id):
|
|
25
|
+
if spinner:
|
|
26
|
+
spinner.stop()
|
|
27
|
+
click.echo("❌ No personal workspace found for user")
|
|
28
|
+
click.get_current_context().exit(1)
|
|
29
|
+
return feed_id, folder_id
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import urllib.parse
|
|
3
|
+
from typing import Any, Optional
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
import requests
|
|
7
|
+
|
|
8
|
+
from ..spinner import Spinner
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def get_release_info(
|
|
12
|
+
base_url: str,
|
|
13
|
+
token: str,
|
|
14
|
+
package_name: str,
|
|
15
|
+
folder_id: str,
|
|
16
|
+
spinner: Optional[Spinner] = None,
|
|
17
|
+
) -> None | tuple[Any, Any] | tuple[None, None]:
|
|
18
|
+
headers = {
|
|
19
|
+
"Authorization": f"Bearer {token}",
|
|
20
|
+
"x-uipath-organizationunitid": str(folder_id),
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
release_url = f"{base_url}/orchestrator_/odata/Releases/UiPath.Server.Configuration.OData.ListReleases?$select=Id,Key&$top=1&$filter=(contains(Name,%27{urllib.parse.quote(package_name)}%27))&$orderby=Name%20asc"
|
|
24
|
+
response = requests.get(release_url, headers=headers)
|
|
25
|
+
if response.status_code == 200:
|
|
26
|
+
try:
|
|
27
|
+
data = json.loads(response.text)
|
|
28
|
+
release_id = data["value"][0]["Id"]
|
|
29
|
+
release_key = data["value"][0]["Key"]
|
|
30
|
+
return release_id, release_key
|
|
31
|
+
except KeyError:
|
|
32
|
+
if spinner:
|
|
33
|
+
spinner.stop()
|
|
34
|
+
click.echo("\n⚠️ Warning: Failed to deserialize release data")
|
|
35
|
+
return None, None
|
|
36
|
+
except IndexError:
|
|
37
|
+
if spinner:
|
|
38
|
+
spinner.stop()
|
|
39
|
+
click.echo(
|
|
40
|
+
"\n❌ Process not found in your workspace. Try publishing it first."
|
|
41
|
+
)
|
|
42
|
+
click.get_current_context().exit(1)
|
|
43
|
+
|
|
44
|
+
else:
|
|
45
|
+
if spinner:
|
|
46
|
+
spinner.stop()
|
|
47
|
+
click.echo("\n⚠️ Warning: Failed to fetch release info")
|
|
48
|
+
click.echo(f"Status code: {response.status_code}")
|
|
49
|
+
return None, None
|
|
@@ -12,6 +12,7 @@ from ._auth._oidc_utils import get_auth_config, get_auth_url
|
|
|
12
12
|
from ._auth._portal_service import PortalService, select_tenant
|
|
13
13
|
from ._auth._utils import update_auth_file, update_env_file
|
|
14
14
|
from ._utils._common import environment_options
|
|
15
|
+
from .spinner import Spinner
|
|
15
16
|
|
|
16
17
|
load_dotenv()
|
|
17
18
|
|
|
@@ -37,7 +38,7 @@ def set_port():
|
|
|
37
38
|
if is_port_in_use(port_option_two):
|
|
38
39
|
if is_port_in_use(port_option_three):
|
|
39
40
|
raise RuntimeError(
|
|
40
|
-
"All configured ports are in use. Please close applications using ports or configure different ports."
|
|
41
|
+
"❌ All configured ports are in use. Please close applications using ports or configure different ports."
|
|
41
42
|
)
|
|
42
43
|
else:
|
|
43
44
|
port = port_option_three
|
|
@@ -56,6 +57,8 @@ def set_port():
|
|
|
56
57
|
@environment_options
|
|
57
58
|
def auth(domain="alpha"):
|
|
58
59
|
"""Authenticate with UiPath Cloud Platform."""
|
|
60
|
+
spinner = Spinner("Authenticating with UiPath...")
|
|
61
|
+
spinner.start()
|
|
59
62
|
portal_service = PortalService(domain)
|
|
60
63
|
if (
|
|
61
64
|
os.getenv("UIPATH_URL")
|
|
@@ -64,9 +67,13 @@ def auth(domain="alpha"):
|
|
|
64
67
|
):
|
|
65
68
|
try:
|
|
66
69
|
portal_service.ensure_valid_token()
|
|
67
|
-
|
|
70
|
+
spinner.stop()
|
|
71
|
+
click.echo(
|
|
72
|
+
click.style("✓ ", fg="green", bold=True) + "Authentication successful"
|
|
73
|
+
)
|
|
68
74
|
return
|
|
69
75
|
except Exception:
|
|
76
|
+
spinner.stop()
|
|
70
77
|
click.echo(
|
|
71
78
|
"Authentication not found or expired. Please authenticate again."
|
|
72
79
|
)
|
|
@@ -75,23 +82,26 @@ def auth(domain="alpha"):
|
|
|
75
82
|
|
|
76
83
|
webbrowser.open(auth_url, 1)
|
|
77
84
|
auth_config = get_auth_config()
|
|
78
|
-
|
|
85
|
+
spinner.stop()
|
|
79
86
|
print(
|
|
80
87
|
"If a browser window did not open, please open the following URL in your browser:"
|
|
81
88
|
)
|
|
82
89
|
print(auth_url)
|
|
90
|
+
|
|
83
91
|
server = HTTPSServer(port=auth_config["port"])
|
|
84
92
|
token_data = server.start(state, code_verifier, domain)
|
|
85
|
-
try:
|
|
86
|
-
if token_data:
|
|
87
|
-
portal_service.update_token_data(token_data)
|
|
88
|
-
update_auth_file(token_data)
|
|
89
|
-
access_token = token_data["access_token"]
|
|
90
|
-
update_env_file({"UIPATH_ACCESS_TOKEN": access_token})
|
|
91
93
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
if token_data:
|
|
95
|
+
portal_service.update_token_data(token_data)
|
|
96
|
+
update_auth_file(token_data)
|
|
97
|
+
access_token = token_data["access_token"]
|
|
98
|
+
update_env_file({"UIPATH_ACCESS_TOKEN": access_token})
|
|
99
|
+
|
|
100
|
+
tenants_and_organizations = portal_service.get_tenants_and_organizations()
|
|
101
|
+
select_tenant(domain, tenants_and_organizations)
|
|
102
|
+
click.echo(
|
|
103
|
+
click.style("✓ ", fg="green", bold=True)
|
|
104
|
+
+ "Authentication completed successfully!"
|
|
105
|
+
)
|
|
106
|
+
else:
|
|
107
|
+
click.echo("❌ Authentication failed")
|
|
@@ -11,6 +11,7 @@ import click
|
|
|
11
11
|
from ._utils._input_args import generate_args
|
|
12
12
|
from ._utils._parse_ast import generate_bindings_json
|
|
13
13
|
from .middlewares import Middlewares
|
|
14
|
+
from .spinner import Spinner
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
def generate_env_file(target_directory):
|
|
@@ -51,6 +52,7 @@ def get_user_script(directory: str, entrypoint: Optional[str] = None) -> Optiona
|
|
|
51
52
|
@click.argument("entrypoint", required=False, default=None)
|
|
52
53
|
def init(entrypoint: str) -> None:
|
|
53
54
|
"""Initialize a uipath.json configuration file for the script."""
|
|
55
|
+
spinner = Spinner("Initializing UiPath project...")
|
|
54
56
|
current_directory = os.getcwd()
|
|
55
57
|
generate_env_file(current_directory)
|
|
56
58
|
|
|
@@ -67,12 +69,11 @@ def init(entrypoint: str) -> None:
|
|
|
67
69
|
|
|
68
70
|
if not result.should_continue:
|
|
69
71
|
return
|
|
70
|
-
|
|
71
72
|
script_path = get_user_script(current_directory, entrypoint=entrypoint)
|
|
72
73
|
|
|
73
74
|
if not script_path:
|
|
74
75
|
click.get_current_context().exit(1)
|
|
75
|
-
|
|
76
|
+
spinner.start()
|
|
76
77
|
try:
|
|
77
78
|
args = generate_args(script_path)
|
|
78
79
|
|
|
@@ -94,21 +95,23 @@ def init(entrypoint: str) -> None:
|
|
|
94
95
|
# Generate bindings JSON based on the script path
|
|
95
96
|
try:
|
|
96
97
|
bindings_data = generate_bindings_json(script_path)
|
|
97
|
-
|
|
98
98
|
# Add bindings to the config data
|
|
99
99
|
config_data["bindings"] = bindings_data
|
|
100
|
-
|
|
101
|
-
click.echo("Bindings generated successfully.")
|
|
102
100
|
except Exception as e:
|
|
103
|
-
click.echo(f"Warning: Could not generate bindings: {str(e)}")
|
|
101
|
+
click.echo(f"⚠️ Warning: Could not generate bindings: {str(e)}")
|
|
104
102
|
|
|
105
103
|
config_path = "uipath.json"
|
|
106
104
|
with open(config_path, "w") as config_file:
|
|
107
105
|
json.dump(config_data, config_file, indent=4)
|
|
108
106
|
|
|
109
|
-
|
|
107
|
+
spinner.stop()
|
|
108
|
+
click.echo(
|
|
109
|
+
click.style("✓ ", fg="green", bold=True)
|
|
110
|
+
+ f"Configuration file {config_path} created successfully."
|
|
111
|
+
)
|
|
110
112
|
|
|
111
113
|
except Exception as e:
|
|
112
|
-
|
|
114
|
+
spinner.stop()
|
|
115
|
+
click.echo(f"❌ Error generating configuration: {str(e)}")
|
|
113
116
|
click.echo(traceback.format_exc())
|
|
114
117
|
click.get_current_context().exit(1)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# type: ignore
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
import requests
|
|
8
|
+
from dotenv import load_dotenv
|
|
9
|
+
|
|
10
|
+
from .spinner import Spinner
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
import tomllib
|
|
14
|
+
except ImportError:
|
|
15
|
+
import tomli as tomllib
|
|
16
|
+
|
|
17
|
+
from ._utils._common import get_env_vars
|
|
18
|
+
from ._utils._folders import get_personal_workspace_info
|
|
19
|
+
from ._utils._processes import get_release_info
|
|
20
|
+
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
load_dotenv()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _read_project_name() -> str:
|
|
26
|
+
current_path = os.getcwd()
|
|
27
|
+
toml_path = os.path.join(current_path, "pyproject.toml")
|
|
28
|
+
if not os.path.isfile(toml_path):
|
|
29
|
+
raise Exception("pyproject.toml not found")
|
|
30
|
+
|
|
31
|
+
with open(toml_path, "rb") as f:
|
|
32
|
+
content = tomllib.load(f)
|
|
33
|
+
if "project" not in content:
|
|
34
|
+
raise Exception("pyproject.toml is missing the required field: project")
|
|
35
|
+
if "name" not in content["project"]:
|
|
36
|
+
raise Exception(
|
|
37
|
+
"pyproject.toml is missing the required field: project.name"
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
return content["project"]["name"]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@click.command()
|
|
44
|
+
@click.argument("entrypoint", required=False)
|
|
45
|
+
@click.argument("input", required=False, default="{}")
|
|
46
|
+
def invoke(entrypoint: Optional[str], input: Optional[str]) -> None:
|
|
47
|
+
"""Invoke a remote agent with JSON input."""
|
|
48
|
+
spinner = Spinner("Starting job...")
|
|
49
|
+
spinner.start()
|
|
50
|
+
|
|
51
|
+
current_path = os.getcwd()
|
|
52
|
+
load_dotenv(os.path.join(current_path, ".env"), override=True)
|
|
53
|
+
[base_url, token] = get_env_vars(spinner)
|
|
54
|
+
|
|
55
|
+
url = f"{base_url}/orchestrator_/odata/Jobs/UiPath.Server.Configuration.OData.StartJobs"
|
|
56
|
+
_, personal_workspace_folder_id = get_personal_workspace_info(
|
|
57
|
+
base_url, token, spinner
|
|
58
|
+
)
|
|
59
|
+
project_name = _read_project_name()
|
|
60
|
+
|
|
61
|
+
_, release_key = get_release_info(
|
|
62
|
+
base_url, token, project_name, personal_workspace_folder_id, spinner
|
|
63
|
+
)
|
|
64
|
+
payload = {
|
|
65
|
+
"StartInfo": {
|
|
66
|
+
"ReleaseKey": str(release_key),
|
|
67
|
+
"RunAsMe": True,
|
|
68
|
+
"InputArguments": input,
|
|
69
|
+
"EntryPointPath": entrypoint,
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
headers = {
|
|
73
|
+
"Authorization": f"Bearer {token}",
|
|
74
|
+
"x-uipath-organizationunitid": str(personal_workspace_folder_id),
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
response = requests.post(url, json=payload, headers=headers)
|
|
78
|
+
spinner.stop()
|
|
79
|
+
|
|
80
|
+
if response.status_code == 201:
|
|
81
|
+
job_key = None
|
|
82
|
+
try:
|
|
83
|
+
job_key = response.json()["value"][0]["Key"]
|
|
84
|
+
except KeyError:
|
|
85
|
+
click.echo("Error: Failed to get job key from response")
|
|
86
|
+
click.Abort()
|
|
87
|
+
if job_key:
|
|
88
|
+
job_url = f"{base_url}/orchestrator_/jobs(sidepanel:sidepanel/jobs/{job_key}/details)?fid={personal_workspace_folder_id}"
|
|
89
|
+
click.echo("\n✨ Job started successfully!")
|
|
90
|
+
click.echo(
|
|
91
|
+
"\n🔗 Monitor your job here: "
|
|
92
|
+
+ click.style(
|
|
93
|
+
f"\u001b]8;;{job_url}\u001b\\{job_url}\u001b]8;;\u001b\\",
|
|
94
|
+
fg="bright_blue",
|
|
95
|
+
bold=True,
|
|
96
|
+
)
|
|
97
|
+
+ "\n"
|
|
98
|
+
)
|
|
99
|
+
else:
|
|
100
|
+
click.echo(f"\n❌ Error starting job: {response.text}")
|
|
101
|
+
click.Abort()
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
if __name__ == "__main__":
|
|
105
|
+
invoke()
|
|
@@ -6,6 +6,7 @@ import traceback
|
|
|
6
6
|
import click
|
|
7
7
|
|
|
8
8
|
from .middlewares import Middlewares
|
|
9
|
+
from .spinner import Spinner
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def generate_script(target_directory):
|
|
@@ -37,6 +38,7 @@ requires-python = ">=3.9"
|
|
|
37
38
|
@click.command()
|
|
38
39
|
@click.argument("name", type=str, default="")
|
|
39
40
|
def new(name: str):
|
|
41
|
+
spinner = Spinner("Creating new project...")
|
|
40
42
|
directory = os.getcwd()
|
|
41
43
|
|
|
42
44
|
if not name:
|
|
@@ -44,12 +46,15 @@ def new(name: str):
|
|
|
44
46
|
"Please specify a name for your project\n`uipath new hello-world`"
|
|
45
47
|
)
|
|
46
48
|
|
|
47
|
-
click.echo(
|
|
49
|
+
click.echo(
|
|
50
|
+
click.style("✓ ", fg="green", bold=True)
|
|
51
|
+
+ f"Initializing project {name} in current directory.."
|
|
52
|
+
)
|
|
48
53
|
|
|
49
54
|
result = Middlewares.next("new", name)
|
|
50
55
|
|
|
51
56
|
if result.error_message:
|
|
52
|
-
click.echo(result.error_message)
|
|
57
|
+
click.echo("❌ " + result.error_message)
|
|
53
58
|
if result.should_include_stacktrace:
|
|
54
59
|
click.echo(traceback.format_exc())
|
|
55
60
|
click.get_current_context().exit(1)
|
|
@@ -61,13 +66,14 @@ def new(name: str):
|
|
|
61
66
|
return
|
|
62
67
|
|
|
63
68
|
generate_script(directory)
|
|
64
|
-
click.echo("Created main.py file
|
|
69
|
+
click.echo(click.style("✓ ", fg="green", bold=True) + "Created main.py file")
|
|
65
70
|
generate_pyproject(directory, name)
|
|
66
|
-
click.echo("Created pyproject.toml file
|
|
67
|
-
|
|
71
|
+
click.echo(click.style("✓ ", fg="green", bold=True) + "Created pyproject.toml file")
|
|
72
|
+
spinner.start()
|
|
68
73
|
ctx = click.get_current_context()
|
|
69
74
|
init_cmd = ctx.parent.command.get_command(ctx, "init")
|
|
70
75
|
ctx.invoke(init_cmd)
|
|
76
|
+
spinner.stop()
|
|
71
77
|
|
|
72
78
|
click.echo("""` uipath run main.py '{"message": "Hello World!"}' `""")
|
|
73
79
|
|