Skip to main content

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 / exclude globs (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. See LIMITATIONS.md.

For untrusted input prefer extract() (streamed, capped) over read() / open_member(), which return whole members and do not apply the caps. Note inspect() on a standalone .gz/.bz2/.xz streams the whole payload to report its uncompressed size (memory-safe, but not free) — see LIMITATIONS.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:

Security model

zipmonkey is built to handle untrusted/hostile archives safely. For that:

  • Use extract() for untrusted input. It streams under max_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() and open_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_bytes for untrusted large 7z.
  • Not race-proof against a hostile filesystem. Path checks assume dest is a directory only you write to (extract into a fresh private dir). The threat model is malicious archives, not another process mutating dest mid-extraction. See LIMITATIONS.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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zipmonkey-1.0.0.tar.gz (64.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

zipmonkey-1.0.0-py3-none-any.whl (36.3 kB view details)

Uploaded Python 3

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

Hashes for zipmonkey-1.0.0.tar.gz
Algorithm Hash digest
SHA256 7f9bb4a5de509cb04493495131402dd9cb36af1f48a8ec3ed62bcecdba04fab8
MD5 3687d28b38a5b730825183041120d7fc
BLAKE2b-256 b9c8f662e385016138a03db53de1a612a2601ad824ae040d4731d2c48e5222de

See more details on using hashes here.

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

Hashes for zipmonkey-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d8b4ef56af5149fe87b75823f7abbf27a649dc3a4e55b7b53184035358ddfd88
MD5 d140e858f7630defc7e7a524e5f98159
BLAKE2b-256 f8c756c6d8cff21fe309edc0b1160d37d78f722cc0b784866d51a3da996164e5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page