Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/uipath/_cli/_auth/_oidc_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import httpx

from ..._utils._ssl_context import get_httpx_client_kwargs
from ..._utils._http_clients import get_httpx_client_kwargs
from .._utils._console import ConsoleLogger
from ._models import AuthConfig
from ._url_utils import build_service_url
Expand Down
2 changes: 1 addition & 1 deletion src/uipath/_cli/_auth/_portal_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
)

from ..._utils._auth import update_env_file
from ..._utils._ssl_context import get_httpx_client_kwargs
from ..._utils._http_clients import get_httpx_client_kwargs
from ...platform.common import TokenData
from .._utils._console import ConsoleLogger
from ._models import OrganizationInfo, TenantInfo, TenantsAndOrganizationInfoResponse
Expand Down
2 changes: 1 addition & 1 deletion src/uipath/_cli/_utils/_processes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import httpx

from ..._utils._ssl_context import get_httpx_client_kwargs
from ..._utils._http_clients import get_httpx_client_kwargs
from ._console import ConsoleLogger

console = ConsoleLogger()
Expand Down
2 changes: 1 addition & 1 deletion src/uipath/_cli/cli_invoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import click
import httpx

from .._utils._ssl_context import get_httpx_client_kwargs
from .._utils._http_clients import get_httpx_client_kwargs
from ._utils._common import get_env_vars
from ._utils._console import ConsoleLogger
from ._utils._folders import get_personal_workspace_info_async
Expand Down
2 changes: 1 addition & 1 deletion src/uipath/_cli/cli_publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import click
import httpx

from .._utils._ssl_context import get_httpx_client_kwargs
from .._utils._http_clients import get_httpx_client_kwargs
from ._utils._common import get_env_vars
from ._utils._console import ConsoleLogger
from ._utils._folders import get_personal_workspace_info_async
Expand Down
21 changes: 0 additions & 21 deletions src/uipath/_utils/_ssl_context.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import os
import ssl
from typing import Any, Dict


def expand_path(path):
Expand Down Expand Up @@ -32,23 +31,3 @@ def create_ssl_context():
cafile=ssl_cert_file or requests_ca_bundle or certifi.where(),
capath=ssl_cert_dir,
)


def get_httpx_client_kwargs() -> Dict[str, Any]:
"""Get standardized httpx client configuration."""
client_kwargs: Dict[str, Any] = {"follow_redirects": True, "timeout": 30.0}

# Check environment variable to disable SSL verification
disable_ssl_env = os.environ.get("UIPATH_DISABLE_SSL_VERIFY", "").lower()
disable_ssl_from_env = disable_ssl_env in ("1", "true", "yes", "on")

if disable_ssl_from_env:
client_kwargs["verify"] = False
else:
# Use system certificates with truststore fallback
client_kwargs["verify"] = create_ssl_context()

# Auto-detect proxy from environment variables (httpx handles this automatically)
# HTTP_PROXY, HTTPS_PROXY, NO_PROXY are read by httpx by default

return client_kwargs
30 changes: 30 additions & 0 deletions src/uipath/_utils/_url.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from typing import Literal
from urllib.parse import urlparse

from ._service_url_overrides import get_service_override


class UiPathUrl:
"""A class that represents a UiPath URL.
Expand Down Expand Up @@ -61,13 +63,41 @@ def scope_url(self, url: str, scoped: Literal["org", "tenant"] = "tenant") -> st
if not self._is_relative_url(url):
return url

# Check for service-specific URL override
override_url = self._resolve_service_override(url)
if override_url is not None:
return override_url

parts = [self.org_name]
if scoped == "tenant":
parts.append(self.tenant_name)
parts.append(url.strip("/"))

return "/".join(parts)

def _resolve_service_override(self, url: str) -> str | None:
"""Return an absolute URL if a service override is configured for *url*.

Extracts the first path segment. If it ends with ``_`` (the UiPath
service-prefix convention), look up an override. When found, strip the
prefix and return an absolute URL pointing at the override host.
"""
stripped = url.strip("/")
if not stripped:
return None

first_segment, _, rest = stripped.partition("/")
if not first_segment.endswith("_"):
return None

override_base = get_service_override(first_segment)
if override_base is None:
return None

if rest:
return f"{override_base}/{rest}"
return override_base

@property
def _org_tenant_names(self):
parsed = urlparse(self._url)
Expand Down
2 changes: 2 additions & 0 deletions src/uipath/_utils/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
ENV_UIPATH_PROCESS_UUID = "UIPATH_PROCESS_UUID"
ENV_UIPATH_TRACE_ID = "UIPATH_TRACE_ID"
ENV_UIPATH_PROCESS_VERSION = "UIPATH_PROCESS_VERSION"
ENV_LICENSE_TRANSACTION_ID = "LICENSE_TRANSACTION_ID"

# Headers
HEADER_FOLDER_KEY = "x-uipath-folderkey"
Expand All @@ -28,6 +29,7 @@
HEADER_INTERNAL_TENANT_ID = "x-uipath-internal-tenantid"
HEADER_JOB_KEY = "x-uipath-jobkey"
HEADER_SW_LOCK_KEY = "x-uipath-sw-lockkey"
HEADER_LICENSING_TRANSACTION_ID = "X-UiPath-Licensing-TransactionId"

# Data sources (request types)
ORCHESTRATOR_STORAGE_BUCKET_DATA_SOURCE_REQUEST = (
Expand Down
9 changes: 7 additions & 2 deletions src/uipath/platform/common/_base_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
)

from ..._utils import UiPathUrl, user_agent_value
from ..._utils._ssl_context import get_httpx_client_kwargs
from ..._utils._http_clients import get_httpx_client_kwargs
from ..._utils.constants import HEADER_USER_AGENT
from ..errors import EnrichedException
from ._config import UiPathApiConfig
Expand All @@ -46,11 +46,12 @@ def __init__(
self._url = UiPathUrl(self._config.base_url)

default_client_kwargs = get_httpx_client_kwargs()
base_headers = default_client_kwargs.pop("headers", {})

client_kwargs = {
**default_client_kwargs, # SSL, proxy, timeout, redirects
"base_url": self._url.base_url,
"headers": Headers(self.default_headers),
"headers": Headers({**base_headers, **self.default_headers}),
}

self._client = Client(**client_kwargs)
Expand Down Expand Up @@ -103,6 +104,8 @@ def request(
kwargs["headers"][HEADER_USER_AGENT] = user_agent_value(specific_component)

scoped_url = self._url.scope_url(str(url), scoped)
if scoped_url.startswith(("http://", "https://")):
self._logger.debug(f"Service URL override active: {scoped_url}")

response = self._client.request(method, scoped_url, **kwargs)

Expand Down Expand Up @@ -140,6 +143,8 @@ async def request_async(
)

scoped_url = self._url.scope_url(str(url), scoped)
if scoped_url.startswith(("http://", "https://")):
self._logger.debug(f"Service URL override active: {scoped_url}")

response = await self._client_async.request(method, scoped_url, **kwargs)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import httpx
from httpx import HTTPStatusError, Request

from ..._utils._ssl_context import get_httpx_client_kwargs
from ..._utils._http_clients import get_httpx_client_kwargs
from ..._utils.constants import ENV_BASE_URL
from ..errors import EnrichedException
from .auth import TokenData
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from pydantic import Field, TypeAdapter

from ..._utils import Endpoint, RequestSpec, header_folder, resource_override
from ..._utils._ssl_context import get_httpx_client_kwargs
from ..._utils._http_clients import get_httpx_client_kwargs
from ..._utils.constants import (
LLMV4_REQUEST,
ORCHESTRATOR_STORAGE_BUCKET_DATA_SOURCE,
Expand Down
2 changes: 1 addition & 1 deletion src/uipath/platform/orchestrator/_attachments_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from httpx._types import RequestContent

from ..._utils import Endpoint, RequestSpec, header_folder
from ..._utils._ssl_context import get_httpx_client_kwargs
from ..._utils._http_clients import get_httpx_client_kwargs
from ..._utils.constants import TEMP_ATTACHMENTS_FOLDER
from ...tracing import traced
from ..attachments import Attachment, AttachmentMode, BlobFileAccessInfo
Expand Down
2 changes: 1 addition & 1 deletion src/uipath/platform/orchestrator/_buckets_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import httpx

from ..._utils import Endpoint, RequestSpec, header_folder, resource_override
from ..._utils._ssl_context import get_httpx_client_kwargs
from ..._utils._http_clients import get_httpx_client_kwargs
from ..._utils.validation import validate_pagination_params
from ...tracing import traced
from ..common import BaseService, FolderContext, UiPathApiConfig, UiPathExecutionContext
Expand Down
8 changes: 5 additions & 3 deletions src/uipath/tracing/_otel_exporters.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
SpanExportResult,
)

from uipath._utils._ssl_context import get_httpx_client_kwargs
from uipath._utils._http_clients import get_httpx_client_kwargs

from ._utils import _SpanUtils

Expand Down Expand Up @@ -117,13 +117,15 @@ def __init__(
super().__init__()
self.base_url = self._get_base_url()
self.auth_token = os.environ.get("UIPATH_ACCESS_TOKEN")
client_kwargs = get_httpx_client_kwargs()
base_headers = client_kwargs.pop("headers", {})

self.headers = {
**base_headers,
"Content-Type": "application/json",
"Authorization": f"Bearer {self.auth_token}",
}

client_kwargs = get_httpx_client_kwargs()

self.http_client = httpx.Client(**client_kwargs, headers=self.headers)
self.trace_id = trace_id

Expand Down
2 changes: 1 addition & 1 deletion src/uipath/utils/_endpoints_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import httpx

from uipath._utils._ssl_context import get_httpx_client_kwargs
from uipath._utils._http_clients import get_httpx_client_kwargs

loggger = logging.getLogger(__name__)

Expand Down
Loading