Skip to content

feat: Add pluggable cloud transfer system with scheme-based dispatch#24

Merged
tomdurrant merged 5 commits intomainfrom
transfer_entrypoint
Feb 18, 2026
Merged

feat: Add pluggable cloud transfer system with scheme-based dispatch#24
tomdurrant merged 5 commits intomainfrom
transfer_entrypoint

Conversation

@tomdurrant
Copy link
Contributor

Summary

This PR introduces a new pluggable transfer system that enables multi-destination file transfers with scheme-based dispatch. The implementation uses cloudpathlib to support various cloud storage protocols.

Changes

Core Features

  • TransferManager: Orchestrates multi-destination file transfers
  • Scheme-based dispatch: Automatically routes transfers based on URI scheme (s3://, gs://, az://, http://, https://, etc.)
  • Cloudpath integration: Leverages cloudpathlib for cloud storage operations
  • Oceanum support: Dedicated handler for Oceanum data platform

New Modules

  • src/rompy/transfer/: Complete transfer subsystem
    • base.py: Abstract base classes and interfaces
    • manager.py: TransferManager implementation
    • registry.py: Scheme-based handler registry
    • cloud.py: Cloud storage handlers (S3, GCS, Azure)
    • file.py: Local file system transfers
    • http.py: HTTP/HTTPS transfers
    • oceanum.py: Oceanum platform integration
    • utils.py: Utility functions including join_prefix
    • exceptions.py: Custom exception classes

Tests

  • Comprehensive test coverage (9 new test files, ~1300 lines)
  • Unit tests for all transfer handlers
  • Integration-style tests for TransferManager
  • Mock-based testing for cloud operations

Refactoring

  • Updated src/rompy/core/data.py to integrate with new transfer system
  • Removed ~80 lines of legacy transfer code

Files Changed

21 files changed, 2053 insertions(+), 80 deletions(-)

Commits

  • 2aa600f: Added cloudpath based cloud transfer protocols
  • aa1e641: Implement TransferManager for multi-destination file transfers
  • 04a36a4: Add TransferManager types and join_prefix utility
  • 2f4d166: add to gitignore
  • 379fdb6: feat: add pluggable transfer system with scheme-based dispatch

Replaces DataBlob's tight coupling to AnyPath and HTTP with a flexible
transfer plugin system supporting file://, http://, https://, and oceanum://
schemes via entry points.

Core Infrastructure:
- TransferBase: Abstract interface for get/exists/list/put/delete/stat operations
- Registry: Loads transfer plugins via importlib.metadata.entry_points()
- get_transfer(): Dispatches to appropriate transfer based on URI scheme
- parse_scheme(): Normalizes scheme handling (case-insensitive, empty->file)
- UnsupportedOperation: Exception for unavailable operations on a scheme

Built-in Transfer Implementations:
- FileTransfer: Local filesystem operations (copy/symlink + full CRUD)
- HttpTransfer: HTTP/HTTPS downloads (delegates to existing http_handler)
- OceanumTransfer: Oceanum DataMesh operations via fsspec

DataBlob Integration:
- Refactored DataBlob.get() to use transfer registry (80 lines -> 12 lines)
- Removed HttpUrl type constraint, now accepts plain str URIs
- Maintains backwards compatibility with AnyPath inputs
- Preserves link=True semantics for local files

Entry Points:
- Declared in pyproject.toml: file, http, https (->http), oceanum
- Plugins loaded at runtime via importlib.metadata

Tests:
- 48 new transfer-specific tests (registry, file, http, oceanum)
- Updated DataBlob HTTP tests to accept str type instead of HttpUrl
- All tests use mocking for external services (respx for HTTP, fsspec mocks)
- Add TransferManager class with transfer_files signature
- Add TransferFailurePolicy enum (CONTINUE, FAIL_FAST)
- Add TransferItemResult and TransferBatchResult dataclasses
- Implement join_prefix() utility for URI/path joining
- Add comprehensive tests for join_prefix()

Part of Wave 1 (Tasks 2-3) for WW3 output transfer postprocessor.
Add TransferManager.transfer_files() supporting fan-out to multiple
destination prefixes with configurable failure policies (CONTINUE/FAIL_FAST).

Changes:
- Implement transfer_files() with sequential file→destination fan-out
- Use get_transfer() for backend resolution and join_prefix() for URIs
- Record detailed TransferItemResult for each operation
- Add TransferBatchResult.all_succeeded() convenience method
- Export TransferManager types in public API
- Add comprehensive tests covering success and failure scenarios

All tests passing (6/6 for TransferManager, 8/8 for join_prefix).
@tomdurrant tomdurrant merged commit 78878a1 into main Feb 18, 2026
1 check 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.

1 participant