How to Create ZIP Archives of Directories in Python
Creating ZIP archives of directories is a common task for packaging files, creating backups, or sharing data.
This guide explores how to create ZIP archives of directories in Python, covering the simple and recommended shutil.make_archive()
method and the more detailed zipfile
module for granular control. We'll also touch on using the command line and the zipapp
module for creating executable Python archives.
Creating ZIP Archives with shutil.make_archive()
(Recommended)
The shutil.make_archive()
function provides the simplest and most convenient way to create ZIP archives (and other archive formats) of entire directories:
import shutil
path_to_dir = './my-directory'
output_filename = 'my-zip' # No extension needed here
shutil.make_archive(output_filename, 'zip', path_to_dir)
print('Zip archive of directory created.') # Output: Zip archive of directory created.
shutil.make_archive(base_name, format, root_dir)
:base_name
: The name of the archive file without the extension (e.g., 'my-zip'). The extension is added automatically based on the format.format
: The archive format. Common options include:'zip'
(requires thezlib
module, which is almost always available)'tar'
'gztar'
(gzip-compressed tar, requireszlib
)'bztar'
(bzip2-compressed tar, requiresbz2
)'xztar'
(xz-compressed tar, requireslzma
)
root_dir
: The directory to archive. All paths within the archive will be relative to this directory.
- The return value of
make_archive
is the path to the archive file.
Creating ZIP Archives with zipfile
(Advanced Control)
The zipfile
module gives you fine-grained control over the ZIP archive creation process. This is useful if you need to:
- Exclude specific files or directories.
- Set custom compression levels.
- Add files individually, rather than an entire directory.
Here's an example of recursively zipping a directory with zipfile
:
import os
import zipfile
def zip_directory(path, zip_file_handle):
for root, _dirs, files in os.walk(path):
for file in files:
zip_file_handle.write(
os.path.join(root, file),
os.path.relpath(
os.path.join(root, file),
os.path.join(path, '..')
)
)
print(f'Directory {path} zipped successfully')
path_to_dir = './my-directory'
output_filename = 'my-zip.zip'
with zipfile.ZipFile(
output_filename,
'w',
zipfile.ZIP_DEFLATED) as zip_file: # Use ZIP_DEFLATED for compression.
zip_directory(path_to_dir, zip_file)
zipfile.ZipFile(output_filename, 'w', zipfile.ZIP_DEFLATED)
: Opens (or creates) a ZIP file in write mode ('w'
) with DEFLATED compression (requires thezlib
module). You can also usezipfile.ZIP_STORED
for no compression.os.walk(path)
: This efficiently walks through the directory tree, yielding tuples of(root, dirs, files)
for each subdirectory.zip_file_handle.write(...)
: This adds a file to the archive. The important part is calculating the correct archive name (the path within the ZIP file).os.path.relpath()
is used to make the paths relative to the directory being zipped.
Using pathlib
with zipfile
Using pathlib
simplifies the path management with zipfile
.
import zipfile
from pathlib import Path
def zip_directory(directory, filename):
directory = Path(directory)
with zipfile.ZipFile(
filename, "w", zipfile.ZIP_DEFLATED
) as zip_file:
for entry in directory.rglob("*"): # rglob for recursive
zip_file.write(entry, entry.relative_to(directory))
print('Zip archive created successfully')
path_to_dir = './my-directory'
output_filename = 'my-zip.zip'
zip_directory(path_to_dir, output_filename)
- The
pathlib
module is used to generate file paths, and to get relative paths. - This is a cleaner approach that avoids using
os.path
methods.
Creating ZIP Archives from the Command Line
You can create ZIP archives directly from the command line using Python's built-in zipfile
module:
python -m zipfile -c my-zip.zip my-directory # Include the my-directory itself
python -m zipfile -c my-zip.zip my-directory/* # Exclude the parent my-directory
-m zipfile
: Runs thezipfile
module as a script.-c
: Specifies that you want to create an archive.my-zip.zip
: The name of the output ZIP file.my-directory
: The directory to archive. Usingmy-directory/*
includes the contents ofmy-directory
but not the directory itself in the archive.
Creating Executable Archives with zipapp
The zipapp
module (introduced in Python 3.5) allows you to create executable Python applications packaged as ZIP files:
python -m zipapp my_application # Creates my_application.pyz
python my_application.pyz # Runs the application
- The
zipapp
creates a single file that contains all code for the application. - This approach is used to create standalone applications using Python.
You can also specify the function to be invoked when you run the .pyz
file:
python -m zipapp myapp -m "myapp:main"
python myapp.pyz
- In this case, the python interpreter will run the
main
function inside themyapp
directory.