11import json
22import os
33import uuid
4- from typing import Any , Dict , Optional
4+ from typing import Any , Dict , Optional , Union
5+
6+ from opentelemetry import trace
7+ from opentelemetry .trace import format_span_id
58
69from ..._utils import Endpoint , RequestSpec , header_folder , resource_override
710from ..._utils .constants import ENV_JOB_KEY , HEADER_JOB_KEY
811from ...tracing import traced
12+ from ...tracing ._utils import _SpanUtils
913from ..attachments import Attachment
10- from ..common import BaseService , FolderContext , UiPathApiConfig , UiPathExecutionContext
14+ from ..common import (
15+ BaseService ,
16+ FolderContext ,
17+ UiPathApiConfig ,
18+ UiPathConfig ,
19+ UiPathExecutionContext ,
20+ )
1121from ._attachments_service import AttachmentsService
1222from .job import Job
1323
@@ -41,6 +51,7 @@ def invoke(
4151 folder_key : Optional [str ] = None ,
4252 folder_path : Optional [str ] = None ,
4353 attachments : Optional [list [Attachment ]] = None ,
54+ ** kwargs : Any ,
4455 ) -> Job :
4556 """Start execution of a process by its name.
4657
@@ -87,6 +98,7 @@ def invoke(
8798 input_data = input_data ,
8899 folder_key = folder_key ,
89100 folder_path = folder_path ,
101+ parent_span_id = kwargs .get ("parent_span_id" ),
90102 )
91103 response = self .request (
92104 spec .method ,
@@ -109,6 +121,7 @@ async def invoke_async(
109121 folder_key : Optional [str ] = None ,
110122 folder_path : Optional [str ] = None ,
111123 attachments : Optional [list [Attachment ]] = None ,
124+ ** kwargs : Any ,
112125 ) -> Job :
113126 """Asynchronously start execution of a process by its name.
114127
@@ -150,6 +163,7 @@ async def main():
150163 input_data = input_data ,
151164 folder_key = folder_key ,
152165 folder_path = folder_path ,
166+ parent_span_id = kwargs .get ("parent_span_id" ),
153167 )
154168
155169 response = await self .request_async (
@@ -266,20 +280,44 @@ async def _handle_input_arguments_async(
266280
267281 return result
268282
283+ @staticmethod
284+ def _add_tracing (
285+ payload : Dict [str , Any ],
286+ trace_id : Optional [str ] = None ,
287+ parent_span_id : Optional [Union [str , int ]] = None ,
288+ ) -> None :
289+ """Enrich payload with trace context for cross-process correlation."""
290+ if not trace_id :
291+ return
292+
293+ payload ["TraceId" ] = _SpanUtils .normalize_trace_id (trace_id )
294+ if not parent_span_id :
295+ span_context = trace .get_current_span ().get_span_context ()
296+ if span_context .span_id :
297+ parent_span_id = format_span_id (span_context .span_id )
298+ if parent_span_id :
299+ if isinstance (parent_span_id , int ):
300+ parent_span_id = format_span_id (parent_span_id )
301+ payload ["ParentSpanId" ] = _SpanUtils .normalize_span_id (parent_span_id )
302+
269303 def _invoke_spec (
270304 self ,
271305 name : str ,
272306 input_data : Optional [Dict [str , Any ]] = None ,
273307 * ,
274308 folder_key : Optional [str ] = None ,
275309 folder_path : Optional [str ] = None ,
310+ parent_span_id : Optional [str ] = None ,
276311 ) -> RequestSpec :
312+ payload : Dict [str , Any ] = {"ReleaseName" : name , ** (input_data or {})}
313+ self ._add_tracing (payload , UiPathConfig .trace_id , parent_span_id )
314+
277315 request_spec = RequestSpec (
278316 method = "POST" ,
279317 endpoint = Endpoint (
280318 "/orchestrator_/odata/Jobs/UiPath.Server.Configuration.OData.StartJobs"
281319 ),
282- json = {"startInfo" : { "ReleaseName" : name , ** ( input_data or {})} },
320+ json = {"startInfo" : payload },
283321 headers = {
284322 ** header_folder (folder_key , folder_path ),
285323 },
0 commit comments