Skip to content
Python Basics: Creating and Inspecting ZIP Archives

Python Basics: Creating and Inspecting ZIP Archives

October 11, 2026

Python’s standard-library zipfile module can create a ZIP archive, list its members, and read a selected file without extracting it.

Use Python 3.12 or newer on Linux. The example creates its own small files in a fresh temporary directory. Warning: leaving the TemporaryDirectory context removes that directory and everything inside it.

Create an archive and read it back

Save as demo_zipfile_1.py:

from pathlib import Path
from tempfile import TemporaryDirectory
from zipfile import ZipFile, ZIP_DEFLATED

with TemporaryDirectory() as directory:
    workspace = Path(directory)
    source = workspace / "notes.txt"
    archive = workspace / "bundle.zip"
    with source.open("x", encoding="utf-8") as file:
        file.write("Ready for review\n")

    with ZipFile(archive, "x", compression=ZIP_DEFLATED) as bundle:
        bundle.write(source, arcname="notes.txt")
        bundle.writestr("status.txt", "draft\n")

    with ZipFile(archive, "r") as bundle:
        for member in bundle.infolist():
            print(member.filename, member.file_size)
        print(bundle.read("notes.txt").decode("utf-8"), end="")
        print("CRC check:", bundle.testzip())

Run:

python3 demo_zipfile_1.py

Output:

notes.txt 17
status.txt 6
Ready for review
CRC check: None

Mode "x" creates an archive exclusively and raises FileExistsError if it already exists. Mode "w" would replace an existing archive. arcname controls the path stored inside the ZIP, so the temporary directory name is not included.

ZIP_DEFLATED uses compression and requires Python’s zlib support. file_size is the uncompressed size. The context manager closes the writer before the archive is reopened for reading.

Handle an absent member

read() returns bytes and raises KeyError for a missing name. This independent example keeps the archive in memory.

Save as demo_zipfile_2.py:

from io import BytesIO
from zipfile import ZipFile

with BytesIO() as buffer:
    with ZipFile(buffer, "w") as bundle:
        bundle.writestr("status.txt", "draft\n")
    buffer.seek(0)
    with ZipFile(buffer, "r") as bundle:
        try:
            bundle.read("missing.txt")
        except KeyError:
            print("Member not found")

Run:

python3 demo_zipfile_2.py

Output:

Member not found

testzip() reads all members and returns the first name with a bad CRC or header, or None when it finds none. This checks corruption, not authenticity.

Only use these unrestricted reads on small, trusted archives. Compressed content can expand dramatically, and read() loads a whole member into memory. For outside archives, enforce size and resource limits and review member paths before any extraction. Listing names alone does not make extraction safe.

References

Acknowledgements

This post was created with assistance from AI.

Last updated on