Atomic filesystem operations for safe batch processing.
Project description
fs-transaction ๐ก๏ธ
Stop writing corrupted files.
fs-transaction provides Python context managers for atomic, crash-safe file operations. It ensures your file writes are "all-or-nothing," preventing data corruption during crashes, power failures, or concurrent access.
๐ฅ The Problem
In standard Python, writing to a file is risky:
# โ ๏ธ DANGEROUS CODE
with open("database.json", "w") as f:
f.write(start_processing())
# <--- CRASH HERE (Power loss, Exception, OOM)
f.write(finish_processing())
# RESULT: "database.json" is now half-written and corrupted forever.
โ The Solution
fs-transaction uses the Write-Replace Pattern:
- It writes data to a temporary file in the same directory.
- It calls
os.fsync()for crash safety. - It performs an atomic
os.replace()to swap the new file with the old one.
If the script crashes at any point before step 3, your original file remains 100% untouched and valid.
๐ Why use fs-transaction?
| Feature | Standard open() |
fs-transaction |
|---|---|---|
| Atomic Writes | โ No (Partial writes possible) | โ Yes (All or nothing) |
| Crash Safety | โ Low (Data corruption risk) | โ
High (fsync + atomic replace) |
| Concurrency | โ Manual locking required | โ Thread-safe implementation |
| Cleanup | โ Manual try/finally blocks |
โ Automatic temp file cleanup |
| Rollback | โ Not possible | โ Automatic on failure |
| Overwrite Safety | โ Destroys original | โ Backup + restore on failure |
| Ease of Use | ๐ก Native | ๐ข Drop-in replacement |
๐ฆ Installation
pip install fs-transaction
๐ Usage
Quick Start: AtomicWrite
Use AtomicWrite as a drop-in replacement for open() when you need crash-safe single-file writes:
from fs_transaction import AtomicWrite
import json
data = {"status": "processing", "items": [1, 2, 3]}
# Even if this block raises an Exception, 'config.json' will NOT be corrupted.
with AtomicWrite("config.json", mode="w") as f:
f.write(json.dumps(data, indent=2))
print("File written safely and atomically!")
Batch Operations: Transaction
Use Transaction to group multiple file operations into a single atomic unit:
from fs_transaction import Transaction
with Transaction() as t:
t.write("config.json", json.dumps(new_config), overwrite=True)
t.move("data/old.csv", "archive/old.csv")
t.copy("templates/default.yaml", "config/app.yaml")
t.delete("cache/stale.tmp")
# โ
All 4 operations succeed together, or none of them happen.
Overwriting Existing Files
By default, operations raise FileExistsError if the destination exists. Use overwrite=True to safely replace:
# AtomicWrite overwrites by default (like open())
with AtomicWrite("existing_file.txt") as f:
f.write("Updated content")
# Transaction methods require explicit overwrite=True
with Transaction() as t:
t.write("existing_file.txt", "Updated", overwrite=True)
t.copy("src.txt", "existing_dst.txt", overwrite=True)
t.move("new.txt", "existing.txt", overwrite=True)
Dry-Run Mode
Validate all operations without executing them:
with Transaction(dry_run=True) as t:
t.move("important.txt", "archive/important.txt")
t.write("report.txt", generate_report())
# โ
Validation passed, but no files were changed.
Deleting Files Safely
with Transaction() as t:
t.delete("obsolete_config.json")
t.delete("old_data.csv")
# Files are backed up before deletion.
# If something fails, they are restored automatically.
๐ง API Reference
AtomicWrite(path, mode='w', overwrite=True, fsync=True, **kwargs)
Context manager for atomic single-file writes.
| Parameter | Type | Default | Description |
|---|---|---|---|
path |
str | Path |
โ | Target file path |
mode |
str |
'w' |
File open mode ('w', 'wb', etc.) |
overwrite |
bool |
True |
Replace existing files |
fsync |
bool |
True |
Call os.fsync() for crash safety |
**kwargs |
โ | โ | Passed to open() |
Transaction(dry_run=False, fsync=True)
Context manager for batching multiple file operations atomically.
| Parameter | Type | Default | Description |
|---|---|---|---|
dry_run |
bool |
False |
Validate without executing |
fsync |
bool |
True |
Call os.fsync() for crash safety |
Methods:
| Method | Description |
|---|---|
write(dst, content, mode='w', overwrite=False) |
Atomic file write |
move(src, dst, overwrite=False) |
Move/rename a file |
copy(src, dst, overwrite=False) |
Copy a file |
delete(path) |
Delete a file (with backup for rollback) |
commit() |
Manually commit (auto-called on __exit__) |
๐๏ธ Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Transaction โ
โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโ โ
โ โFileMove โ โFileCopy โ โFileWriteโ โFileDel โ โ
โ โโโโโโฌโโโโโ โโโโโโฌโโโโโ โโโโโโฌโโโโโ โโโโโฌโโโโโ โ
โ โ โ โ โ โ
โ โโโโโโผโโโโโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโโโโโผโโโโโ โ
โ โ 1. Validate All โ โ
โ โ 2. Execute All (with backups) โ โ
โ โ 3. Cleanup / Rollback โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ก๏ธ Safety Guarantees
- Atomicity: Operations are committed as a single unit. Partial state is impossible.
- Crash Safety:
os.fsync()ensures data hits disk before the atomic rename. - Backup-Restore: Original files are backed up before overwrite. On failure, they are restored.
- Thread Safety: Internal locking prevents concurrent commits.
- Automatic Cleanup: Temp files are always cleaned up, even on exceptions.
๐ค Contributing
Contributions, issues, and feature requests are welcome!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
See CONTRIBUTING.md for detailed guidelines.
๐ License
This project is licensed under the GNU General Public License v3.0 โ see the LICENSE file for details.
๐ Changelog
See CHANGELOG.md for a list of changes.
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 fs_transaction-0.2.0.tar.gz.
File metadata
- Download URL: fs_transaction-0.2.0.tar.gz
- Upload date:
- Size: 26.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dbc5a745b37190ef8b792a32993195b80f65038606659c18f4c16c3544d9de78
|
|
| MD5 |
808470ea22084b658d13dabb198a6432
|
|
| BLAKE2b-256 |
e5c1d7b29e7cee746be650825ddd08c4ac3df8751b6c3a8cea972475a99b8d84
|
Provenance
The following attestation bundles were made for fs_transaction-0.2.0.tar.gz:
Publisher:
python-publish.yml on SKAUL05/fs-transaction
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fs_transaction-0.2.0.tar.gz -
Subject digest:
dbc5a745b37190ef8b792a32993195b80f65038606659c18f4c16c3544d9de78 - Sigstore transparency entry: 1773331740
- Sigstore integration time:
-
Permalink:
SKAUL05/fs-transaction@49cb0bb5ed6cd152adfe107b73a60a65fd6a993c -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/SKAUL05
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@49cb0bb5ed6cd152adfe107b73a60a65fd6a993c -
Trigger Event:
release
-
Statement type:
File details
Details for the file fs_transaction-0.2.0-py3-none-any.whl.
File metadata
- Download URL: fs_transaction-0.2.0-py3-none-any.whl
- Upload date:
- Size: 22.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c1c33050cefc9bc5811068aa0407e398f319b162a38c902a42c4f5313df87485
|
|
| MD5 |
6dc2f9b973346372f55a3d34fd22ba51
|
|
| BLAKE2b-256 |
495f94a5b2a9de6635957d9681377164ba8f395d2882d7971efb1703b35c1473
|
Provenance
The following attestation bundles were made for fs_transaction-0.2.0-py3-none-any.whl:
Publisher:
python-publish.yml on SKAUL05/fs-transaction
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fs_transaction-0.2.0-py3-none-any.whl -
Subject digest:
c1c33050cefc9bc5811068aa0407e398f319b162a38c902a42c4f5313df87485 - Sigstore transparency entry: 1773331840
- Sigstore integration time:
-
Permalink:
SKAUL05/fs-transaction@49cb0bb5ed6cd152adfe107b73a60a65fd6a993c -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/SKAUL05
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@49cb0bb5ed6cd152adfe107b73a60a65fd6a993c -
Trigger Event:
release
-
Statement type: