Smart archive inspection and extraction: OS-artifact cleanup, recursive unpacking, type detection, and selective extraction over ZIP/tar.
Project description
zipmonkey
Smart archive inspection and extraction. Collapses the repetitive zipfile /
tarfile boilerplate into one clean API: auto-clean OS junk, inspect without
extracting, selective extraction, flattening, recursive unpacking of nested
archives, and magic-byte type detection — with a CLI on top.
Part of the *monkey toolkit. MIT licensed.
Install
pip install zipmonkey
# optional backends:
pip install zipmonkey[sevenzip] # .7z support (py7zr)
pip install zipmonkey[rar] # .rar support (rarfile)
Core features need only the standard library. Requires Python 3.11+.
Why
Users upload ZIPs full of nested ZIPs, mixed file types, Mac __MACOSX
garbage, and inconsistent structure. You end up writing the same zipfile
loop — strip junk, handle nesting, detect types, clean up temp dirs — every
time. zipmonkey is that loop, done once, opinionated.
Quick start
import zipmonkey
# Inspect without extracting.
report = zipmonkey.inspect("bundle.zip")
print(report.format, report.file_count, report.total_size)
for e in report.entries:
print(e.name, e.detected_type, e.is_artifact)
# Extract with automatic temp-dir cleanup.
with zipmonkey.open("bundle.zip") as arc:
result = arc.extract() # temp dir, cleaned on exit
print(result.count, "files ->", result.dest)
# Selective + recursive extraction to a directory you own.
zipmonkey.extract("bundle.zip", "out", include="*.csv", recursive=True)
# Walk extracted files tagged for dispatch.
for tf in zipmonkey.walk_typed("bundle.zip", "out"):
print(tf.path.name, tf.detected_type, tf.category)
What it handles for you
- Strips
__MACOSX/,.DS_Store, AppleDouble._*,Thumbs.db,desktop.ini. - Detects archive formats by magic bytes (a mislabelled archive still opens), with extension fallback for ambiguous document/text types (CSV, JSON, xlsx — see
LIMITATIONS.md). - Unpacks nested archives (zip-in-zip, tar.gz-in-zip) with depth and size caps.
- Skips path-traversal (
..) members; re-roots absolute paths under the destination. - Flattens to one directory, renaming basename collisions (
name (1).ext). - Filters with
include/excludeglobs (matched against full path and basename).
Formats
ZIP, tar, tar.gz, tar.bz2, tar.xz, standalone gzip/bzip2/xz files, plus 7z and rar when the optional extras are installed.
Streaming-safety note. The decompression-bomb caps are enforced while streaming for the stdlib-backed formats (ZIP/tar/gzip/bzip2/xz) and rar. The optional 7z backend materialises each member in memory before writing (py7zr has no streaming API); a declared-size preflight rejects oversized members before decompression, but peak memory for an honestly-declared large 7z member is proportional to its size. Apply a small
max_total_bytes(or your own preflight) for untrusted large 7z archives. SeeLIMITATIONS.md.For untrusted input prefer
extract()(streamed, capped) overread()/open_member(), which return whole members and do not apply the caps. Noteinspect()on a standalone.gz/.bz2/.xzstreams the whole payload to report its uncompressed size (memory-safe, but not free) — seeLIMITATIONS.md.
CLI
zipmonkey inspect bundle.zip # summary + per-file table
zipmonkey tree bundle.zip # indented content tree
zipmonkey extract bundle.zip out --include "*.csv" --recursive --flat
# safety caps and overwrite are flags (0 disables a cap):
zipmonkey extract big.zip out --max-total-bytes 0 --max-files 0 --max-depth 0 --no-overwrite
Pairs well with
Extracted files usually need more processing — dispatch on TypedFile.category:
tabular(CSV/TSV) ->dsvmonkeypdf->pdfmonkeyexcel->xldetect+xlfilldown
Security model
zipmonkey is built to handle untrusted/hostile archives safely. For that:
- Use
extract()for untrusted input. It streams undermax_total_bytes, caps the file count (max_files), bounds nesting (max_depth), strips OS junk, skips path-traversal members and symlinks/devices, and resolves symlinked destination prefixes.read()andopen_member()are convenience APIs that return whole members and do not apply these caps — use them only on trusted or already-bounded members. - Optional 7z materialises members in memory (py7zr has no streaming API),
guarded by a declared-size preflight. Apply a small
max_total_bytesfor untrusted large 7z. - Not race-proof against a hostile filesystem. Path checks assume
destis a directory only you write to (extract into a fresh private dir). The threat model is malicious archives, not another process mutatingdestmid-extraction. SeeLIMITATIONS.md.
Using with AI assistants
This repository includes a SKILL.md at its root (also bundled in the sdist via
MANIFEST.in) with an LLM-oriented decision tree, worked examples, and a
"don't" list. See LIMITATIONS.md for deliberate design tradeoffs (e.g. why tar
archives show a 0.00 compression ratio).
License
MIT — see LICENSE.
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 zipmonkey-1.0.0.tar.gz.
File metadata
- Download URL: zipmonkey-1.0.0.tar.gz
- Upload date:
- Size: 64.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f9bb4a5de509cb04493495131402dd9cb36af1f48a8ec3ed62bcecdba04fab8
|
|
| MD5 |
3687d28b38a5b730825183041120d7fc
|
|
| BLAKE2b-256 |
b9c8f662e385016138a03db53de1a612a2601ad824ae040d4731d2c48e5222de
|
File details
Details for the file zipmonkey-1.0.0-py3-none-any.whl.
File metadata
- Download URL: zipmonkey-1.0.0-py3-none-any.whl
- Upload date:
- Size: 36.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d8b4ef56af5149fe87b75823f7abbf27a649dc3a4e55b7b53184035358ddfd88
|
|
| MD5 |
d140e858f7630defc7e7a524e5f98159
|
|
| BLAKE2b-256 |
f8c756c6d8cff21fe309edc0b1160d37d78f722cc0b784866d51a3da996164e5
|