A flexible file versioning system with compression support
Project description
py-file-versioning
A flexible file versioning system with compression support, written in Python.
Table of Contents
Features
- Create versioned backups of files with automatic sequence numbering
- Multiple compression options: gzip, bzip2, xz, or uncompressed
- Configurable timestamp formats (UTC or local time)
- Limit the number of versions kept per file
- Command-line interface for easy integration
- Support for Unicode filenames
- Cross-platform compatibility
Package Name Convention
While the package is installed as py-file-versioning (using hyphens), you should use py_file_versioning (using underscores) in your Python imports following Python naming conventions.
Installation
From PyPI
pip install py-file-versioning
From Source
git clone https://github.com/jftuga/py-file-versioning.git
cd py-file-versioning
pip install .
For development installation:
uv venv
source .venv/bin/activate
uv pip install -e '.[dev]'
uv pip list
Command Line Usage
The package installs a command-line tool called pyfileversioning. Here are some common operations:
Create a version:
pyfileversioning create myfile.txt
Create a compressed version:
pyfileversioning create myfile.txt -c gz # or --compression gz
List all versions:
pyfileversioning list myfile.txt
Restore a specific version to a new file path:
pyfileversioning restore versions/myfile--20240120.123456_001.txt.gz --target /path/to/restored_file.txt
Remove a version:
pyfileversioning remove versions/myfile--20240120.123456_001.txt.gz
Demo Shell Session
Here's a practical demonstration of using the command-line interface:
# Create a sample config file
$ echo "database_host=localhost" > config.ini
$ cat config.ini
database_host=localhost
# Create first version (uncompressed)
$ pyfileversioning create config.ini -d backups
Created version: backups/config--20250207.044841_001--loc_mod.ini
# Update the file content
$ echo "database_port=5432" >> config.ini
# Create compressed version
$ pyfileversioning create config.ini -d backups -c gz
Created version: backups/config--20250207.044924_001--loc_mod.ini.gz
# List all versions
$ pyfileversioning list config.ini -d backups
Path | Sequence | Size | Timestamp | TimeZone | TimestampSrc
==== | ======== | ==== | ========= | ======== | ============
config--20250207.044924_001--loc_mod.ini.gz | 1 | 95 | 2025-02-07T04:49:24 | local | modify time
config--20250207.044841_001--loc_mod.ini | 1 | 24 | 2025-02-07T04:48:41 | local | modify time
# Add more content and create another version with UTC time
$ echo "database_name=myapp" >> config.ini
$ pyfileversioning create config.ini -d backups -c gz -u
Created version: backups/config--20250207.095009_001--utc_mod.ini.gz
# View all versions with size and timestamp (note: mixed timezone versions not recommended)
$ pyfileversioning list config.ini -d backups
Path | Sequence | Size | Timestamp | TimeZone | TimestampSrc
==== | ======== | ==== | ========= | ======== | ============
config--20250207.095009_001--utc_mod.ini.gz | 1 | 107 | 2025-02-07T09:50:09 | utc | modify time
config--20250207.044924_001--loc_mod.ini.gz | 1 | 95 | 2025-02-07T04:49:24 | local | modify time
config--20250207.044841_001--loc_mod.ini | 1 | 24 | 2025-02-07T04:48:41 | local | modify time
Python API Usage
The library provides a flexible API for file versioning. Here's how to use it:
from py_file_versioning import FileVersioning, FileVersioningConfig
# Create a test file
def create_example_file(filename: str) -> None:
content = """
# Database configuration settings
db_host = db.example.com
db_port = 5432
db_name = production_db
""".strip()
with open(filename, 'w') as f:
f.write(content)
# Basic usage
filename = "example.ini"
create_example_file(filename)
versioning = FileVersioning()
version_path, removed, error = versioning.create_version(filename)
if error:
print(f"Warning: {error}")
print(version_path)
# Advanced configuration
config = FileVersioningConfig(
versions_path="backups", # Store versions in 'backups' directory
compression="gz", # Use gzip compression
max_versions=5, # Keep only last 5 versions
use_utc=True, # Use UTC timestamps
use_modified_time=True, # Use file's modified time
delimiter="__" # Custom delimiter for version files
)
versioning = FileVersioning(config)
version_path, removed, error = versioning.create_version(filename)
if error:
print(f"Warning: {error}")
print(version_path)
Configuration Options
FileVersioningConfig Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| delimiter | str | "--" | Separator between filename and version information |
| use_utc | bool | False | Use UTC timestamps instead of local time |
| versions_path | str | "versions" | Directory to store versions |
| compression | str | "none" | Compression type: "none", "gz", "bz2", "xz" |
| max_versions | Optional[int] | None | Maximum number of versions to keep |
| use_modified_time | bool | True | Use file's modified time instead of current time |
Command Line Options
usage: pyfileversioning [-h] [-V] [-t TARGET] [-d VERSIONS_PATH]
[-c {none,gz,bz2,xz}] [-m MAX_VERSIONS] [-s {mod,sto}]
[-u] [-D DELIMITER]
[{create,restore,list,remove}] files [files ...]
Options:
-V, --version: Show version information-t, --target: Target file path for restore operation (must be full path to the restored file)-d, --versions-path: Directory to store versions (default: versions)-c, --compression: Compression type to use (none, gz, bz2, xz)-m, --max-versions: Maximum number of versions to keep-s, --src: Source for timestamps (mod: file modified time, sto: current time)-u, --utc: Use UTC timezone for timestamps (default: local time)--delimiter DELIMITER: The delimiter to use (default: --)
Environment Variables:
PFV_VERSIONS_PATH: Override default versions directoryPFV_COMPRESSION: Override default compression typePFV_DELIMITER: Override default delimiter
Notes:
- The tool supports file patterns (e.g.,
*.txt,config*.ini) - Multiple files can be specified for batch operations
Examples
Maintaining Multiple Versions
from py_file_versioning import FileVersioning, FileVersioningConfig
# Create versions with different timezone and timestamp combinations
configs = [
# Local timezone versions
{"use_utc": False, "use_modified_time": True, "desc": "local timezone, modified time"},
{"use_utc": False, "use_modified_time": False, "desc": "local timezone, current time"},
# UTC timezone versions
{"use_utc": True, "use_modified_time": True, "desc": "UTC timezone, modified time"},
{"use_utc": True, "use_modified_time": False, "desc": "UTC timezone, current time"}
]
for cfg in configs:
config = FileVersioningConfig(
use_utc=cfg["use_utc"],
use_modified_time=cfg["use_modified_time"]
)
versioning = FileVersioning(config)
version_path, removed, error = versioning.create_version("example.ini")
print(version_path)
Using Different Compression Types
from py_file_versioning import FileVersioning, FileVersioningConfig
# Create versions using each compression type
compression_types = ["gz", "bz2", "xz"]
for compression in compression_types:
config = FileVersioningConfig(
compression=compression,
use_utc=True, # Use UTC time
use_modified_time=True # Use file's modified time
)
versioning = FileVersioning(config)
version_path, removed, error = versioning.create_version("example.ini")
print(version_path)
Version File Naming
Version files follow this naming pattern:
{original_name}{delimiter}{timestamp}_{sequence}{delimiter}{version_spec}{extension}[.compression_ext]
Example:
myfile--20240120.123456_001--utc_mod.txt.gz
Where:
myfileis the original filename--is the delimiter (configurable)20240120.123456is the timestamp (YYYYMMDD.HHMMSS)001is the sequence numberutc_modis the version specification:- First part (
utcorloc) indicates timezone (UTC or local) - Second part (
modorsto) indicates timestamp source (modified time or stored/current time)
- First part (
.txtis the original extension.gzis the compression extension (if compression is used)
Note: All versions of a file must use consistent timezone and timestamp source settings.
Development
Setting Up Development Environment
# Clone the repository
git clone https://github.com/jftuga/py-file-versioning.git
cd py-file-versioning
# Create and activate virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install development dependencies
pip install -e '.[dev]'
Running Tests
pytest
For coverage report:
pytest --cov=file_versioning --cov-report=html
Code Quality Checks
# Format code
black .
# Sort imports
isort .
# Style checking
flake8
# Linting
ruff check
License
This project is licensed under the MIT License - see the LICENSE file for details.
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 Distributions
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 py_file_versioning-0.10.0-py3-none-any.whl.
File metadata
- Download URL: py_file_versioning-0.10.0-py3-none-any.whl
- Upload date:
- Size: 16.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eec3f40044def2d738eb8732b2eb578b748bbe688fafd285df3af077178510d2
|
|
| MD5 |
bc2b3e59bbae818677d183f20c0fa18b
|
|
| BLAKE2b-256 |
7f234f56f163ca56a49f1576e2a0f43df9df2a21860131a8f883c7836b63087f
|