Skip to content

Commit 29dfd0e

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

5 files changed

Lines changed: 73 additions & 7 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/connections/_connections_service.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from ..common._base_service import BaseService
1010
from ..common._bindings import resource_override
11-
from ..common._config import UiPathApiConfig
11+
from ..common._config import UiPathApiConfig, UiPathConfig
1212
from ..common._execution_context import UiPathExecutionContext
1313
from ..common._folder_context import header_folder
1414
from ..common._models import Endpoint, RequestSpec
@@ -24,6 +24,13 @@
2424

2525
logger: logging.Logger = logging.getLogger("uipath")
2626

27+
HEADER_ORIGINATOR = "x-uipath-originator"
28+
HEADER_SOURCE = "x-uipath-source"
29+
# Sent on outbound Integration Service activity invocations so GenAI activities
30+
# can be stitched back to the parent job for licensing attribution.
31+
HEADER_ACTIVITY_JOB_ID = "x-uipath-job-id"
32+
_ORIGINATOR_VALUE = "uipath-python"
33+
2734

2835
class ConnectionsService(BaseService):
2936
"""Service for managing UiPath external service connections.
@@ -768,11 +775,13 @@ def _build_activity_request_spec(
768775

769776
# header parameter handling
770777
headers = {
771-
"x-uipath-originator": "uipath-python",
772-
"x-uipath-source": "uipath-python",
778+
HEADER_ORIGINATOR: _ORIGINATOR_VALUE,
779+
HEADER_SOURCE: _ORIGINATOR_VALUE,
773780
**header_folder(folder_key, None),
774781
**header_params,
775782
}
783+
if job_key := UiPathConfig.job_key:
784+
headers[HEADER_ACTIVITY_JOB_ID] = job_key
776785

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

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

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
ConnectionToken,
1818
EventArguments,
1919
)
20-
from uipath.platform.connections._connections_service import ConnectionsService
20+
from uipath.platform.connections._connections_service import (
21+
HEADER_ACTIVITY_JOB_ID,
22+
ConnectionsService,
23+
)
2124
from uipath.platform.orchestrator._folder_service import FolderService
2225

2326

@@ -1421,6 +1424,60 @@ def test_invoke_activity_sets_standard_headers(
14211424
assert sent_request.headers["x-uipath-originator"] == "uipath-python"
14221425
assert sent_request.headers["x-uipath-source"] == "uipath-python"
14231426

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