Skip to content

Feature/gallery upload routing rsdev 1192#56

Open
tilorspace wants to merge 3 commits into
masterfrom
feature/gallery-upload-routing-RSDEV-1192
Open

Feature/gallery upload routing rsdev 1192#56
tilorspace wants to merge 3 commits into
masterfrom
feature/gallery-upload-routing-RSDEV-1192

Conversation

@tilorspace

@tilorspace tilorspace commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Makes the RSpace Gallery a friendlier upload target for GalleryFilesystem
(PyFilesystem) by handling the Gallery's media-type section rule instead of
failing opaquely. Two separable changes plus a Galaxy-compatibility fix.

Jira: RSDEV-1192

Background

The Gallery is split into media-type sections (Images, Audios, Videos,
Documents, Chemistry, ...). A file can only be uploaded into a folder whose
section matches its media type; a mismatched folder is rejected by the API.
Previously upload() passed the folder straight through, so a mismatch surfaced
as an opaque ApiError and the file was lost.

What changed (three commits, reviewable in order)

  1. Clearer error (8bb9e2a) — on a folder-targeted upload the server
    rejects, re-raise a GallerySectionMismatch naming the folder's section (and
    the file's guessed media type), with the original error preserved. Detection
    is reactive: it only enriches after a real server rejection, so the
    best-effort filename classifier can never block a valid upload.

  2. Opt-in auto-reroute (7e8e07e) — add an on_mismatch policy: "raise"
    (default) or "reroute". On reroute, the file is re-uploaded with no
    folderId so the server places it in the correct section's inbox. The policy
    is set filesystem-wide in the constructor (so it also applies to generic
    PyFilesystem operations that call upload/openbin) and can be overridden
    per upload() call. upload() now returns a Placement describing where the
    file landed (global id, section, human-readable path, rerouted flag).

  3. Galaxy-compatibility fix (6cb1f60) — Galaxy's RSpace file source
    monkeypatches eln_client.upload_file with a wrapper that returns None,
    then calls our upload() via super(). Commit 2 started consuming that
    return value to build the Placement, which crashed on None. _placement
    now tolerates a non-dict/None response and the folder-lookup helpers never
    raise, so a successful upload can never fail during Placement construction.

API / behaviour

# filesystem-wide default (applies to all writes, incl. generic fs ops)
fs = GalleryFilesystem(url, api_key, on_mismatch="reroute")

# or per call
placement = fs.upload("/GF123", file_obj, on_mismatch="reroute")
placement.rerouted   # True if it did not land in the requested folder
placement.section    # e.g. "Documents"
placement.path       # e.g. "Gallery/Documents/Api Inbox"

Default policy is "raise", so existing behaviour is preserved apart from the
clearer exception type (a subclass of the previous ApiError).

## Backwards compatibility
Constructor and upload() signatures remain call-compatible (new params are
keyword/defaulted).
GallerySectionMismatch subclasses ApiError, so existing except ApiError
handlers still catch it.
Verified against Galaxy's file source (lib/galaxy/files/sources/rspace.py,
PR [#20167](https://github.com/rspace-os/rspace-client-python/issues/20167) on dev): the reroute is inert for Galaxy (default policy) and the
fix in commit 3 keeps its export path working. Recommend re-confirming against
the specific Galaxy release branch deployed.

## Testing
rspace_client/tests/eln_fs_test.py18 unit tests pass, covering both
policies (constructor + per-call), the media classifier, policy validation, the
no-folder passthrough, success/mismatch/reroute placements, and a regression
that reproduces Galaxy's upload_file-returns-None monkeypatch.

## Docs
docs/usage-guide.md documents the section rule, on_mismatch, and Placement.

## Follow-ups (not in this PR)
Galaxy could drop its upload_file monkeypatch and read Placement.file_global_id
directly, now that upload() returns it.

tilorspace and others added 3 commits July 13, 2026 18:32
When a file is uploaded to a Gallery folder in the wrong media-type section,
the RSpace API rejects it and the client raised an opaque ApiError. Re-raise
as GallerySectionMismatch naming the folder's section (and the file's guessed
media type) with the original error preserved.

Detection is reactive: the enriched error is only produced after a real
server rejection of a folder-targeted upload, so the best-effort filename
classifier can never block an otherwise-valid upload.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add an on_mismatch policy to GalleryFilesystem: "raise" (default, the clear
error from the previous change) or "reroute", which on a section mismatch
re-uploads with no folderId so the server places the file in the correct
section's inbox. The policy is set filesystem-wide in the constructor (so it
also applies to generic PyFilesystem operations that call upload/openbin) and
can be overridden per upload() call.

upload() now returns a Placement describing where the file landed (global id,
section, human-readable path, and whether it was rerouted). Reroutes are logged
at INFO. Document the behaviour in the usage guide.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…EV-1192)

Galaxy's RSpace file source monkeypatches eln_client.upload_file with a wrapper
that captures the response and returns None, then calls GalleryFilesystem.upload
via super(). Change 2 started consuming upload_file's return value to build a
Placement, which crashed on that None with AttributeError, breaking every
Galaxy->RSpace export.

Make _placement tolerate a non-dict/None response and make the best-effort
folder-lookup helpers never raise, so a successful upload can never fail during
Placement construction. Direct callers still receive a full Placement.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@anuprulez

Copy link
Copy Markdown

The changes look ok to me. Thanks a lot @tilorspace

@tilorspace tilorspace marked this pull request as ready for review July 15, 2026 15:53
@tilorspace tilorspace requested a review from nebay-abraha July 15, 2026 15:53
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