Alex P.
Alex P.

Reputation: 3787

Stop shutil.make_archive adding archive to itself

I have App dir inside Release dir

$ cd Release
$ tree
.
`-- App
    |-- App.exe
    ..........

and I am trying to create App-1.0.zip in the Release dir containg App with all its content. That is after unpacking App-1.0.zip I would get this App dir.

I tried shutil.make_archive but when I do this

import shutil

shutil.make_archive('App-1.0', 'zip', '.')

from Release dir, I get 48 byte App-1.0.zip inside App-1.0.zip besides the App dir. That is it adds this unfinished archive to itself.

Is there any way to avoid that except creating the archive in temp dir and moving?

I tried to set base_dir and use App as root_dir

shutil.make_archive('App-1.0', 'zip', 'App', 'App')

but I get error that App is not found when I set base_dir.

Traceback (most recent call last):
  File ".......archive.py", line 4, in <module>
    shutil.make_archive('App-1.0', 'zip', 'App', 'App')
  File "C:\Users\Alex\.virtualenvs\....-nAKWzegL\lib\shutil.py", line 800, in make_archive
    filename = func(base_name, base_dir, **kwargs)
  File "C:\Users\Alex\.virtualenvs\....-nAKWzegL\lib\shutil.py", line 686, in _make_zipfile
    zf.write(path, path)
  File "C:\Users\Alex\AppData\Local\Programs\Python\Python36-32\Lib\zipfile.py", line 1594, in write
    zinfo = ZipInfo.from_file(filename, arcname)
  File "C:\Users\Alex\AppData\Local\Programs\Python\Python36-32\Lib\zipfile.py", line 484, in from_file
    st = os.stat(filename)
FileNotFoundError: [WinError 2] The system cannot find the file specified: "'App'"

The same for '/App' and './App'. With full path it works, but I get all parent dirs, not just App.

Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32

Upvotes: 6

Views: 3856

Answers (3)

Vishal Kharde
Vishal Kharde

Reputation: 1727

You can try creating the archive in a temporary directory and then moving it to the desired output directory. Following solution worked for me:

import os
import shutil
import tempfile

def create_zip(output_directory, zip_filename):
    try:
        # Create a temporary directory
        temp_dir = tempfile.mkdtemp()

        # Create the archive in the temporary directory
        temp_archive_path = os.path.join(temp_dir, f"{zip_filename}.zip")
        shutil.make_archive(temp_archive_path, 'zip', output_directory)

        # Move the archive from the temporary directory to the output directory
        final_archive_path = os.path.join(output_directory, f"{zip_filename}.zip")
        shutil.move(temp_archive_path, final_archive_path)

        # Clean up the temporary directory
        shutil.rmtree(temp_dir)

        return True
    except Exception as e:
        print(f"Error while creating zip file: {e}")
        return False

Upvotes: 0

USMCBacklash
USMCBacklash

Reputation: 21

What I learned while fighting with this is this:

shutil.make_archive('App-1.0', 'zip', '.', 'App')

While 'App-1.0' is technically a "filename", it must be represented as a path to the file without the extension ('c:\myfiles\myzipfile'). I have not played with all the variants for path names yet, so some of the shortcuts likely work (such as: 'Release/App-1.0').

Upvotes: 2

ekhumoro
ekhumoro

Reputation: 120608

Here's a couple of solutions that worked or me:

# curdir: Release
shutil.make_archive('App-1.0', 'zip', '.', 'App')

# curdir: ../Release
shutil.make_archive('Release/App-1.0', 'zip', 'Release', 'App')

Upvotes: 4

Related Questions