Skip to content

Instantly share code, notes, and snippets.

@jmchilton
Created January 15, 2026 13:30
Show Gist options
  • Select an option

  • Save jmchilton/dd5b36a4e300b4ff59d3d687dac2181f to your computer and use it in GitHub Desktop.

Select an option

Save jmchilton/dd5b36a4e300b4ff59d3d687dac2181f to your computer and use it in GitHub Desktop.
Triage: Issue #21591 - Batch export of histories, workflow invocations, and datasets

Feature Request #21591: Batch export of histories, workflow invocations, and datasets

URL: galaxyproject/galaxy#21591 Author: M Bernt (@bernt-matthias) Created: 2026-01-15 Labels: feature-request Reactions: 1 thumbs up

Description

It would be great to be able to export multiple histories, invocations, or datasets at once.

For histories I could imaging that users select all histories they want to export and then the same export dialog opens where a destination can be selected. It would be perfectly sufficient for my needs to have a separate export job per history. But one could also imagine that users might want to have all histories in a single export.

Invocations currently miss the possibility to select multiple ones. But I could imagine a similar approach as for histories is feasible.

For datasets we can only download single datasets at the moment, i.e. there is no export (eg. to a file source). Selecting multiple datasets and having the possibility to export them to a file source could be a nice thing to have as well.

Comments

No comments yet.

Feature #21591: Batch Export Code Research

Issue Summary

Feature request for batch export capabilities:

  1. Batch export of histories to file sources
  2. Batch export of workflow invocations
  3. Batch export/download of datasets to file sources

1. Existing Export Mechanisms

1.1 History Export

Backend API

  • Endpoint (write to file source): POST /api/histories/{history_id}/write_store
  • Endpoint (download): POST /api/histories/{history_id}/prepare_store_download
  • API Implementation: /lib/galaxy/webapps/galaxy/api/histories.py (lines 350-364)
  • Service Layer: /lib/galaxy/webapps/galaxy/services/histories.py
    • prepare_download() - creates download via short term storage (line 375)
    • write_store() - writes to file source URI (line 399)

Key Service Methods

# lib/galaxy/webapps/galaxy/services/histories.py
def prepare_download(self, trans, history_id, payload: StoreExportPayload) -> AsyncFile:
    # Creates short_term_storage_target, triggers celery task

def write_store(self, trans, history_id, payload: WriteStoreToPayload) -> AsyncTaskResultSummary:
    # Writes to target_uri via celery task

Celery Tasks

  • /lib/galaxy/celery/tasks.py
    • prepare_history_download (line 395) - generates history model store for download
    • write_history_to (line 431) - writes history store to file source URI

Model Store Manager

  • /lib/galaxy/managers/model_stores.py
    • ModelStoreManager.prepare_history_download() (line 108)
    • ModelStoreManager.write_history_to() (line 224)

Frontend Components

  • Export Wizard: /client/src/components/History/Export/HistoryExportWizard.vue
    • Multi-step wizard for export configuration
    • Supports download, remote source, RDM repository, Zenodo
    • Uses useFileSources() composable for file source access
  • API Client: /client/src/api/histories.export.ts
    • exportHistoryToFileSource() - calls write_store endpoint

1.2 Workflow Invocation Export

Backend API

  • Endpoint (write to file source): POST /api/invocations/{invocation_id}/write_store
  • Endpoint (download): POST /api/invocations/{invocation_id}/prepare_store_download
  • API Implementation: /lib/galaxy/webapps/galaxy/api/workflows.py (lines 1417-1446)
  • Service Layer: /lib/galaxy/webapps/galaxy/services/invocations.py

Celery Tasks

  • prepare_invocation_download (line 413)
  • write_invocation_to (line 422)

1.3 Dataset/Collection Export

Backend API

  • Endpoint (write to file source): POST /api/histories/{history_id}/contents/{type}s/{id}/write_store
  • Endpoint (download): POST /api/histories/{history_id}/contents/{type}s/{id}/prepare_store_download
  • API Implementation: /lib/galaxy/webapps/galaxy/api/history_contents.py (lines 587-602)
  • Service Layer: /lib/galaxy/webapps/galaxy/services/history_contents.py
    • prepare_store_download() (line 360)
    • write_store() (line 393)

Celery Tasks

  • prepare_history_content_download (line 403)
  • write_history_content_to (line 437)

2. File Source Integration Points

2.1 Core File Sources

  • /lib/galaxy/managers/file_source_instances.py - User-defined file sources management
  • /lib/galaxy/managers/remote_files.py - Remote file operations
  • /lib/galaxy/files/ - Core file sources framework

2.2 Key Integration Patterns

Payload Schema

# lib/galaxy/schema/schema.py
class WriteStoreToPayload(StoreExportPayload):
    target_uri: str  # Galaxy Files URI to write store content to

class StoreExportPayload(Model):
    model_store_format: ModelStoreFormat  # tar.gz, rocrate.zip
    include_files: bool
    include_deleted: bool
    include_hidden: bool

Task Request Schema

# lib/galaxy/schema/tasks.py
class WriteHistoryTo(WriteStoreToPayload):
    history_id: int
    user: RequestUser
    export_association_id: Optional[int]

class WriteInvocationTo(WriteStoreToPayload, BcoGenerationTaskParametersMixin):
    invocation_id: int
    user: RequestUser

class WriteHistoryContentTo(WriteStoreToPayload):
    content_type: HistoryContentType
    content_id: int
    user: RequestUser

2.3 File Source Access Pattern

# Model store export with file source
user_context = ModelStoreUserContext(self._app, user)
export_store = model.store.get_export_store_factory(
    self._app, model_store_format, export_files=export_files, user_context=user_context
)(target_uri)

3. Multi-Select UI Patterns

3.1 History Content Selection

  • Component: /client/src/components/History/CurrentHistory/HistoryOperations/SelectionOperations.vue
  • Features:
    • Dropdown menu with batch operations (hide, delete, purge, etc.)
    • Supports both explicit selection and query-based selection
    • Modal confirmations for destructive operations

3.2 History List Selection

  • Component: /client/src/components/History/HistoryList.vue
  • Composable: /client/src/composables/selectedItems/selectedItems.ts
  • Features:
    • Checkbox selection
    • Shift+Click range selection
    • Ctrl+Click multi-select
    • Select all functionality
    • Bulk operations: delete, restore, purge, add tags, open in multiview

3.3 Selection Composable

// client/src/composables/selectedItems/selectedItems.ts
export function useSelectedItems<T>({
    scopeKey, getItemKey, filterText, totalItemsInQuery, allItems,
    filterClass, selectable, ...
}) {
    const selectedItems = ref<Map<string, T>>(new Map());
    // ... selection logic, range select, etc.
    return {
        selectedItems, selectAllInCurrentQuery, isSelected,
        setSelected, resetSelection, ...
    };
}

3.4 Grid Selection

  • Component: /client/src/components/Grid/GridList.vue
  • Has checkbox selection built into grid framework (line 67)
  • Batch operations via BatchOperation type

4. Extension Points for Batch Operations

4.1 Existing Bulk Operations Pattern (History Contents)

# lib/galaxy/schema/schema.py
class HistoryContentItemOperation(str, Enum):
    hide = "hide"
    unhide = "unhide"
    delete = "delete"
    undelete = "undelete"
    purge = "purge"
    change_datatype = "change_datatype"
    change_dbkey = "change_dbkey"
    add_tags = "add_tags"
    remove_tags = "remove_tags"

class HistoryContentBulkOperationPayload(Model):
    operation: HistoryContentItemOperation
    items: Optional[list[HistoryContentItem]]
    params: Optional[AnyBulkOperationParams]

API Endpoint: PUT /api/histories/{history_id}/contents/bulk

4.2 Proposed Batch Export Extension Points

Backend - New Task Request Models

# Potential new schema in lib/galaxy/schema/tasks.py
class BatchWriteHistoriesTo(WriteStoreToPayload):
    history_ids: list[int]
    user: RequestUser

class BatchWriteInvocationsTo(WriteStoreToPayload, BcoGenerationTaskParametersMixin):
    invocation_ids: list[int]
    user: RequestUser

class BatchWriteHistoryContentsTo(WriteStoreToPayload):
    content_items: list[HistoryContentItem]  # {id, history_content_type}
    user: RequestUser

Backend - New Celery Tasks

# In lib/galaxy/celery/tasks.py
@galaxy_task(action="batch export histories to file source")
def batch_write_histories_to(model_store_manager, request: BatchWriteHistoriesTo, ...):
    for history_id in request.history_ids:
        # Export each history to target_uri/{history_name}.{format}

Backend - New API Endpoints

# In lib/galaxy/webapps/galaxy/api/histories.py
@router.post("/api/histories/batch_write_store")
def batch_write_store(self, payload: BatchWriteStoreToPayload) -> AsyncTaskResultSummary:
    ...

# In lib/galaxy/webapps/galaxy/api/workflows.py
@router.post("/api/invocations/batch_write_store")
def batch_write_store(self, payload: BatchWriteInvocationsStoreToPayload) -> AsyncTaskResultSummary:
    ...

# In lib/galaxy/webapps/galaxy/api/history_contents.py (or datasets.py)
@router.post("/api/datasets/batch_write_store")
def batch_write_store(self, payload: BatchWriteDatasetsToPayload) -> AsyncTaskResultSummary:
    ...

5. Key Files for Modification

Backend (Python)

File Purpose Changes Needed
lib/galaxy/schema/schema.py Pydantic models Add batch payload schemas
lib/galaxy/schema/tasks.py Task request models Add batch task request models
lib/galaxy/celery/tasks.py Celery tasks Add batch export tasks
lib/galaxy/managers/model_stores.py Export logic Add batch export methods
lib/galaxy/webapps/galaxy/api/histories.py History API Add batch export endpoint
lib/galaxy/webapps/galaxy/api/workflows.py Invocation API Add batch export endpoint
lib/galaxy/webapps/galaxy/api/history_contents.py Content API Add batch export endpoint
lib/galaxy/webapps/galaxy/services/histories.py History service Add batch export service method
lib/galaxy/webapps/galaxy/services/history_contents.py Content service Add batch export service method
lib/galaxy/webapps/galaxy/services/invocations.py Invocation service Add batch export service method

Frontend (TypeScript/Vue)

File Purpose Changes Needed
client/src/api/histories.export.ts History export API Add batch export function
client/src/components/History/HistoryList.vue History list UI Add batch export button/action
client/src/components/History/Export/HistoryExportWizard.vue Export wizard Modify for batch support
client/src/components/History/CurrentHistory/HistoryOperations/SelectionOperations.vue Content operations Add batch export option
client/src/components/Grid/GridInvocation.vue Invocation grid Add batch export action
client/src/composables/selectedItems/selectedItems.ts Selection logic May need batch action hooks

6. Architectural Patterns to Follow

6.1 Async Task Pattern

  1. API endpoint receives payload
  2. Creates export association record
  3. Queues Celery task with request
  4. Returns AsyncTaskResultSummary with task UUID
  5. Client polls for completion

6.2 Export Tracking Pattern

  • Use StoreExportAssociation model for tracking
  • StoreExportTracker manager for CRUD
  • Store metadata via ExportObjectMetadata

6.3 File Source URI Pattern

target_uri = f"{base_directory}/{object_name}.{model_store_format}"
# e.g., "gxfiles://my_s3_bucket/exports/My_History.rocrate.zip"

6.4 UI Pattern for Batch Operations

  1. Selection via composable (useSelectedItems)
  2. Action button in dropdown/toolbar
  3. Modal dialog for configuration (export options)
  4. Progress indicator during async operation
  5. Toast/notification on completion

7. Unresolved Questions

  1. Naming convention for batch exports - Individual files per item vs single archive?
  2. Subdirectory structure - Flat or organized by type (histories/, invocations/, datasets/)?
  3. Error handling - Continue on failure vs abort batch?
  4. Progress tracking - Single task vs task per item?
  5. Rate limiting - Max items per batch?
  6. UI flow - Wizard per batch or simplified single-step?
  7. Concurrent export limit - How many parallel exports allowed?

Demand Analysis: Issue #21591 - Batch Export of Histories, Workflow Invocations, and Datasets

Issue Overview

Issue: #21591 Title: Batch export of histories, workflow invocations, and datasets Author: @bernt-matthias (M Bernt) - Galaxy maintainer/member Created: 2026-01-15 Labels: feature-request

Request Summary:

  1. Export multiple histories at once to file source destinations
  2. Export multiple invocations at once (currently no multi-select)
  3. Export multiple datasets to file sources (currently only download, no export)

Direct Demand Signals

Issue #21591 Metrics

  • Thumbs Up Reactions: 1 (from @mvdbeek - core maintainer)
  • Comments: 0
  • Age: Same day (very new issue)

Related Issue from Same Author (Same Day)

Related Issues Analysis

Directly Related (Batch/Multi Export)

Issue Title State Reactions Comments Age
#3195 Enhance History "Operations on multiple datasets" to include multi-download Open 3 thumbs up + 8 on comment 7 2016
#18245 Option to download selected datasets Open 1 thumbs up 2 2024
#2968 Add more download options for datasets and histories Open 4 thumbs up 11 2016
#8378 Extend batch operations on multiple histories Open 1 thumbs up + 2 on comment 1 2019
#15345 Feature request: operations on multiple histories Open 0 1 2022

Export to File Sources Related

Issue Title State Reactions Comments
#20269 Improve export of workflow invocation outputs Open 2 thumbs up, 2 hearts 1
#19640 Ability to list file source for history archiving only Open 0 0
#16974 Export workflow invocation as planemo workflow test Open 2 thumbs up 17
#5389 Archival and replication of user analyses Open 5 thumbs up 7

History Archiving/Export (Broader Context)

Issue Title State Reactions Comments
#14771 Archiving Histories Closed 0 16
#10695 Unify history/workflow uploading with data upload dialog Open 0 4

Quantified Demand Summary

Total Reaction Count (Related Issues)

  • Thumbs Up: 19+ across related issues
  • Hearts: 2
  • Hooray: 6 (on #5389 comment)

Comment Activity

  • High engagement issues: #2968 (11 comments), #16974 (17 comments), #14771 (16 comments)
  • Long-standing requests: Issues dating back to 2016 still open

Issue Longevity

  • Oldest related request: #2968 (September 2016) - 9+ years open
  • Multiple requests: #3195 (November 2016) - 9+ years open
  • Pattern: Batch export/download has been requested for nearly a decade

User Sentiment Analysis

Positive Signals

  1. Core maintainer support: @mvdbeek (core maintainer) immediately thumbs-up'd #21591
  2. Long-standing need: Multiple independent requests over 9+ years
  3. Workaround adoption: Users actively using collection-based workarounds (create collection then download)
  4. Training/GTN demand: #16974 shows trainers need simpler export workflows
  5. VGP collaboration need: #20269 demonstrates real production use case for complex exports

User Quotes

"It would be really useful if I could group these histories to one project... To my knowledge there is no option to see and share already in the 'All histories' view this." - @joachimwolff (#8378)

"I find myself a bit frustrated by having to do imports one at a time... And for history tarball, I want to upload multiple potentially, not just one." - @hexylena (#10695)

"Given how hard it is to initially train users to just learn how to share their histories via a link, pointing out yet another place with scary words like RO-Crate... is really tough." - @nomadscientist (#10695)

"This came up on our side today too" - @hexylena on download throttling (#2968)

Pain Points Identified

  1. Time-consuming manual process: Users report 4+ minutes per history to share/export
  2. Scalability issues: Users with 14+ project histories struggle with current workflow
  3. Training barrier: Non-developers find current export tools intimidating
  4. No unified interface: Export scattered across multiple menus/tools

Feature Request Patterns

Component 1: Batch History Export

  • Direct requests: #21591, #8378, #15345
  • Related: #14771 (archiving), #5389 (archival)
  • Estimated demand: MEDIUM-HIGH

Component 2: Batch Invocation Export

  • Direct requests: #21591, #21592
  • Related: #20269, #16974
  • Estimated demand: MEDIUM

Component 3: Dataset Export to File Sources

  • Direct requests: #21591
  • Related: #3195, #18245, #2968
  • Estimated demand: HIGH (oldest and most requested)

Duplicate/Related Issues

Potential Duplicates

  • #3195 vs #18245: Both request multi-dataset download
  • #8378 vs #15345: Both request batch history operations

Should Consider Closing/Linking

If #21591 is implemented, could partially address:

  • #3195 (multi-download - if export to local added)
  • #18245 (download selected datasets)
  • #8378 (batch history operations)
  • Parts of #2968 (more download options)

Implementation Considerations

Existing Workarounds

  1. Create collection from selected datasets, download collection as ZIP
  2. Use export_remote tool for individual datasets
  3. Manual one-by-one export

Technical Foundation

  • History export to file sources already exists
  • Invocation export exists (RO-Crate, BCO)
  • Export datasets tool exists (but individual only)
  • Multi-select UI patterns exist in history panel

Overall Demand Assessment

Aspect Rating Justification
User Interest MEDIUM 1 reaction but new issue; related issues show consistent demand
Longevity HIGH Related requests span 9+ years
Core Team Interest HIGH Core maintainer (@mvdbeek) immediately supported
Related Activity HIGH Multiple related issues, active discussions
Workaround Availability MEDIUM Collections partially address download need
Implementation Complexity MEDIUM Foundation exists but UI/UX work needed

OVERALL DEMAND: MEDIUM-HIGH

Rationale: While the specific issue is new with limited direct engagement, the underlying need has been expressed repeatedly over 9 years across multiple issues. The thumbs-up from a core maintainer suggests technical alignment with project direction. The existence of workarounds (collections) indicates users actively want this functionality. The feature fits within Galaxy's ongoing efforts to improve export/archival capabilities (see #14771 implementation).

Recommendations

  1. Link related issues: Connect #21591 to #3195, #18245, #2968, #8378 for visibility
  2. Scope definition: Consider implementing in phases:
    • Phase 1: Batch dataset export to file sources
    • Phase 2: Batch history export
    • Phase 3: Batch invocation export
  3. Close duplicates: After implementation, close older related issues
  4. Promote issue: Given long-standing demand, consider adding to project roadmap

Data Sources

  • GitHub Issues API (galaxyproject/galaxy)
  • Issue search: "batch export", "bulk download", "export multiple", "file source export"
  • Comment and reaction analysis
  • Cross-reference with related feature requests

Feature Assessment: Issue #21591 - Batch Export of Histories, Workflow Invocations, and Datasets

Issue URL: galaxyproject/galaxy#21591 Requester: @bernt-matthias (established Galaxy contributor) Date Filed: 2026-01-15


1. User Demand Assessment: LOW-MEDIUM

Signals:

  • 1 thumbs up reaction (minimal community engagement)
  • 0 comments (no additional voices)
  • Requested by single (albeit respected) contributor

Analysis:

  • No linked duplicates or related feature requests found
  • The use case (bulk export to file sources) is plausible for power users/training administrators
  • Pattern exists: similar bulk operations are commonly requested after they become feasible
  • Hidden demand likely higher than signals suggest - users with this need may work around it via scripting/API

Verdict: Low current demand signal but likely underrepresented. Power users with export-heavy workflows would benefit significantly.


2. Strategic Value Assessment: MEDIUM-HIGH

Alignment with Galaxy Direction:

  • Galaxy has invested heavily in file source infrastructure (RDM, S3, FTP, Azure, etc.)
  • Export to file sources is a natural extension of the file source ecosystem
  • Aligns with reproducibility goals (batch export of invocations = reproducible research archives)

Enabling Capabilities:

  • Foundation for automated backup workflows
  • Better integration with institutional data repositories
  • Potential building block for data lifecycle management features
  • Could enable downstream features like scheduled exports, retention policies

UX Improvement:

  • Current workaround requires N separate export operations
  • Significant time savings for training courses (export all participant histories)
  • Better support for project completion workflows (archive everything at once)

Verdict: Good strategic alignment with file source ecosystem and reproducibility goals.


3. Effort Estimate: LARGE

This is effectively THREE related but separate features:

3a. Batch History Export

  • UI: Selection mechanism exists in HistoryList.vue via useSelectedItems composable
  • Backend: New endpoint needed: /api/histories/batch_write_store or similar
  • Client: Modal/wizard for destination selection with batch preview
  • Effort: Medium (can leverage existing exportHistoryToFileSource pattern)

3b. Batch Invocation Export

  • UI: GridInvocation.vue uses GridList but lacks batch selection - needs batch config
  • Backend: New endpoint similar to histories
  • Client: Invocation export wizard already exists, needs batch mode
  • Effort: Medium-Large (grid selection infrastructure less mature than HistoryList)

3c. Dataset Export to File Sources

  • UI: HistoryPanel has selection via useSelectedItems
  • Backend: Endpoint exists for single dataset (/api/histories/{id}/contents/{type}s/{id}/write_store) - needs batch variant
  • Client: New modal needed for file source destination + export params
  • Effort: Medium (leverages existing patterns)

Infrastructure Needed:

  • Batch task management (multiple async tasks per user request)
  • Progress tracking UI for batch operations
  • Error aggregation/reporting for partial failures
  • Celery task orchestration considerations

Total Effort: ~3-4 developer weeks for full implementation of all three features


4. Risk Assessment

Breaking Changes

  • Risk: Low
  • New endpoints, no modification to existing API contracts
  • UI additions are additive

Migration Needs

  • Risk: None
  • No database schema changes required
  • No configuration changes required

Security Considerations

  • Risk: Medium
  • File source access already validated per-operation; batch must respect same permissions
  • Must prevent resource exhaustion (user queuing thousands of exports)
  • Need rate limiting or queue depth limits per user
  • Credential/token handling for file sources already established

Performance Implications

  • Risk: Medium-High
  • Large batch exports could strain:
    • Object store I/O (reading datasets)
    • Network bandwidth (to remote file sources)
    • Celery worker pool
    • Short-term storage quotas
  • Mitigation: Configurable batch size limits, staggered execution

Testing Considerations

  • Integration tests needed for each export type
  • File source mocking for various destination types
  • Error scenario testing (partial failures, network issues)

5. Recommendation: BACKLOG

Rationale:

  • Strategic value is real but not urgent
  • Low current demand signal doesn't justify immediate prioritization
  • Implementation is non-trivial (3 separate features with shared infrastructure)
  • Good candidate for contributor-driven development or future release planning

Alternative Approaches:

  1. Phase 1 (Lower Effort): Implement batch history export only - most common use case
  2. API-First: Expose batch endpoints without UI - power users can script
  3. Collection Workaround: Document using dataset collections as export aggregation mechanism

If Prioritizing:

  • Start with batch history export (clearest demand, best existing infrastructure)
  • Datasets second (most reusable patterns)
  • Invocations last (requires grid selection work)

Suggested Actions:

  1. Add backlog label
  2. Link to this assessment
  3. Ask requester to gather additional community interest
  4. Consider for next major release planning if demand signals increase

Summary Table

Dimension Rating Notes
User Demand Low-Medium 1 reaction, respected requester, likely hidden demand
Strategic Value Medium-High Aligns with file source ecosystem, reproducibility
Effort Large 3-4 weeks, three features + shared infrastructure
Risk Medium Security/performance need attention
Recommendation Backlog Good feature, not urgent

Implementation Plan: Issue #21591 - Batch Export

Issue: galaxyproject/galaxy#21591 Date: 2026-01-15


1. Recommended Approach: Phased Implementation

Start with batch history export, then datasets, then invocations.

Why Phased Over All-At-Once

Factor Phased All-At-Once
Time to first value ~1 week 3-4 weeks
Risk containment Lower - test patterns early Higher - many unknowns
Feedback loop Get user feedback before investing more No early validation
Infrastructure Build shared patterns incrementally Must design all upfront
Code review Smaller, focused PRs Large complex PR

Why history export first:

  1. Highest user demand based on related issues (#8378, #15345, #14771)
  2. Best existing infrastructure - HistoryList.vue already has robust selection via useSelectedItems
  3. Single history export wizard (HistoryExportWizard.vue) is mature
  4. Clearest user story - "archive all project histories at once"

2. Phase 1: Batch History Export

2.1 Affected Files

Backend (Python)

File Changes
lib/galaxy/schema/schema.py Add BatchWriteStoreToPayload schema
lib/galaxy/schema/tasks.py Add BatchWriteHistoriesTo task request model
lib/galaxy/celery/tasks.py Add batch_write_histories_to task
lib/galaxy/managers/model_stores.py Add batch_write_histories_to() method
lib/galaxy/webapps/galaxy/api/histories.py Add POST /api/histories/batch_write_store endpoint
lib/galaxy/webapps/galaxy/services/histories.py Add batch_write_store() service method

Frontend (TypeScript/Vue)

File Changes
client/src/api/histories.export.ts Add batchExportHistoriesToFileSource() function
client/src/components/History/HistoryList.vue Add "Export Selected" to bulk operations dropdown
client/src/components/History/Export/HistoryExportWizard.vue Support batch mode (multiple history IDs)

2.2 API Design

Endpoint

POST /api/histories/batch_write_store

Payload Schema

class BatchHistoryWriteStoreToPayload(StoreExportPayload):
    history_ids: List[DecodedDatabaseIdField]
    target_uri: str  # Base directory URI - each history written as subfile
    # Inherits from StoreExportPayload:
    # - model_store_format: ModelStoreFormat (tar.gz, rocrate.zip)
    # - include_files: bool
    # - include_deleted: bool
    # - include_hidden: bool

Response

class BatchExportResult(Model):
    task_ids: List[str]  # One celery task UUID per history
    total_count: int

File Naming Convention

{target_uri}/{history_name}_{history_id}.{format}
# Example: gxfiles://my_s3/exports/My_Analysis_abc123.rocrate.zip

2.3 UI Integration

Where Export Button Lives

In HistoryList.vue, add to existing bulk operations dropdown alongside "Delete Selected", "Purge Selected":

<!-- In HistoryList.vue operations dropdown -->
<BDropdownItem @click="exportSelected">
    <FontAwesomeIcon :icon="faFileExport" class="mr-1" />
    Export Selected to File Source
</BDropdownItem>

How Selection Works

Already implemented via useSelectedItems composable:

  • Checkbox selection per history
  • Shift+click range select
  • "Select All" button
  • Selection state stored in selectedItems ref

Export Flow

  1. User selects multiple histories via checkboxes
  2. Clicks "Export Selected to File Source" in dropdown
  3. HistoryExportWizard opens in batch mode
  4. Wizard shows:
    • Count of selected histories
    • File source destination picker
    • Export format options (model_store_format, include_files, etc.)
  5. User confirms, API called
  6. Toast notification with link to file source destination

2.4 Key Implementation Steps

  1. Schema & Models (backend)

    • Add BatchHistoryWriteStoreToPayload to schema.py
    • Add BatchWriteHistoriesTo to tasks.py
  2. Celery Task (backend)

    • Add batch_write_histories_to task that iterates history_ids
    • Each history exported to {target_uri}/{name}_{id}.{format}
    • Return aggregated result
  3. Service & API (backend)

    • Add batch_write_store() to HistoriesService
    • Add endpoint to histories.py router
  4. API Client (frontend)

    • Add batchExportHistoriesToFileSource() to histories.export.ts
  5. Wizard Modification (frontend)

    • Update HistoryExportWizard.vue props to accept historyIds: string[]
    • Show batch preview step when multiple IDs provided
    • Call batch endpoint when in batch mode
  6. HistoryList Integration (frontend)

    • Add dropdown item
    • Wire up to open wizard with selected IDs

3. Testing Strategy

3.1 Unit Tests

Test Location Description
Schema validation test/unit/schema/ Validate BatchHistoryWriteStoreToPayload
Service method test/unit/webapps/ Mock manager, test batch_write_store service
API serialization test/unit/webapps/api/ Test endpoint response format

3.2 Integration Tests

Test Location Description
Batch export task test/integration/ Full celery task execution with mock file source
API endpoint test/integration/ POST /api/histories/batch_write_store with auth
File source write test/integration/ Verify files written to destination

Recommended test file: test/integration/test_batch_history_export.py

def test_batch_export_to_file_source(self):
    # Create 3 test histories
    # Configure test file source
    # POST to batch endpoint
    # Verify 3 files created at destination
    # Verify naming convention

def test_batch_export_partial_failure(self):
    # Create histories where one will fail (e.g., no access)
    # Verify other exports succeed
    # Verify error reported for failed one

def test_batch_export_empty_list(self):
    # POST with empty history_ids
    # Expect 400 Bad Request

def test_batch_export_unauthorized(self):
    # Attempt to export histories user doesn't own
    # Expect 403 for those histories

3.3 Manual Testing Scenarios

  1. Happy path: Select 3 histories, export to configured S3 file source, verify all 3 archives created
  2. Mixed access: Select history you own + shared history, verify appropriate handling
  3. Large batch: Select 10+ histories, verify performance acceptable
  4. Cancellation: Start batch export, navigate away, verify task completes
  5. Duplicate names: Export two histories with same name, verify unique filenames
  6. Empty selection: Verify "Export Selected" disabled when nothing selected

4. Migration/Breaking Changes

Breaking Changes: None

  • New endpoint, does not modify existing /api/histories/{id}/write_store
  • New UI button, does not change existing single-history export flow
  • Additive schema changes only

Migration: Not Required

  • No database schema changes
  • No configuration file changes
  • Feature gated behind file source configuration (users need file sources to use)

Deprecation: None Planned

  • Single-history export remains canonical for single exports
  • No plans to deprecate existing patterns

5. Future Phases (Brief Outline)

Phase 2: Batch Dataset Export

Scope: Export multiple selected datasets from history to file source

Key Changes:

  • Add /api/datasets/batch_write_store endpoint
  • Add export option to SelectionOperations.vue dropdown
  • Reuse patterns from Phase 1

Estimated effort: ~1 week (patterns established)

Phase 3: Batch Invocation Export

Scope: Export multiple workflow invocations to file source

Key Changes:

  • Add batch selection to GridInvocation.vue (currently lacks checkbox selection)
  • Add /api/invocations/batch_write_store endpoint
  • Reuse patterns from Phase 1

Estimated effort: ~1.5 weeks (grid selection needs work)


6. Unresolved Questions

  1. Error handling strategy - Continue on single failure or abort entire batch?

    • Recommend: Continue, report failures in result
  2. Rate limiting - Max histories per batch request?

    • Need input on server capacity concerns
    • Suggest: Start with 50, make configurable
  3. Filename collision - How handle duplicate history names?

    • Options: append ID (recommended), timestamp, counter
    • {name}_{id}.{format} vs {name}_{timestamp}.{format}
  4. Progress UI - Show progress for batch, or just notify on complete?

    • Single notification simpler; progress polling adds complexity
    • Recommend: Toast on submit, toast on complete (no progress bar for v1)
  5. Concurrent export limit - Per-user limit on active batch exports?

    • Relevant if users can queue multiple large batches
    • May need celery task prioritization
  6. Subdirectory creation - Create {target_uri}/exports/ or write to exact URI?

    • User expectation: probably exact URI
    • Admin expectation: might want organized structure
  7. Overwrite behavior - If file exists at destination, overwrite or fail?

    • Recommend: Fail with clear error, user should choose different destination

Appendix: Code References

Existing Single History Export

  • API: lib/galaxy/webapps/galaxy/api/histories.py lines 350-364
  • Service: lib/galaxy/webapps/galaxy/services/histories.py write_store() line 399
  • Task: lib/galaxy/celery/tasks.py write_history_to line 431
  • Manager: lib/galaxy/managers/model_stores.py write_history_to() line 224
  • Frontend: client/src/components/History/Export/HistoryExportWizard.vue

Selection Composable

  • client/src/composables/selectedItems/selectedItems.ts
  • Used by: HistoryList.vue, history panel operations

Bulk Operations Pattern

  • lib/galaxy/schema/schema.py HistoryContentBulkOperationPayload
  • PUT /api/histories/{history_id}/contents/bulk

Feature Triage Summary: Issue #21591

Issue: Batch export of histories, workflow invocations, and datasets Requester: @bernt-matthias Date: 2026-01-15


Top-Line Summary

This feature requests batch export capabilities for histories, invocations, and datasets to file sources. While the issue itself is new (1 reaction), demand analysis reveals this is a 9+ year request with 19+ reactions across related issues (#3195, #2968, #8378). The recommended approach is phased implementation starting with batch history export (~1 week), which has the best existing infrastructure (selection UI, export wizard) and clearest user story (archive all project histories at once). Core maintainer @mvdbeek has already signaled support.


Importance Assessment Summary

Dimension Rating Notes
User Demand Medium-High 1 direct reaction, but 19+ across related 9-year-old issues
Strategic Value Medium-High Aligns with file source ecosystem, reproducibility goals
Effort Large ~3-4 weeks total (3 features), ~1 week for Phase 1 only
Risk Medium Security (rate limiting) and performance (bulk I/O) need attention
Priority Backlog Good feature, phased approach can deliver value incrementally

Key Questions for Discussion

  1. Scope for v1: Should we start with batch history export only, or commit to all three features?

  2. Error handling: If one history fails to export, should the batch abort or continue with others?

  3. Rate limiting: What's an acceptable max batch size? (Suggest 50, configurable)

  4. Progress feedback: Is a simple toast notification sufficient, or do users need a progress bar?

  5. File naming: Use {history_name}_{id}.{format} to avoid collisions, or let users choose structure?

  6. Related issues: Should we link/close older duplicates (#3195, #8378, #18245) when implemented?


Concerns

Scope Creep

The request covers three distinct features. Risk of expanding scope to include:

  • Combined export (all histories in single archive)
  • Scheduled exports
  • Export templates

Mitigation: Explicitly scope v1 to batch-to-directory pattern, one file per item.

Long-term Maintenance

  • Batch operations add complexity to error handling, progress tracking, and resource management
  • Each export type (history, invocation, dataset) needs testing against all file source types

Performance

  • Large batch exports could strain object store I/O and network bandwidth
  • Need configurable limits and potentially staggered execution

Recommended Next Steps

  1. Label: Add backlog (or enhancement if actively considering)
  2. Link: Connect to related issues #3195, #2968, #8378, #18245
  3. Scope decision: Confirm Phase 1 (batch history export) as starting point
  4. Clarify questions: Get input on error handling, rate limits before implementation
  5. Assign: Good candidate for contributor with Galaxy UI/API experience

Documents

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment