A pragmatic library that transparently redirects Python's standard file operations to FSSpec backends through monkey-patching, enabling existing code to work with any filesystem without modification.
Project description
fsbridge
A pragmatic monkey-patching library that transparently redirects Python's standard file operations to FSSpec backends, allowing existing code to work with any filesystem without modification.
Why fsbridge?
When working with libraries that use Python's standard file operations (open(), os.path, pathlib.Path, etc.), you often need to:
- Redirect file outputs to a different location
- Support cloud storage or other non-local filesystems
- Guarantee atomic file operations
- Handle virtual file paths
Normally, this would require rewriting code to use FSSpec directly. fsbridge eliminates this need by transparently redirecting standard Python file operations to FSSpec backends through monkey-patching.
Installation
pip install fsbridge
Quick Start
from fsbridge import fsbridge_context
# Redirect all operations on paths beginning with '/outputs/' to '/tmp/actual_outputs/'
with fsbridge_context('/tmp/actual_outputs', path_prefix='/outputs/'):
# Standard file operations work as expected, but are redirected
with open('/outputs/results.csv', 'w') as f:
f.write('data,value\n1,2\n')
# Works with pathlib too
from pathlib import Path
output_dir = Path('/outputs/subdir')
output_dir.mkdir(exist_ok=True)
# Even works with os and shutil operations
import os
import shutil
os.makedirs('/outputs/another/nested/dir', exist_ok=True)
shutil.copy('source.txt', '/outputs/destination.txt')
Features
- Transparent redirection: No changes needed to existing code
- Atomic file operations: All write operations are atomic by default
- Comprehensive coverage: Supports
open(),pathlib.Path,os.*,shutil.*, and more - FSSpec compatibility: Works with any FSSpec backend (local, S3, GCS, HTTP, etc.)
- Context-based: Changes are only applied within the context manager
- Customizable: Configure path prefixes, atomic behavior, and more
How It Works
fsbridge uses monkey-patching to intercept standard Python file operations and redirect them to FSSpec. While monkey-patching is generally considered a "dirty" approach, it's used here pragmatically to solve a real problem: allowing existing code to work with any filesystem without modification.
Inside the fsbridge_context:
- Standard Python file operations are monkey-patched
- Operations matching the path prefix are redirected to the specified filesystem
- Write operations are performed atomically through temporary files
- When the context exits, original functions are restored
Advanced Usage
Using with S3 Storage
import s3fs
from fsbridge import fsbridge_context, create_fsspec_fs
# Create an S3 filesystem
s3 = s3fs.S3FileSystem(anon=False)
# Redirect '/outputs/' paths to an S3 bucket
with fsbridge_context('my-bucket/outputs', fs=s3, path_prefix='/outputs/'):
# This will write to S3 atomically
with open('/outputs/results.csv', 'w') as f:
f.write('data,value\n1,2\n')
Customizing Atomic Behavior
from fsbridge import fsbridge_context
with fsbridge_context('/tmp/outputs', path_prefix='/outputs/',
atomic_writes=True, atomic_suffix='.temp',
atomic_prefix='.tmp.'):
# Customize how atomic operations work
with open('/outputs/file.txt', 'w') as f:
f.write('data')
Selective Patching
from fsbridge import fsbridge_context
with fsbridge_context('/tmp/outputs', path_prefix='/outputs/',
patch_open=True, patch_os=True,
patch_pathlib=True, patch_shutil=False):
# Only selected modules will be patched
pass
Explicit Usage (No Monkey-Patching)
from fsbridge import create_fsspec_mapping
# Get a mapped filesystem without monkey-patching
fs = create_fsspec_mapping('/tmp/outputs', path_prefix='/outputs/')
# Use the filesystem explicitly
with fs.open('/outputs/file.txt', 'w') as f:
f.write('data')
Supported Operations
fsbridge redirects the following operations:
- builtins:
open() - pathlib:
Path(),Path.open(),Path.mkdir(), etc. - os:
os.path.exists(),os.makedirs(),os.mkdir(),os.rename(), etc. - os.path:
exists(),isdir(),isfile(), etc. - shutil:
copyfile(),copy(),copy2(),move(), etc.
Limitations
fsbridge has some limitations you should be aware of:
- Performance overhead: The monkey-patching and redirection add some overhead
- Not all operations supported: Some specialized file operations might not work as expected
- Thread safety: Be cautious when using in multi-threaded environments
- C extensions: Python modules implemented in C might bypass the Python-level monkey patching
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- FSSpec for providing the filesystem abstraction
- PyFilesystem2 for inspiration
- pyfakefs for demonstrating effective file operation monkey-patching
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fsbridge-0.1.0.tar.gz.
File metadata
- Download URL: fsbridge-0.1.0.tar.gz
- Upload date:
- Size: 4.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7dcd688d932015b0b0f9b0e2ecefdee85a45ef9a533f314ec7c4bec2bb0de01c
|
|
| MD5 |
f7659d95b4877ca210ed6d39d88ea979
|
|
| BLAKE2b-256 |
93429ca99207310575ab195d3aa8219a198774c00f74ffa625859c7b49e4e536
|
File details
Details for the file fsbridge-0.1.0-py3-none-any.whl.
File metadata
- Download URL: fsbridge-0.1.0-py3-none-any.whl
- Upload date:
- Size: 4.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aecf4dd220e8a53486a67557a176ce76fbd67fdece4a4f9aa9853aa731588117
|
|
| MD5 |
2bcbe674a6a2682d29c171ba773c7293
|
|
| BLAKE2b-256 |
dfe39a6cb3c827824688a7979b0aeedb1f94e258202a4cc7b252bf6532cd8e29
|