Skip to content
Merged
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 .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: continuous-integration

on: [push]
on: [push, pull_request]

jobs:
test:
Expand Down
56 changes: 41 additions & 15 deletions src/workflow/CommandExecutor.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,15 @@ def run_topp(self, tool: str, input_output: dict, custom_params: dict = {}, tool

# Load merged parameters (_defaults + user overrides) for this tool instance
merged_params = self.parameter_manager.get_merged_params(params_key)

# Load flag parameter names: params.json takes priority (survives session restart),
# session_state is the live fallback during the current session.
flag_map = self.parameter_manager.get_parameters_from_json().get("_flag_params", {})
flag_list = flag_map.get(params_key)
if flag_list is None:
flag_list = st.session_state.get("_topp_flag_params", {}).get(params_key, [])
flag_params: set = set(flag_list)

Comment thread
coderabbitai[bot] marked this conversation as resolved.
# Construct commands for each process
for i in range(n_processes):
command = [tool]
Expand All @@ -288,25 +297,42 @@ def run_topp(self, tool: str, input_output: dict, custom_params: dict = {}, tool
command += [value[i]]
# Add merged TOPP tool parameters (_defaults + user overrides)
for k, v in merged_params.items():
command += [f"-{k}"]
# Skip only empty strings (pass flag with no value)
# Note: 0 and 0.0 are valid values, so use explicit check
if v != "" and v is not None:
if isinstance(v, str) and "\n" in v:
command += v.split("\n")
if k in flag_params:
# CLI flag: include "-k" only when truthy, omit when false
if isinstance(v, str):
is_enabled = v.lower() == "true"
else:
command += [str(v)]
is_enabled = bool(v)
if is_enabled:
command += [f"-{k}"]
continue
# Regular parameter: skip empty/None/empty-list, append value otherwise
if v == "" or v is None or (isinstance(v, list) and not v):
continue
command += [f"-{k}"]
if isinstance(v, str) and "\n" in v:
command += v.split("\n")
elif isinstance(v, list):
command += [str(x) for x in v]
else:
command += [str(v)]
# Add custom parameters
for k, v in custom_params.items():
command += [f"-{k}"]

# Skip only empty strings (pass flag with no value)
# Note: 0 and 0.0 are valid values, so use explicit check
if v != "" and v is not None:
if isinstance(v, list):
command += [str(x) for x in v]
if k in flag_params:
if isinstance(v, str):
is_enabled = v.lower() == "true"
else:
command += [str(v)]
is_enabled = bool(v)
if is_enabled:
command += [f"-{k}"]
continue
if v == "" or v is None or (isinstance(v, list) and not v):
continue
command += [f"-{k}"]
if isinstance(v, list):
command += [str(x) for x in v]
else:
command += [str(v)]
# Add threads parameter for TOPP tools
command += ["-threads", str(threads_per_command)]
commands.append(command)
Expand Down
13 changes: 13 additions & 0 deletions src/workflow/StreamlitUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,7 @@ def input_TOPP(
num_cols: int = 4,
exclude_parameters: List[str] = [],
include_parameters: List[str] = [],
flag_parameters: List[str] = [],
display_tool_name: bool = True,
display_subsections: bool = True,
display_subsection_tabs: bool = False,
Expand Down Expand Up @@ -862,6 +863,18 @@ def input_TOPP(
st.session_state["_topp_tool_instance_map"] = {}
st.session_state["_topp_tool_instance_map"][tool_instance_name] = topp_tool_name

# Persist flag_parameters to session_state and params.json so run_topp
# can skip appending a value for these boolean CLI flags.
if "_topp_flag_params" not in st.session_state:
st.session_state["_topp_flag_params"] = {}
st.session_state["_topp_flag_params"][tool_instance_name] = list(flag_parameters)
_fp = self.parameter_manager.get_parameters_from_json()
if "_flag_params" not in _fp:
_fp["_flag_params"] = {}
_fp["_flag_params"][tool_instance_name] = list(flag_parameters)
with open(self.parameter_manager.params_file, "w", encoding="utf-8") as _f:
json.dump(_fp, _f, indent=4)

if not display_subsections:
display_subsection_tabs = False
if display_subsection_tabs:
Expand Down
4 changes: 1 addition & 3 deletions tests/test_queue_manager_cancel.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,7 @@ def test_stopped_status_is_mapped_in_get_job_info(monkeypatch):

info = qm.get_job_info("stopped-job")
assert info is not None
assert info.status == __import__(
"src.workflow.QueueManager", fromlist=["JobStatus"]
).JobStatus.CANCELED, (
assert info.status.name == "CANCELED", (
"RQ 'stopped' status should be reported as CANCELED to the UI; "
"otherwise stopped jobs appear stuck in 'queued'."
)
Loading
Loading