{"id":4787,"library":"stream-unzip","title":"Stream-unzip","description":"Stream-unzip is a Python library (version 0.0.101) designed to efficiently decompress ZIP archives without loading the entire file or any of its uncompressed contents into memory. It focuses on streaming capabilities, making it suitable for large files or network-bound operations. The library is actively maintained with regular releases and supports various ZIP formats including Deflate64, Zip64, and both AES and legacy ZipCrypto encryption.","status":"active","version":"0.0.101","language":"en","source_language":"en","source_url":"https://github.com/uktrade/stream-unzip","tags":["zip","streaming","archive","compression","memory-efficient"],"install":[{"cmd":"pip install stream-unzip","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"stream_unzip","correct":"from stream_unzip import stream_unzip"}],"quickstart":{"code":"import httpx\nimport os\nfrom stream_unzip import stream_unzip\n\ndef get_zipped_chunks(url):\n    # Ensure httpx is installed: pip install httpx\n    # Example URL for a small test zip if not set:\n    # url = url or 'https://www.learningcontainer.com/wp-content/uploads/2020/07/sample-zip-file.zip'\n    with httpx.stream('GET', url, follow_redirects=True) as r:\n        r.raise_for_status()\n        yield from r.iter_bytes(chunk_size=65536)\n\ndef main():\n    # Replace with a real ZIP file URL or use a local file stream\n    zip_url = os.environ.get('STREAM_UNZIP_TEST_URL', 'https://www.learningcontainer.com/wp-content/uploads/2020/07/sample-zip-file.zip')\n    print(f\"Downloading and unzipping from: {zip_url}\")\n    for file_name, file_size, unzipped_chunks in stream_unzip(get_zipped_chunks(zip_url)):\n        print(f\"\\nProcessing file: {file_name.decode('utf-8')} (Size: {file_size if file_size is not None else 'Unknown'} bytes)\")\n        total_unzipped_bytes = 0\n        # IMPORTANT: unzipped_chunks *must* be iterated to completion\n        for chunk in unzipped_chunks:\n            total_unzipped_bytes += len(chunk)\n            # Process the chunk, e.g., write to disk or another stream\n            # print(f\"  Read {len(chunk)} bytes from {file_name.decode('utf-8')}\")\n        print(f\"  Finished reading {total_unzipped_bytes} bytes for {file_name.decode('utf-8')}\")\n\nif __name__ == '__main__':\n    main()","lang":"python","description":"This quickstart demonstrates how to stream-unzip a ZIP file downloaded via HTTPX. The `stream_unzip` function takes an iterable of bytes (representing the ZIP archive) and yields tuples for each file: `(file_name, file_size, unzipped_bytes_generator)`. The `unzipped_bytes_generator` for each file *must* be iterated to completion to avoid `UnfinishedIterationError`."},"warnings":[{"fix":"Upgrade your Python environment to 3.7.7 or newer to use current versions of `stream-unzip`.","message":"Support for Python 3.6 was dropped in version 0.0.96. Additionally, support for earlier versions of Python 3.7 was dropped in version 0.0.100.","severity":"breaking","affected_versions":">=0.0.96, >=0.0.100"},{"fix":"Always iterate through all chunks yielded by the `unzipped_chunks` generator, even if you don't need the data (e.g., `for _ in unzipped_chunks: pass`).","message":"The `unzipped_chunks` generator yielded for each file *must* be fully consumed (iterated to completion). Failing to do so will result in an `UnfinishedIterationError`.","severity":"gotcha","affected_versions":"All"},{"fix":"Upgrade to version 0.0.97 or newer to avoid import issues.","message":"Version 0.0.96 had a 'missing main import' bug which could lead to `ImportError`. This was fixed in version 0.0.97.","severity":"gotcha","affected_versions":"0.0.96"},{"fix":"Be aware of this architectural choice when processing non-standard or potentially corrupted ZIP files. For such cases, a traditional `zipfile` module approach might be more robust if full file availability is not an issue.","message":"The library processes ZIP entries as they are read and does not rely on the central directory (which is at the end of a ZIP file). While this enables true streaming, it may lead to edge cases or failures with malformed or unusual ZIP archives that depend on the central directory for critical metadata.","severity":"gotcha","affected_versions":"All"},{"fix":"Sanitize or validate file names and sizes before using them, especially when writing to a file system or displaying to users.","message":"The file name and file size values extracted from the ZIP archive should be treated as untrusted input, as they are provided by the ZIP file's creator and could be malicious.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}