Skip to content

Commit 62c8196

Browse files
authored
fix(login): fix login on as version 25.10.2 (#1469)
1 parent 0092c87 commit 62c8196

9 files changed

Lines changed: 115 additions & 36 deletions

File tree

packages/uipath-platform/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "uipath-platform"
3-
version = "0.1.1"
3+
version = "0.1.2"
44
description = "HTTP client library for programmatic access to UiPath Platform"
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.11"

packages/uipath-platform/src/uipath/platform/orchestrator/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@
1212
from ._orchestrator_setup_service import OrchestratorSetupService
1313
from ._processes_service import ProcessesService
1414
from ._queues_service import QueuesService
15-
from ._server_version import get_server_version, get_server_version_async
15+
from ._server_version import (
16+
get_server_info_async,
17+
get_server_version,
18+
get_server_version_async,
19+
)
1620
from .assets import Asset, UserAsset
1721
from .attachment import Attachment
1822
from .buckets import Bucket, BucketFile
@@ -37,6 +41,7 @@
3741
"ProcessesService",
3842
"QueuesService",
3943
"OrchestratorSetupService",
44+
"get_server_info_async",
4045
"get_server_version",
4146
"get_server_version_async",
4247
"Asset",

packages/uipath-platform/src/uipath/platform/orchestrator/_server_version.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""Utility for retrieving the Orchestrator server version."""
22

3+
from typing import Any
4+
35
import httpx
46

57
from ..common._http_config import get_httpx_client_kwargs
@@ -28,6 +30,28 @@ def get_server_version(domain: str) -> str | None:
2830
return None
2931

3032

33+
async def get_server_info_async(domain: str) -> dict[Any, Any] | None:
34+
"""Get the full Orchestrator server status info.
35+
36+
Args:
37+
domain: The base URL of the UiPath platform (e.g., "https://cloud.uipath.com").
38+
39+
Returns:
40+
The full server status JSON as a dict, or None if the request fails for any reason.
41+
"""
42+
url = f"{domain}/orchestrator_/api/status/version"
43+
44+
try:
45+
client_kwargs = get_httpx_client_kwargs()
46+
client_kwargs["timeout"] = 5.0
47+
async with httpx.AsyncClient(**client_kwargs) as client:
48+
response = await client.get(url)
49+
response.raise_for_status()
50+
return response.json()
51+
except Exception:
52+
return None
53+
54+
3155
async def get_server_version_async(domain: str) -> str | None:
3256
"""Get the Orchestrator server version.
3357

packages/uipath-platform/uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/uipath/pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
[project]
22
name = "uipath"
3-
version = "2.10.22"
3+
version = "2.10.23"
44
description = "Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools."
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.11"
77
dependencies = [
88
"uipath-core>=0.5.2, <0.6.0",
99
"uipath-runtime>=0.9.1, <0.10.0",
10-
"uipath-platform>=0.1.1, <0.2.0",
10+
"uipath-platform>=0.1.2, <0.2.0",
1111
"click>=8.3.1",
1212
"httpx>=0.28.1",
1313
"pyjwt>=2.10.1",

packages/uipath/src/uipath/_cli/_auth/_oidc_utils.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import os
55
from urllib.parse import urlencode, urlparse
66

7-
from uipath.platform.orchestrator import get_server_version_async
7+
from uipath.platform.orchestrator import get_server_info_async
88

99
from .._utils._console import ConsoleLogger
1010
from ._models import AuthConfig
@@ -50,10 +50,11 @@ async def _select_config_file(domain: str) -> str:
5050
5151
Logic:
5252
1. If domain is alpha/staging/cloud.uipath.com -> use auth_config_cloud.json
53-
2. Otherwise, try to get version from API
54-
3. If version starts with '25.10' -> use auth_config_25_10.json
55-
4. If version can't be determined -> fallback to auth_config_cloud.json
56-
5. Otherwise -> fallback to auth_config_cloud.json
53+
2. Otherwise, fetch server info from API
54+
3. If deployment is not 'ServiceFabric' (cloud deployment) -> use auth_config_cloud.json
55+
4. If version starts with '25.10' (AS release 25.10) -> use auth_config_25_10.json
56+
5. If version starts with '26.3' (AS release 25.10.2) -> use auth_config_25_10_2.json
57+
6. Otherwise (unknown version) -> use auth_config_25_10_2.json
5758
5859
Args:
5960
domain: The UiPath domain
@@ -65,19 +66,25 @@ async def _select_config_file(domain: str) -> str:
6566
if _is_cloud_domain(domain):
6667
return "auth_config_cloud.json"
6768

68-
# Try to get version from API
69-
version = await get_server_version_async(domain)
69+
# Fetch full server info
70+
info = await get_server_info_async(domain)
7071

71-
# If we can't determine version, fallback to cloud config
72-
if version is None:
72+
# Non-ServiceFabric deployments are cloud
73+
if info is None or info.get("deployment") != "ServiceFabric":
7374
return "auth_config_cloud.json"
7475

75-
# Check if version is 25.10.*
76+
version = info.get("version") or ""
77+
78+
# Check if version is 25.10.* (AS release 25.10)
7679
if version.startswith("25.10"):
7780
return "auth_config_25_10.json"
7881

79-
# Default fallback to cloud config
80-
return "auth_config_cloud.json"
82+
# Check if version is 26.3.* (AS release 25.10.2)
83+
if version.startswith("26.3"):
84+
return "auth_config_25_10_2.json"
85+
86+
# Default fallback to latest AS release config
87+
return "auth_config_25_10_2.json"
8188

8289

8390
class OidcUtils:
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"client_id": "36dea5b8-e8bb-423d-8e7b-c808df8f1c00",
3+
"redirect_uri": "http://localhost:__PY_REPLACE_PORT__/oidc/login",
4+
"scope": "offline_access ProcessMining OrchestratorApiUserAccess StudioWebBackend IdentityServerApi ConnectionService DataService DocumentUnderstanding Du.Digitization.Api Du.Classification.Api Du.Extraction.Api Du.Validation.Api EnterpriseContextService Directory JamJamApi LLMGateway LLMOps OMS RCS.FolderAuthorization TM.Projects TM.TestCases TM.Requirements TM.TestSets",
5+
"port": 8104
6+
}

packages/uipath/tests/cli/test_oidc_utils.py

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -121,32 +121,66 @@ def test_is_cloud_domain(self, domain, expected):
121121
assert _is_cloud_domain(domain) == expected
122122

123123
@pytest.mark.parametrize(
124-
"domain,mock_version,expected_config",
124+
"domain,mock_info,expected_config",
125125
[
126-
# Cloud domains should always use auth_config_cloud.json
126+
# Cloud domains always use auth_config_cloud.json (no API call needed)
127127
("https://alpha.uipath.com", None, "auth_config_cloud.json"),
128128
("https://staging.uipath.com", None, "auth_config_cloud.json"),
129129
("https://cloud.uipath.com", None, "auth_config_cloud.json"),
130-
# Version 25.10.* should use auth_config_25_10.json
130+
# Non-ServiceFabric deployments (cloud releases) use auth_config_cloud.json
131131
(
132132
"https://custom.domain.com",
133-
"25.10.0-beta.415",
134-
"auth_config_25_10.json",
133+
{"version": "26.3.0-s188.574", "deployment": None},
134+
"auth_config_cloud.json",
135+
),
136+
(
137+
"https://custom.domain.com",
138+
{"version": "25.10.0-s99", "deployment": "Kubernetes"},
139+
"auth_config_cloud.json",
135140
),
136-
("https://custom.domain.com", "25.10.1", "auth_config_25_10.json"),
137-
# Other versions should fallback to cloud config
138-
("https://custom.domain.com", "24.10.0", "auth_config_cloud.json"),
139-
("https://custom.domain.com", "26.1.0", "auth_config_cloud.json"),
140-
# Unable to determine version should fallback to cloud config
141+
# API unreachable uses auth_config_cloud.json
141142
("https://custom.domain.com", None, "auth_config_cloud.json"),
143+
# ServiceFabric + 25.10.* (AS release 25.10) uses auth_config_25_10.json
144+
(
145+
"https://custom.domain.com",
146+
{"version": "25.10.0-beta.415", "deployment": "ServiceFabric"},
147+
"auth_config_25_10.json",
148+
),
149+
(
150+
"https://custom.domain.com",
151+
{"version": "25.10.1", "deployment": "ServiceFabric"},
152+
"auth_config_25_10.json",
153+
),
154+
# ServiceFabric + 26.3.* (AS release 25.10.2) uses auth_config_25_10_2.json
155+
(
156+
"https://custom.domain.com",
157+
{"version": "26.3.0-beta.188", "deployment": "ServiceFabric"},
158+
"auth_config_25_10_2.json",
159+
),
160+
(
161+
"https://custom.domain.com",
162+
{"version": "26.3.1", "deployment": "ServiceFabric"},
163+
"auth_config_25_10_2.json",
164+
),
165+
# ServiceFabric + unknown version falls back to latest AS config
166+
(
167+
"https://custom.domain.com",
168+
{"version": "24.10.0", "deployment": "ServiceFabric"},
169+
"auth_config_25_10_2.json",
170+
),
171+
(
172+
"https://custom.domain.com",
173+
{"version": "26.1.0", "deployment": "ServiceFabric"},
174+
"auth_config_25_10_2.json",
175+
),
142176
],
143177
)
144-
async def test_select_config_file(self, domain, mock_version, expected_config):
145-
"""Test _select_config_file selects the correct config based on domain and version."""
178+
async def test_select_config_file(self, domain, mock_info, expected_config):
179+
"""Test _select_config_file selects the correct config based on domain and server info."""
146180
with patch(
147-
"uipath._cli._auth._oidc_utils.get_server_version_async",
181+
"uipath._cli._auth._oidc_utils.get_server_info_async",
148182
new_callable=AsyncMock,
149-
return_value=mock_version,
183+
return_value=mock_info,
150184
):
151185
config_file = await _select_config_file(domain)
152186
assert config_file == expected_config
@@ -170,12 +204,15 @@ async def test_get_auth_config_with_cloud_domain(self):
170204
assert config["port"] == 8104
171205

172206
async def test_get_auth_config_with_25_10_version(self):
173-
"""Test get_auth_config with version 25.10 uses auth_config_25_10.json."""
207+
"""Test get_auth_config with AS 25.10 ServiceFabric deployment uses auth_config_25_10.json."""
174208
with (
175209
patch(
176-
"uipath._cli._auth._oidc_utils.get_server_version_async",
210+
"uipath._cli._auth._oidc_utils.get_server_info_async",
177211
new_callable=AsyncMock,
178-
return_value="25.10.0-beta.415",
212+
return_value={
213+
"version": "25.10.0-beta.415",
214+
"deployment": "ServiceFabric",
215+
},
179216
),
180217
patch(
181218
"uipath._cli._auth._oidc_utils.OidcUtils._find_free_port",

packages/uipath/uv.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)