Jake Dube
Jake Dube

Reputation: 2980

Zip File with Python Shutil like File Explorer

Background

I am trying to zip a directory with python shutil like this:

shutil.make_archive("~/Desktop/zipfile", 'zip', "~/Documents/foldertozip")

but the result only zips the files inside "foldertozip". So for instance,

foldertozip
    -- file1
    -- file2
zipfile.zip
    -- file1
    -- file2

On the other hand, if I zip it from windows file explorer or mac finder, I get the following:

foldertozip
    -- file1
    -- file2
zipfile.zip
    -- foldertozip
        -- file1
        -- file2

Question

How can I use shutil to do the same thing that I could do from a file explorer and include the base directory? I know I could copy "foldertozip" to a folder with the same name and then zip that folder, but I would prefer a cleaner solution if at all possible.

Upvotes: 3

Views: 10600

Answers (2)

mkarts
mkarts

Reputation: 677

From the documentation of make_archive:

shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]])

Create an archive file (eg. zip or tar) and returns its name.

base_name is the name of the file to create, including the path, minus any format-specific extension. format is the archive format: one of “zip”, “tar”, “bztar” or “gztar”.

root_dir is a directory that will be the root directory of the archive; ie. we typically chdir into root_dir before creating the archive.

base_dir is the directory where we start archiving from; ie. base_dir will be the common prefix of all files and directories in the archive.

If I understand the question correctly, you need to have base_dir equal to "foldertozip" and root_dir equal to the parent directory of "foldertozip".

Suppose foldertozip is under "Documents"

So something like this should work:

shutil.make_archive("~/Documents/zipfile", "zip", "~/Documents/", "foldertozip") 

Let us know if this works as expected for you!

Upvotes: 2

Greg Sadetsky
Greg Sadetsky

Reputation: 5082

make_archive will do what you want if you pass both root_dir and base_dir. See the docs.

import shutil

shutil.make_archive('~/Desktop/zipfile', 'zip', '~/Documents/', 'foldertozip')

Upvotes: 6

Related Questions