The zipfile module creates, reads, and extracts ZIP archives. No external tools needed.
Reading ZIP Files
import zipfile
# List contents
with zipfile.ZipFile('archive.zip', 'r') as zf:
print(zf.namelist())
# ['file1.txt', 'folder/file2.txt']
# Get info about a file
with zipfile.ZipFile('archive.zip', 'r') as zf:
info = zf.getinfo('file1.txt')
print(f"Size: {info.file_size}")
print(f"Compressed: {info.compress_size}")Extracting Files
import zipfile
# Extract all
with zipfile.ZipFile('archive.zip', 'r') as zf:
zf.extractall('output_dir')
# Extract single file
with zipfile.ZipFile('archive.zip', 'r') as zf:
zf.extract('file1.txt', 'output_dir')
# Read file without extracting
with zipfile.ZipFile('archive.zip', 'r') as zf:
content = zf.read('file1.txt')
print(content.decode('utf-8'))Creating ZIP Files
import zipfile
# Create new archive
with zipfile.ZipFile('new.zip', 'w') as zf:
zf.write('file1.txt')
zf.write('file2.txt')
# With compression
with zipfile.ZipFile('compressed.zip', 'w', zipfile.ZIP_DEFLATED) as zf:
zf.write('large_file.txt')
# Add with different archive name
with zipfile.ZipFile('archive.zip', 'w') as zf:
zf.write('local/path/file.txt', 'renamed.txt')Write String Content
import zipfile
with zipfile.ZipFile('archive.zip', 'w') as zf:
# Write string directly
zf.writestr('hello.txt', 'Hello, World!')
# Write bytes
zf.writestr('data.bin', b'\x00\x01\x02\x03')Append to Existing ZIP
import zipfile
with zipfile.ZipFile('existing.zip', 'a') as zf:
zf.write('new_file.txt')Compression Options
import zipfile
# No compression (fastest)
with zipfile.ZipFile('store.zip', 'w', zipfile.ZIP_STORED) as zf:
zf.write('file.txt')
# DEFLATE compression (default, good balance)
with zipfile.ZipFile('deflate.zip', 'w', zipfile.ZIP_DEFLATED) as zf:
zf.write('file.txt')
# BZIP2 (better compression, slower)
with zipfile.ZipFile('bzip2.zip', 'w', zipfile.ZIP_BZIP2) as zf:
zf.write('file.txt')
# LZMA (best compression, slowest)
with zipfile.ZipFile('lzma.zip', 'w', zipfile.ZIP_LZMA) as zf:
zf.write('file.txt')
# Per-file compression
with zipfile.ZipFile('mixed.zip', 'w') as zf:
zf.write('text.txt', compress_type=zipfile.ZIP_DEFLATED)
zf.write('image.png', compress_type=zipfile.ZIP_STORED)Password Protection
import zipfile
# Read password-protected ZIP
with zipfile.ZipFile('protected.zip', 'r') as zf:
zf.extractall(pwd=b'secretpassword')
# Note: zipfile can READ encrypted zips but cannot CREATE them
# Use pyminizip or pyzipper for creating encrypted archivesPractical Examples
Backup Directory
import zipfile
import os
from datetime import datetime
def backup_directory(source_dir, backup_dir):
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
zip_name = f"backup_{timestamp}.zip"
zip_path = os.path.join(backup_dir, zip_name)
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zf:
for root, dirs, files in os.walk(source_dir):
for file in files:
filepath = os.path.join(root, file)
arcname = os.path.relpath(filepath, source_dir)
zf.write(filepath, arcname)
return zip_path
backup_directory('./project', './backups')In-Memory ZIP
import zipfile
from io import BytesIO
# Create ZIP in memory
buffer = BytesIO()
with zipfile.ZipFile(buffer, 'w', zipfile.ZIP_DEFLATED) as zf:
zf.writestr('file1.txt', 'Content 1')
zf.writestr('file2.txt', 'Content 2')
# Get bytes for upload, response, etc.
zip_bytes = buffer.getvalue()Extract with Progress
import zipfile
import os
def extract_with_progress(zip_path, extract_to):
with zipfile.ZipFile(zip_path, 'r') as zf:
members = zf.namelist()
total = len(members)
for i, member in enumerate(members, 1):
zf.extract(member, extract_to)
print(f"\rExtracting: {i}/{total}", end='')
print("\nDone!")Verify ZIP Integrity
import zipfile
def verify_zip(zip_path):
try:
with zipfile.ZipFile(zip_path, 'r') as zf:
bad_file = zf.testzip()
if bad_file:
print(f"Corrupted file: {bad_file}")
return False
return True
except zipfile.BadZipFile:
print("Not a valid ZIP file")
return FalseSearch in ZIP
import zipfile
import re
def search_in_zip(zip_path, pattern):
matches = []
regex = re.compile(pattern)
with zipfile.ZipFile(zip_path, 'r') as zf:
for name in zf.namelist():
if name.endswith('/'): # Skip directories
continue
try:
content = zf.read(name).decode('utf-8')
if regex.search(content):
matches.append(name)
except UnicodeDecodeError:
pass # Skip binary files
return matchesZipInfo Object
import zipfile
from datetime import datetime
with zipfile.ZipFile('archive.zip', 'r') as zf:
for info in zf.infolist():
print(f"Name: {info.filename}")
print(f"Size: {info.file_size}")
print(f"Compressed: {info.compress_size}")
print(f"Date: {datetime(*info.date_time)}")
print(f"Is dir: {info.is_dir()}")
print()Quick Reference
import zipfile
# Open modes: 'r' read, 'w' write, 'a' append
with zipfile.ZipFile('file.zip', 'r') as zf:
zf.namelist() # List files
zf.getinfo(name) # Get ZipInfo
zf.infolist() # List ZipInfo objects
zf.read(name) # Read file bytes
zf.extract(name, path) # Extract one file
zf.extractall(path) # Extract all
zf.testzip() # Verify integrity
with zipfile.ZipFile('file.zip', 'w', zipfile.ZIP_DEFLATED) as zf:
zf.write(filepath) # Add file
zf.write(filepath, arcname) # Add with different name
zf.writestr(name, data) # Write string/bytes| Compression | Constant | Speed | Ratio |
|---|---|---|---|
| None | ZIP_STORED | Fastest | 1:1 |
| Deflate | ZIP_DEFLATED | Fast | Good |
| BZIP2 | ZIP_BZIP2 | Slow | Better |
| LZMA | ZIP_LZMA | Slowest | Best |
zipfile handles ZIP archives completely in Python. No need for system zip commands.
React to this post: