Compression Tool (Huffman Coding in Pure Python)
A lightweight, fully tested Huffman compression library with both byte-level and file-level APIs.
This project implements a complete Huffman compression pipeline from scratch, including:
- Frequency counting
- Min-heap construction
- Huffman tree generation
- Code map building
- Bit packing/unpacking
- Header encoding/decoding
- High-level compression & decompression
- File-based compressor and decompressor
- Full test suite (unit + integration)
The goal is to provide a clear, modular reference implementation that is easy to study, extend, and reuse — including on a future demo page.
✨ Features
- 🔧 Pure Python implementation
- 🧪 Fully tested with pytest
- 📄 File compression support
- 🔁 Round-trip safe
- 📦 Simple API:
compress_bytes(data: bytes) -> bytesdecompress_bytes(data: bytes) -> bytescompress_file(path) -> CompressionResultdecompress_file(path) -> DecompressionResult
- 🧩 Modular internal structure
- 📦 Published as a PyPI package
📦 Installation
Install from PyPI:
pip install jv-compression-tool
Then:
import compression_tool
🧩 Usage
1. Compressing bytes
from compression_tool import compress_bytes, decompress_bytes
data = b"hello world"
compressed = compress_bytes(data)
restored = decompress_bytes(compressed)
assert restored == data
2. Compressing files
from compression_tool import compress_file, decompress_file
result = compress_file("example.txt")
print("Original size:", result.original_size)
print("Compressed size:", result.compressed_size)
decomp = decompress_file(result.output_path)
assert decomp.output_path.read_bytes() == Path("example.txt").read_bytes()
The file APIs return simple dataclasses:
CompressionResultDecompressionResult
🧱 Project Structure
The project uses a src/ layout for clean packaging:
jv_compression_tool/
├── pyproject.toml
├── README.md
├── LICENSE
├── src/
│ └── compression_tool/
│ ├── __init__.py
│ ├── compressor.py
│ ├── decompressor.py
│ ├── file_compressor.py
│ ├── file_decompressor.py
│ ├── frequency.py
│ ├── tree.py
│ ├── build_tree.py
│ ├── code_map.py
│ ├── lookup.py
│ ├── header.py
│ └── utils/
│ ├── heapify.py
│ └── bitutils.py
└── tests/
├── test_header.py
├── test_heapify.py
├── test_build_tree.py
├── test_compressor.py
├── test_decompressor.py
├── test_file_io.py
└── data/
└── test.txt
(Test file names are illustrative — your exact structure may differ.)
🔍 Header Format
This project currently uses a simple text-based header:
HUF1|pad=<pad_len>|freq=symbol:weight,...|
HUF1– Magic string + version tagpad– Number of padding bits added to the final bytefreq– A comma-separated table of<symbol>:<weight>- Symbols use their integer byte value (e.g.
104=b"h")
Example
HUF1|pad=3|freq=104:1,101:1,108:3,111:2|
A more compact binary header format may be introduced later.
🛠 Development
To set up a local development environment:
git clone https://github.com/JesseVahlfors/jv_compression_tool.git
cd jv_compression_tool
python -m venv .venv
.\.venv\Scripts\activate # or: source .venv/Scripts/activate
pip install -r requirements.txt
pip install -e .
🧪 Testing
Run all tests:
pytest
Run fast tests only (skipping slow ones):
pytest -m "not slow"
Slow tests (e.g., using a large “Les Misérables” file) are marked:
@pytest.mark.slow
@pytest.mark.skipif(not RUN_SLOW_TESTS, reason="Slow test disabled")
📈 Performance Notes
Huffman compression works best when:
- Input is large
- Symbol distribution is uneven
- Repetition exists in the data
Small files may grow slightly due to header overhead — this is expected.
🗺 Future Improvements
- CLI tool (e.g.,
huff compress file.txt) - Binary header format
- Streaming compression
- Web/demo integration
📜 License
Licensed under the MIT License.
Metadata
Release files for jv-compression-tool 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jv_compression_tool-0.1.2.tar.gz | 19.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jv_compression_tool-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 35.4 kB
Release files / jv_compression_tool-0.1.2.tar.gz
| Download URL | jv_compression_tool-0.1.2.tar.gz |
|---|---|
| Size | 19.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c644310b9a280400022fe6b534d64022e6249be40a84849056dc85efac3593ef
|
|
BLAKE2b-256 checksum How to use checksums |
c0f8b2bc692a2ffc2a80ff0d9f0ccad03c4506abe8b6bc9819304ec4ba7fc05a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.1
|
Release files / jv_compression_tool-0.1.2-py3-none-any.whl
| Download URL | jv_compression_tool-0.1.2-py3-none-any.whl |
|---|---|
| Size | 16.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e7dc1aec81cf697c09093b0b706fcf970de3cd7f69da82fd3871419ac439a6a6
|
|
BLAKE2b-256 checksum How to use checksums |
f596c5efb449d7fbd1f00937b175d9f2bfa9ebff99aebd1c2aa8365bfe697819
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.1
|