From 193ac917d89413224b257c6074152b2b13b3dafe Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 11 Oct 2026 18:12:56 +0000 Subject: [PATCH 1/2] Fix Workflow pages and Layout Managers crashing on a fresh install - Point the example data fallbacks at the mzML and FASTA files shipped in the default demo workspace; the old example-data/deconv and example-data/tnt paths do not exist, so the Workflow pages raised FileNotFoundError in any workspace without uploads. - Call page_setup() before the Layout Managers read st.session_state['workspace'], so opening them by direct link or after a refresh no longer raises KeyError. - Do not index an empty tool list in the parameter summary when no TOPP tool .ini has been written yet. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01KyJg47YNaoYnCCj1QYkHEy --- content/FLASHDeconv/FLASHDeconvLayoutManager.py | 6 ++++-- content/FLASHTnT/FLASHTnTLayoutManager.py | 6 ++++-- src/Workflow.py | 9 +++++---- src/workflow/StreamlitUI.py | 3 ++- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/content/FLASHDeconv/FLASHDeconvLayoutManager.py b/content/FLASHDeconv/FLASHDeconvLayoutManager.py index a2094d2b..5b6e448b 100644 --- a/content/FLASHDeconv/FLASHDeconvLayoutManager.py +++ b/content/FLASHDeconv/FLASHDeconvLayoutManager.py @@ -34,6 +34,10 @@ # "sequence view" and "internal fragment map" added when "input_sequence" is submitted ] +# page_setup() first: it initialises st.session_state['workspace'], which the +# cache access below needs when this page is opened by direct link. +params = page_setup() + # Setup cache access file_manager = FileManager( st.session_state["workspace"], @@ -226,8 +230,6 @@ def setSequenceView(): COMPONENT_NAMES = COMPONENT_NAMES + ['sequence_view', 'internal_fragment_map'] -# page initialization -params = page_setup() # when sequence is submitted, add "Sequence View" as a component option setSequenceView() diff --git a/content/FLASHTnT/FLASHTnTLayoutManager.py b/content/FLASHTnT/FLASHTnTLayoutManager.py index 1ca34a5f..3aaf91b1 100644 --- a/content/FLASHTnT/FLASHTnTLayoutManager.py +++ b/content/FLASHTnT/FLASHTnTLayoutManager.py @@ -28,6 +28,10 @@ 'ms1_deconv_heat_map' ] +# page_setup() first: it initialises st.session_state['workspace'], which the +# cache access below needs when this page is opened by direct link. +params = page_setup() + # Setup cache access file_manager = FileManager( st.session_state["workspace"], @@ -201,8 +205,6 @@ def handleSettingButtons(): for exp in uploaded_layout] st.session_state.num_of_experiment_to_show = len(uploaded_layout) -# page initialization -params = page_setup() # handles "onclick" of buttons if st.session_state.get("edit_mode") is None: diff --git a/src/Workflow.py b/src/Workflow.py index f172f267..049a39b1 100644 --- a/src/Workflow.py +++ b/src/Workflow.py @@ -12,10 +12,11 @@ from src.parse.deconv import parseDeconv from src.workflow.WorkflowManager import WorkflowManager +# Example inputs shipped with the default demo workspace. EXAMPLE_DATA = [ - 'example-data/deconv/example_lc_ms.mzML', - 'example-data/tnt/example_native_aqpz.mzML', - 'example-data/tnt/example_native_antibody.mzML', + 'example-data/workspaces/default/flashdeconv/input-files/mzML-files/example_fd.mzML', + 'example-data/workspaces/default/flashtnt/input-files/mzML-files/example_spectrum_aqpz.mzML', + 'example-data/workspaces/default/flashtnt/input-files/mzML-files/example_spectrum_antibody.mzML', ] class TagWorkflow(WorkflowManager): @@ -33,7 +34,7 @@ def upload(self)-> None: self.ui.upload_widget(key="mzML-files", name="MS data", file_types="mzML", fallback=EXAMPLE_DATA) with t[1]: self.ui.upload_widget(key="fasta-file", name="Database", file_types="fasta", - fallback='example-data/tnt/example_database.fasta') + fallback='example-data/workspaces/default/flashtnt/input-files/fasta-file/example_database.fasta') @st.fragment diff --git a/src/workflow/StreamlitUI.py b/src/workflow/StreamlitUI.py index 07b78c72..71a29d01 100644 --- a/src/workflow/StreamlitUI.py +++ b/src/workflow/StreamlitUI.py @@ -1672,7 +1672,8 @@ def export_parameters_markdown(self): if len(tool_text) > 1: tool_text = ", ".join(tool_text[:-1]) + " and " + tool_text[-1] else: - tool_text = tool_text[0] + # No .ini files yet when the TOPP tools are not installed. + tool_text = tool_text[0] if tool_text else "" result = subprocess.run( "FileFilter --help", shell=True, text=True, capture_output=True From edc9e2bc0eee0c6cd38dbf7ec94327c952202e9a Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 11 Oct 2026 18:15:32 +0000 Subject: [PATCH 2/2] Count rows with pl.len(), which polars 2.0 requires polars 2.0 removed the no-argument pl.count(), so CI, which installs the newest polars allowed by requirements.txt (>=1.0.0), failed test_nonempty_input_passes_through_binning. pl.len() exists since 0.20. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01KyJg47YNaoYnCCj1QYkHEy --- src/render/compression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/compression.py b/src/render/compression.py index f42576b4..805b75b4 100644 --- a/src/render/compression.py +++ b/src/render/compression.py @@ -60,7 +60,7 @@ def downsample_heatmap(data, max_datapoints=20000, rt_bins=400, mz_bins=50, logg return data # Count peaks - total_count = sorted_data.select(pl.count()).item() + total_count = sorted_data.select(pl.len()).item() # Extract arrays for scipy mass_array = sorted_data['mass'].to_numpy()