Skip to content

Commit 44221fb

Browse files
committed
WIP: add debug functionality
1 parent 55de34c commit 44221fb

4 files changed

Lines changed: 35 additions & 32 deletions

File tree

pyproject.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "uipath"
3-
version = "2.0.73"
3+
version = "3.0.0"
44
description = "Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools."
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.10"
@@ -66,8 +66,7 @@ dev = [
6666
"types-toml>=0.10.8",
6767
]
6868

69-
[project.optional-dependencies]
70-
langchain = ["uipath-langchain>=0.0.88,<0.1.0"]
69+
# TODO: add the uipath-langchain and uipath-llamaindex optional dependencies here
7170

7271
[tool.hatch.build.targets.wheel]
7372
packages = ["src/uipath"]

src/uipath/_cli/_runtime/_contracts.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,13 @@ class UiPathRuntimeContext(BaseModel):
148148
trace_context: Optional[UiPathTraceContext] = None
149149
tracing_enabled: Union[bool, str] = False
150150
resume: bool = False
151+
debug: bool = False
151152
config_path: str = "uipath.json"
152153
runtime_dir: Optional[str] = "__uipath"
153154
logs_file: Optional[str] = "execution.log"
154155
logs_min_level: Optional[str] = "INFO"
155156
output_file: str = "output.json"
157+
execution_output_file: str = "execution_output.json"
156158
state_file: str = "state.db"
157159
result: Optional[UiPathRuntimeResult] = None
158160

@@ -187,6 +189,7 @@ def from_config(cls, config_path=None):
187189
mapping = {
188190
"dir": "runtime_dir",
189191
"outputFile": "output_file",
192+
"executionOutputFile": "execution_output_file",
190193
"stateFile": "state_file",
191194
"logsFile": "logs_file",
192195
}
@@ -365,11 +368,14 @@ async def __aexit__(self, exc_type, exc_val, exc_tb):
365368
content = execution_result.to_dict()
366369
logger.debug(content)
367370

368-
# Always write output file at runtime
371+
# Always write output and execution_output files at runtime
369372
if self.context.job_id:
370373
with open(self.output_file_path, "w") as f:
371374
json.dump(content, f, indent=2, default=str)
372375

376+
with open(self.execution_output_file_path, "w") as f:
377+
json.dump(execution_result.output or "", f, indent=2, default=str)
378+
373379
# Don't suppress exceptions
374380
return False
375381

@@ -424,6 +430,13 @@ def output_file_path(self) -> str:
424430
return os.path.join(self.context.runtime_dir, self.context.output_file)
425431
return os.path.join("__uipath", "output.json")
426432

433+
@cached_property
434+
def execution_output_file_path(self) -> str:
435+
if self.context.runtime_dir and self.context.execution_output_file:
436+
os.makedirs(self.context.runtime_dir, exist_ok=True)
437+
return os.path.join(self.context.runtime_dir, self.context.execution_output_file)
438+
return os.path.join("__uipath", "execution_output.json")
439+
427440
@cached_property
428441
def state_file_path(self) -> str:
429442
if self.context.runtime_dir and self.context.state_file:

src/uipath/_cli/cli_run.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from typing import Optional
77
from uuid import uuid4
88

9+
from ._utils._common import serialize_object
910
import click
1011
from dotenv import load_dotenv
1112

@@ -32,6 +33,7 @@ def python_run_middleware(
3233
entrypoint: Optional[str],
3334
input: Optional[str],
3435
resume: bool,
36+
**kwargs,
3537
) -> MiddlewareResult:
3638
"""Middleware to handle Python script execution.
3739
@@ -85,12 +87,12 @@ async def execute():
8587
)
8688
context.logs_min_level = env.get("LOG_LEVEL", "INFO")
8789
async with UiPathRuntime.from_context(context) as runtime:
88-
await runtime.execute()
90+
return await runtime.execute()
8991

90-
asyncio.run(execute())
92+
result = asyncio.run(execute())
9193

9294
# Return success
93-
return MiddlewareResult(should_continue=False)
95+
return MiddlewareResult(should_continue=False, output=serialize_object(result))
9496

9597
except UiPathRuntimeError as e:
9698
return MiddlewareResult(
@@ -118,6 +120,13 @@ async def execute():
118120
type=click.Path(exists=True),
119121
help="File path for the .json input",
120122
)
123+
@click.option(
124+
"-o",
125+
"--output-file",
126+
required=False,
127+
type=click.Path(exists=False),
128+
help="File path where the output will be written",
129+
)
121130
@click.option(
122131
"--debug",
123132
is_flag=True,
@@ -135,6 +144,7 @@ def run(
135144
input: Optional[str],
136145
resume: bool,
137146
file: Optional[str],
147+
output_file: Optional[str],
138148
debug: bool,
139149
debug_port: int,
140150
) -> None:
@@ -151,14 +161,17 @@ def run(
151161
console.error(f"Failed to start debug server on port {debug_port}")
152162

153163
# Process through middleware chain
154-
result = Middlewares.next("run", entrypoint, input, resume)
164+
result = Middlewares.next("run", entrypoint, input, resume, debug=debug, debug_port=debug_port)
155165

156166
if result.should_continue:
157167
result = python_run_middleware(
158168
entrypoint=entrypoint,
159169
input=input,
160170
resume=resume,
161171
)
172+
if output_file:
173+
with open(output_file, "w") as f:
174+
f.write(str(result.output))
162175

163176
# Handle result from middleware
164177
if result.error_message:

src/uipath/_cli/middlewares.py

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class MiddlewareResult:
1616
info_message: Optional[str] = None
1717
error_message: Optional[str] = None
1818
should_include_stacktrace: bool = False
19-
19+
output: Optional[str] = None
2020

2121
MiddlewareFunc = Callable[..., MiddlewareResult]
2222

@@ -54,30 +54,8 @@ def next(cls, command: str, *args: Any, **kwargs: Any) -> MiddlewareResult:
5454

5555
middlewares = cls.get(command)
5656
for middleware in middlewares:
57-
sig = inspect.signature(middleware)
58-
59-
# handle older versions of plugins that don't support the new signature
60-
try:
61-
bound = sig.bind(*args, **kwargs)
62-
new_args = bound.args
63-
new_kwargs = bound.kwargs
64-
except TypeError:
65-
console.warning("Install the latest version for uipath packages")
66-
accepted_args = [
67-
name
68-
for name, param in sig.parameters.items()
69-
if param.kind
70-
in (param.POSITIONAL_ONLY, param.POSITIONAL_OR_KEYWORD)
71-
]
72-
73-
trimmed_args = args[: len(accepted_args)]
74-
trimmed_kwargs = {k: v for k, v in kwargs.items() if k in accepted_args}
75-
76-
new_args = trimmed_args
77-
new_kwargs = trimmed_kwargs
78-
7957
try:
80-
result = middleware(*new_args, **new_kwargs)
58+
result = middleware(*args, **kwargs)
8159
if not result.should_continue:
8260
logger.debug(
8361
f"Command '{command}' stopped by {middleware.__name__}"

0 commit comments

Comments
 (0)