Explain Codes LogoExplain Codes Logo

How to create a zip archive of a directory?

python
zipfile
advanced-usage
python-modules
Anton ShumikhinbyAnton Shumikhin·Sep 24, 2024
TLDR

Looking for a speedy zip? shutil.make_archive() is your Pythonic wand!:

import shutil # "Poof!" and your directory is zipped shutil.make_archive('output_filename', 'zip', 'directory_path')

Substitute 'output_filename' with the preferred zip file name (extension not required), and 'directory_path' with the directory's path to be compressed and voila, you've got your output_filename.zip file.

Advanced usage

Low-level control with zipfile

Craving for more control over the compression process? From setting compression levels to including/excluding files, the zipfile module aids you in bending the rules:

import os import zipfile def zipdir(path, ziph): # ziph the zipper, zips the directory, preserving its structure for root, dirs, files in os.walk(path): for file in files: filePath = os.path.join(root, file) ziph.write(filePath, os.path.relpath(filePath, start=path)) # ZIP_DEFLATED is the deflate gate in the world of zips with zipfile.ZipFile('output_filename.zip', 'w', zipfile.ZIP_DEFLATED) as zipf: zipdir('directory_path', zipf)

zipfile.ZipFile gives you an array of options to specify the compression mode and in teamwork with os.path.join during an os.walk(), a zipped replica of your directory structure is ready!

Running zipped Python applications

Python 3.5+ has gifted us the capability to bundle and run applications directly from a .pyz archive using the zipapp module:

# Makes an archive from a Python application and outputs a .pyz file python -m zipapp myapp -o myapp.pyz # Runs the bundled application python myapp.pyz

Creating zips on different platforms like Cygwin? A root_dir='.' protects the consistency of path format across platforms:

shutil.make_archive('output_filename', 'zip', root_dir='.', base_dir='directory_path')

Parent directory exclusion in zipping

Keen on creating a zip archive that omits the parent directory of the files?

python -m zipfile -c output_filename.zip directory_path/*

Zipping Python packages for distribution

When zipping a Python package for distribution, slap an __init__.py in there and, if your package doubles as an executable, stick a __main__.py in there too:

shutil.make_archive('my_package', 'zip', root_dir='.', base_dir='my_package')

Best practices, gotchas, and "Trapzillas"

Make sure to "seal the deal" - Finalize your archive

Don't forget to call zf.close() to ensure the zip gate is locked, safeguarding your archive content from corruption.

News-Flash! Out-of-the-box, zipfile will ignore symbolic links and will only include regular files in the zip directory. If this is not ideal, gird your loins and get ready to write additional code to handle symbolic links.

Shortcut to creating archives via command-line

Why write a script when you can pop a one-liner command right from your terminal?

python -m zipfile -c output_filename.zip directory_path