Skip to content

Commit 741f11c

Browse files
fix: pass job key to is activities for licensing
1 parent de3b91c commit 741f11c

6 files changed

Lines changed: 69 additions & 4 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.45"
3+
version = "0.1.46"
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/common/constants.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
HEADER_INTERNAL_TENANT_ID = "x-uipath-internal-tenantid"
3737
HEADER_INTERNAL_ACCOUNT_ID = "x-uipath-internal-accountid"
3838
HEADER_JOB_KEY = "x-uipath-jobkey"
39+
# Sent on outbound Integration Service activity invocations so GenAI activities
40+
# can be stitched back to the parent job for licensing attribution.
41+
HEADER_ACTIVITY_JOB_ID = "x-uipath-job-id"
3942
HEADER_PROCESS_KEY = "x-uipath-processkey"
4043
HEADER_TRACE_ID = "x-uipath-traceid"
4144
HEADER_AGENTHUB_CONFIG = "x-uipath-agenthub-config"

packages/uipath-platform/src/uipath/platform/connections/_connections_service.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22
import logging
3+
import os
34
from typing import Any, Dict, List, Optional
45
from urllib.parse import parse_qsl, quote, urlsplit
56

@@ -12,6 +13,7 @@
1213
from ..common._execution_context import UiPathExecutionContext
1314
from ..common._folder_context import header_folder
1415
from ..common._models import Endpoint, RequestSpec
16+
from ..common.constants import ENV_JOB_KEY, HEADER_ACTIVITY_JOB_ID
1517
from ..orchestrator._folder_service import FolderService
1618
from .connections import (
1719
ActivityMetadata,
@@ -773,6 +775,8 @@ def _build_activity_request_spec(
773775
**header_folder(folder_key, None),
774776
**header_params,
775777
}
778+
if job_key := os.getenv(ENV_JOB_KEY):
779+
headers[HEADER_ACTIVITY_JOB_ID] = job_key
776780

777781
# body and files handling
778782
json_data: Dict[str, Any] | None = None

packages/uipath-platform/tests/services/test_connections_service.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88

99
from uipath.platform import UiPathApiConfig, UiPathExecutionContext
1010
from uipath.platform.common import jsonschema_to_pydantic
11-
from uipath.platform.common.constants import HEADER_FOLDER_KEY, HEADER_USER_AGENT
11+
from uipath.platform.common.constants import (
12+
HEADER_ACTIVITY_JOB_ID,
13+
HEADER_FOLDER_KEY,
14+
HEADER_USER_AGENT,
15+
)
1216
from uipath.platform.connections import (
1317
ActivityMetadata,
1418
ActivityParameterLocationInfo,
@@ -1421,6 +1425,60 @@ def test_invoke_activity_sets_standard_headers(
14211425
assert sent_request.headers["x-uipath-originator"] == "uipath-python"
14221426
assert sent_request.headers["x-uipath-source"] == "uipath-python"
14231427

1428+
def test_invoke_activity_propagates_job_id_header(
1429+
self,
1430+
httpx_mock: HTTPXMock,
1431+
service: ConnectionsService,
1432+
simple_activity_metadata: ActivityMetadata,
1433+
monkeypatch: pytest.MonkeyPatch,
1434+
) -> None:
1435+
"""Activity invocations carry x-uipath-job-id so GenAI calls can be stitched for licensing."""
1436+
monkeypatch.setenv("UIPATH_JOB_KEY", "job-key-abc")
1437+
connection_id = "test-connection-123"
1438+
1439+
httpx_mock.add_response(
1440+
method="GET",
1441+
status_code=200,
1442+
json={"id": connection_id, "name": "Test", "elementInstanceId": 1},
1443+
)
1444+
httpx_mock.add_response(method="POST", status_code=200, json={})
1445+
1446+
service.invoke_activity(
1447+
activity_metadata=simple_activity_metadata,
1448+
connection_id=connection_id,
1449+
activity_input={"body_field1": "x"},
1450+
)
1451+
1452+
sent_request = httpx_mock.get_requests()[1]
1453+
assert sent_request.headers[HEADER_ACTIVITY_JOB_ID] == "job-key-abc"
1454+
1455+
def test_invoke_activity_omits_job_id_header_when_unset(
1456+
self,
1457+
httpx_mock: HTTPXMock,
1458+
service: ConnectionsService,
1459+
simple_activity_metadata: ActivityMetadata,
1460+
monkeypatch: pytest.MonkeyPatch,
1461+
) -> None:
1462+
"""No job-id header is sent when UIPATH_JOB_KEY is not set."""
1463+
monkeypatch.delenv("UIPATH_JOB_KEY", raising=False)
1464+
connection_id = "test-connection-123"
1465+
1466+
httpx_mock.add_response(
1467+
method="GET",
1468+
status_code=200,
1469+
json={"id": connection_id, "name": "Test", "elementInstanceId": 1},
1470+
)
1471+
httpx_mock.add_response(method="POST", status_code=200, json={})
1472+
1473+
service.invoke_activity(
1474+
activity_metadata=simple_activity_metadata,
1475+
connection_id=connection_id,
1476+
activity_input={"body_field1": "x"},
1477+
)
1478+
1479+
sent_request = httpx_mock.get_requests()[1]
1480+
assert HEADER_ACTIVITY_JOB_ID not in sent_request.headers
1481+
14241482
def test_invoke_activity_with_body_fields(
14251483
self,
14261484
httpx_mock: HTTPXMock,

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/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.

0 commit comments

Comments
 (0)