Skip to content

Fix manual file upload and improve FLASHTnT parsing - #97

Merged
t0mdavid-m merged 2 commits into
developfrom
claude/flashapp-upload-suffix-error-dy1djs
Aug 25, 2026
Merged

Fix manual file upload and improve FLASHTnT parsing#97
t0mdavid-m merged 2 commits into
developfrom
claude/flashapp-upload-suffix-error-dy1djs

Conversation

@t0mdavid-m

Copy link
Copy Markdown
Member

Summary

Fixes a critical bug in manual result upload that prevented Streamlit UploadedFile objects from being stored, and refactors the upload workflows to handle tool-generated file names correctly. Also improves FLASHTnT to parse deconvolution data before tag matching.

Key Changes

FileManager fix (src/workflow/FileManager.py)

  • Bug fix: FileManager.store_file() now handles file-like objects (Streamlit's UploadedFile) that lack a suffix attribute by falling back to extracting the extension from the name attribute
  • Previously failed with AttributeError: 'UploadedFile' object has no attribute 'suffix'

FLASHDeconv upload workflow (content/FLASHDeconv/FLASHDeconvWorkflow.py)

  • Refactored process_uploaded_files() to use a declarative UPLOAD_FILE_TYPES tuple mapping file suffixes to name tags and tool prefixes
  • Replaces verbose if/elif chains with a single loop
  • Introduces default_dataset (timestamped) to group files with tool-generated names (out_deconv.mzML, anno_annotated.mzML) that would otherwise split into separate datasets
  • Adds validation to ensure both deconvolved and annotated mzML files are present before parsing
  • Wraps parsing in a spinner for better UX

FLASHTnT upload workflow (content/FLASHTnT/FLASHTnTWorkflow.py)

  • Same refactoring as FLASHDeconv with UPLOAD_FILE_TYPES and default_dataset
  • Adds support for legacy _tagged.tsv file name (maps to tags_tsv)
  • Key improvement: Now calls parseDeconv() before parseTnT() to ensure deconvolution data is available for tag matching
  • Adds partial=True to get_results() calls to allow processing with incomplete file sets
  • Validates required files (deconv_mzML, anno_annotated_mzML, tags_tsv, protein_tsv) before processing
  • Wraps parsing in a spinner

Test coverage (tests/test_manual_upload.py)

  • New comprehensive test suite covering:
    • File extension preservation when storing UploadedFile objects
    • Backward compatibility with Path input
    • Correct dataset grouping for tool-generated file names
    • Experiment name extraction from user-provided file names
    • FLASHTnT legacy file name support

Implementation Details

  • The UPLOAD_FILE_TYPES tuples are defined locally in each workflow page (cannot be imported without Streamlit runtime) and reproduced in tests as literals
  • File name parsing: experiment = file.name[:-len(suffix)].rstrip('_') extracts the experiment name, then falls back to default_dataset if the result is empty or matches the tool prefix
  • default_dataset uses time.strftime('uploaded_%Y%m%d-%H%M%S') to create unique, human-readable dataset names for ungrouped uploads
  • FLASHTnT now ensures deconvolution tolerance is parsed before tag matching (required for tag resolution)

https://claude.ai/code/session_01RAyRJPFo13Xn4w8b4B8ju6

claude added 2 commits August 25, 2026 13:10
Uploading result files in the "Manual Result Upload" tab crashed with

    AttributeError: 'UploadedFile' object has no attribute 'suffix'

FileManager.store_file derived the stored file name from `file.suffix`,
which only exists on Path inputs - Streamlit's UploadedFile is a BytesIO
subclass that carries the original file name in `name`.

Two things kept the tab from working once past the crash:

- The dataset id was the part of the file name in front of the known
  suffix. FLASHDeconv names its results `out_deconv.mzML` and
  `anno_annotated.mzML`, so the two halves of one run were filed under the
  datasets "out" and "anno" and never parsed together. Files with the
  unchanged tool output names now go to a common dataset, renamed files
  (`sample_deconv.mzML`) keep their experiment name as before.
- parseDeconv was called by its pre-refactor signature
  (`parseDeconv(**results)`); it writes into the FileManager itself and
  needs it plus the dataset id and a logger.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RAyRJPFo13Xn4w8b4B8ju6
The FLASHTnT tab had the same three problems as the FLASHDeconv one:
storing an UploadedFile crashed in FileManager.store_file (fixed in the
previous commit), the dataset id was the part of the file name in front of
the known suffix, and the parsers were called by a signature that no
longer exists.

FLASHDeconv and FLASHTnT name their results 'out_deconv.mzML',
'anno_annotated.mzML', 'tags.tsv' and 'protein.tsv', so the files of one
run were filed under the datasets "out", "anno" and (for the tsv files)
not at all - the tab only matched '*_tagged.tsv' and '*_protein.tsv',
which FLASHTnT never writes. Files with the unchanged output names now go
to a common dataset and 'tags.tsv' is accepted next to the previously
expected '*_tagged.tsv'; renamed files keep their experiment name.

parseTnT no longer returns dataframes, it writes into the FileManager and
needs it plus the dataset id and a logger, and it reads the deconvolution
tolerance - so, as in Workflow.execution(), parseDeconv runs first unless
the dataset was deconvolved before. Incomplete uploads are reported
instead of raising a KeyError.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RAyRJPFo13Xn4w8b4B8ju6
@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f2d34af0-ef27-4d65-98ac-84c6ae22b9d2


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@t0mdavid-m
t0mdavid-m merged commit a186f47 into develop Aug 25, 2026
5 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants