Compress multiple folders containing files into one zip using python

48 Views Asked by At

I'm having a folder structure like this

Parent folder
   Folder1 
     1.txt
     2.msg
     ...
   Folder2
     1.txt
     2.py
     ...

My current approach is using shutil.make_archive I'm compressing the parent folder (eg: 13_03_2024.zip).
Problem is when extracting its showing Parent folder >> folder1,folder2 Expected is only folder1, folder2

Could someone please help me with this. Thanks in advance!!

2

There are 2 best solutions below

3
Wera On

I manually created 'test' directory in my Downloads folder and add your structure.

import shutil

shutil.make_archive(
    base_name =  '13_03_2024',
    format    =  'zip',
    root_dir  =  'test/', 
    base_dir  =  '.'
)

After running this code I extracted it successfully by selecting "Extract here..." - no parent folder

enter image description here

Also can be extracted by shutil:

import shutil
shutil.unpack_archive(
    filename    = '13_03_2024.zip',
    extract_dir = '.',
    format      = 'zip')

enter image description here

0
Rogan 21 On
import glob
import os
import zipfile


def remove_parent_path(parent_path, file_path):
    # Get the relative path of the file_path with respect to the parent_path
    relative_path = os.path.relpath(file_path, parent_path)
    return relative_path


def compress_to(parent_path, out_file_path, structured_files=None, include_parent_dir=False):
    with zipfile.ZipFile(out_file_path, 'w') as zipf:
        for file in structured_files:
            if not include_parent_dir:
                zip_archive_name = remove_parent_path(parent_path, file)
            else:
                zip_archive_name = file
                zipf.write(file, zip_archive_name)

if __name__ == '__main__':
    parent_dir = 'out'
    files_with_sub_dir = os.path.join(parent_dir, '*', '*.*')
    out_file_path = 'sample.zip'`enter code here`
    files_list = glob.glob(files_with_sub_dir, recursive=True)
    compress_to(parent_dir, out_file_path, files_list, include_parent_dir=True)