Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: How to use shutil.make_archive?

Tags:

python

zip

shutil

I can't figure out how to use shutil.make_archive to zip a folder into a zip-file and then put that saved_20170721.zip file into the folder named past_data

I have the code:

from shutil   import make_archive
from datetime import datetime

folderpath_to_zip_up = 'c:\my_work\todays_data'                    # I wanna zip up this folder
folderpath_archive   = 'c:\past_data'                              # And put it into here as file
filename             = 'saved_{:%Y-%m-%d}'.format(datetime.now())    

make_archive(filename, 'zip', folderpath_archive, folderpath_to_zip_up)

My goal is for 'c:\past_data' to look like:

past_data---+ saved_20170721.zip
            + saved_20170722.zip
            + saved_20170723.zip
            + saved_20170724.zip

But I can't understand the documentation and I keep getting weird results.

like image 298
user1367204 Avatar asked Mar 09 '23 13:03

user1367204


2 Answers

I ran into this same issue and found the docs for shutil.make_archive very dense and counter intuitive.

I eventually got it and wrote a function to help me out because I could never get it right the first time.

import os, shutil
def make_archive(source, destination):
        base = os.path.basename(destination)
        name = base.split('.')[0]
        format = base.split('.')[1]
        archive_from = os.path.dirname(source)
        archive_to = os.path.basename(source.strip(os.sep))
        shutil.make_archive(name, format, archive_from, archive_to)
        shutil.move('%s.%s'%(name,format), destination)

make_archive('/path/to/folder', '/path/to/folder.zip')

Hope it helps.. I also have a blog post about it here

http://www.seanbehan.com/how-to-use-python-shutil-make_archive-to-zip-up-a-directory-recursively-including-the-root-folder/

like image 116
seanbehan Avatar answered Mar 25 '23 01:03

seanbehan


The docs are not worded helpfully. If we go from the usage shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]])

  • base_name is the path where you want the archive to be created, including the filename, but not including the extension
  • format, as you figured out, is the type of archive you want to create

You might have noticed that everything else is optional. With just those two parameters, the function will create an archive of your current working directory. That's not what you want, so let's check out the next two parameters:

  • root_dir is the directory from which you want to create an archive
  • base_dir is a way to filter the contents of root_dir. if you set base_dir, your archive will contain the parent directories of base_dir going up to root_dir, but all other contents of those parent directories will not be present. Only base_dir and its children will contain all their contents.

Since you're just trying to archive your directory as is, you don't need base_dir. So I would just amend your original call to:

import os
#...
make_archive(os.path.join(folderpath_archive, filename), 'zip', folderpath_to_zip_up)
like image 38
ibadibam Avatar answered Mar 25 '23 03:03

ibadibam