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 pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "uipath"
version = "2.2.8"
version = "2.2.9"
description = "Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools."
readme = { file = "README.md", content-type = "text/markdown" }
requires-python = ">=3.11"
Expand Down
177 changes: 155 additions & 22 deletions src/uipath/_services/tasks_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ def _create_spec(
app_key: Optional[str] = None,
app_folder_key: Optional[str] = None,
app_folder_path: Optional[str] = None,
app_version: Optional[int] = None,
priority: Optional[str] = None,
labels: Optional[List[str]] = None,
is_actionable_message_enabled: Optional[bool] = None,
actionable_message_metadata: Optional[Dict[str, Any]] = None,
agent_id: Optional[str] = None,
instance_id: Optional[str] = None,
job_key: Optional[str] = None,
process_key: Optional[str] = None,
resource_key: Optional[str] = None,
) -> RequestSpec:
field_list = []
outcome_list = []
Expand Down Expand Up @@ -76,30 +86,89 @@ def _create_spec(
}
)

return RequestSpec(
method="POST",
endpoint=Endpoint("/orchestrator_/tasks/AppTasks/CreateAppTask"),
json={
"appId": app_key,
"title": title,
"data": data if data is not None else {},
"actionableMessageMetaData": {
"fieldSet": {
"id": str(uuid.uuid4()),
"fields": field_list,
}
if len(field_list) != 0
else {},
"actionSet": {
"id": str(uuid.uuid4()),
"actions": outcome_list,
# Build tags array from labels
tags = []
if labels:
for label in labels:
tags.append(
{
"Name": label,
"DisplayName": label,
"Value": label,
"DisplayValue": label,
}
if len(outcome_list) != 0
else {},
)

# Build additional properties
additional_properties: Dict[str, Any] = {}
if resource_key:
additional_properties["AppType"] = "Dynamic"
additional_properties["FolderKey"] = app_folder_key or ""

# Build task source metadata
task_source_metadata: Dict[str, Any] = {}
if instance_id:
task_source_metadata["InstanceId"] = instance_id
if app_folder_key:
task_source_metadata["FolderKey"] = app_folder_key
if job_key:
task_source_metadata["JobKey"] = job_key
if process_key:
task_source_metadata["ProcessKey"] = process_key

# Build task source
task_source: Optional[Dict[str, Any]] = None
if agent_id:
task_source = {
"SourceName": "Agent",
"SourceId": agent_id,
"TaskSourceMetadata": task_source_metadata,
}

# Build base payload matching .NET structure
payload: Dict[str, Any] = {
"appId": app_key,
"title": title,
"data": data if data is not None else {},
}

# Add optional fields
if app_version is not None:
payload["appVersion"] = app_version
if priority is not None:
payload["priority"] = priority
if tags:
payload["tags"] = tags
if is_actionable_message_enabled is not None:
payload["isActionableMessageEnabled"] = is_actionable_message_enabled
if additional_properties:
payload["additionalProperties"] = additional_properties
if task_source:
payload["taskSource"] = task_source

# Add actionable message metadata (legacy format for backward compatibility)
if actionable_message_metadata:
payload["actionableMessageMetaData"] = actionable_message_metadata
elif action_schema is not None:
payload["actionableMessageMetaData"] = {
"fieldSet": {
"id": str(uuid.uuid4()),
"fields": field_list,
}
if action_schema is not None
if len(field_list) != 0
else {},
},
"actionSet": {
"id": str(uuid.uuid4()),
"actions": outcome_list,
}
if len(outcome_list) != 0
else {},
}

return RequestSpec(
method="POST",
endpoint=Endpoint("/orchestrator_/tasks/AppTasks/CreateAppTask"),
json=payload,
headers=folder_headers(app_folder_key, app_folder_path),
)

Expand Down Expand Up @@ -132,7 +201,11 @@ def _retrieve_app_key_spec(app_name: str) -> RequestSpec:
return RequestSpec(
method="GET",
endpoint=Endpoint("/apps_/default/api/v1/default/deployed-action-apps-schemas"),
params={"search": app_name},
params={
"search": app_name,
"filterByDeploymentTitle": "true",
"state": "deployed",
},
headers={HEADER_TENANT_ID: tenant_id},
)

Expand Down Expand Up @@ -181,6 +254,16 @@ async def create_async(
app_folder_path: Optional[str] = None,
app_folder_key: Optional[str] = None,
assignee: Optional[str] = None,
app_version: Optional[int] = None,
priority: Optional[str] = None,
labels: Optional[List[str]] = None,
is_actionable_message_enabled: Optional[bool] = None,
actionable_message_metadata: Optional[Dict[str, Any]] = None,
agent_id: Optional[str] = None,
instance_id: Optional[str] = None,
job_key: Optional[str] = None,
process_key: Optional[str] = None,
resource_key: Optional[str] = None,
) -> Task:
"""Creates a new action asynchronously.

Expand All @@ -195,6 +278,16 @@ async def create_async(
app_folder_path: Optional folder path for the action
app_folder_key: Optional folder key for the action
assignee: Optional username or email to assign the task to
app_version: Optional application version
priority: Optional task priority (Low, Medium, High, Critical)
labels: Optional list of tag labels for the task
is_actionable_message_enabled: Optional flag for actionable message feature
actionable_message_metadata: Optional metadata for actionable messages
agent_id: Optional agent identifier for task source
instance_id: Optional instance/trace identifier
job_key: Optional job key for task source metadata
process_key: Optional process key for task source metadata
resource_key: Optional resource key for additional properties

Returns:
Action: The created action object
Expand All @@ -216,6 +309,16 @@ async def create_async(
action_schema=action_schema,
app_folder_key=app_folder_key,
app_folder_path=app_folder_path,
app_version=app_version,
priority=priority,
labels=labels,
is_actionable_message_enabled=is_actionable_message_enabled,
actionable_message_metadata=actionable_message_metadata,
agent_id=agent_id,
instance_id=instance_id,
job_key=job_key,
process_key=process_key,
resource_key=resource_key,
)

response = await self.request_async(
Expand Down Expand Up @@ -249,6 +352,16 @@ def create(
app_folder_path: Optional[str] = None,
app_folder_key: Optional[str] = None,
assignee: Optional[str] = None,
app_version: Optional[int] = None,
priority: Optional[str] = None,
labels: Optional[List[str]] = None,
is_actionable_message_enabled: Optional[bool] = None,
actionable_message_metadata: Optional[Dict[str, Any]] = None,
agent_id: Optional[str] = None,
instance_id: Optional[str] = None,
job_key: Optional[str] = None,
process_key: Optional[str] = None,
resource_key: Optional[str] = None,
) -> Task:
"""Creates a new task synchronously.

Expand All @@ -263,6 +376,16 @@ def create(
app_folder_path: Optional folder path for the action
app_folder_key: Optional folder key for the action
assignee: Optional username or email to assign the task to
app_version: Optional application version
priority: Optional task priority (Low, Medium, High, Critical)
labels: Optional list of tag labels for the task
is_actionable_message_enabled: Optional flag for actionable message feature
actionable_message_metadata: Optional metadata for actionable messages
agent_id: Optional agent identifier for task source
instance_id: Optional instance/trace identifier
job_key: Optional job key for task source metadata
process_key: Optional process key for task source metadata
resource_key: Optional resource key for additional properties

Returns:
Action: The created action object
Expand All @@ -284,6 +407,16 @@ def create(
action_schema=action_schema,
app_folder_key=app_folder_key,
app_folder_path=app_folder_path,
app_version=app_version,
priority=priority,
labels=labels,
is_actionable_message_enabled=is_actionable_message_enabled,
actionable_message_metadata=actionable_message_metadata,
agent_id=agent_id,
instance_id=instance_id,
job_key=job_key,
process_key=process_key,
resource_key=resource_key,
)

response = self.request(
Expand Down
44 changes: 44 additions & 0 deletions src/uipath/_utils/_bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,47 @@ def get_inferred_bindings_names(cls: T):
inferred_bindings[name] = method._infer_bindings_mappings # type: ignore # probably a better way to do this

return inferred_bindings


def resolve_folder_from_bindings(
resource_type: str,
resource_name: Optional[str],
folder_path: Optional[str] = None,
) -> tuple[Optional[str], Optional[str]]:
"""Resolve folder path and key from bindings context.

This function looks up the bindings context variable to find the folder
information for a given resource. It's used to ensure that resume triggers
are created with the correct folder information from bindings.

Args:
resource_type: The type of resource (e.g., "app", "process", "index")
resource_name: The name/identifier of the resource
folder_path: Optional current folder path for more specific matching

Returns:
Tuple of (folder_path, folder_key) from bindings. Returns (None, None)
if no bindings context is available or no matching resource is found.
"""
if not resource_name:
return (None, None)

context_overwrites = _resource_overwrites.get()
if context_overwrites is None:
return (None, None)

key = f"{resource_type}.{resource_name}"

if folder_path:
specific_key = f"{key}.{folder_path}"
if specific_key in context_overwrites:
key = specific_key

matched = context_overwrites.get(key)
if matched is None:
return (None, None)

if isinstance(matched, ConnectionResourceOverwrite):
return (None, matched.folder_identifier)

return (matched.folder_identifier, None)
15 changes: 12 additions & 3 deletions src/uipath/platform/common/interrupt_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,18 @@ class CreateTask(BaseModel):


class CreateEscalation(CreateTask):
"""Model representing an escalation creation."""

pass
"""Model representing an escalation creation with additional metadata."""

app_version: Optional[int] = None
priority: Optional[str] = None
labels: Optional[list[str]] = None
is_actionable_message_enabled: Optional[bool] = None
actionable_message_metadata: Optional[Dict[str, Any]] = None
agent_id: Optional[str] = None
instance_id: Optional[str] = None
job_key: Optional[str] = None
process_key: Optional[str] = None
resource_key: Optional[str] = None


class WaitTask(BaseModel):
Expand Down
Loading
Loading