'Getting the correct directory structure using Zipfile with Python

I have a directory structure that is like /level1/level2/level3/level4/level5 and in level5 I have .json files I want to replace with zipped up versions so from /level1/level2/level3/level4/level5/{file1.json, file2.json, file3.json} to /level1/level2/level3/level4/level5/{file1.zip, file2.zip, file3.zip}

However my code generates the zip files in the folder where the script is, which is level 3, resulting in /level1/level2/[level3]{file1.zip, file2.zip, file3.zip}/level4/level5/{file1.json, file2.json, file3.json}

In addition if I unzip the file I get the entire directory structure instead of just the file. For example if I unzip file1.zip I get /level1/level2/[level3]{(/level1/level2/level3/level4/level5/file1.json), file2.zip, file3.zip}/level4/level5/{file1.json, file2.json, file3.json}

I've tried different arguments but I'm not sure how to get the result I want. How can I accomplish this?

This is my code currently

        path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            level4, level5)

        for root, dirs, files in os.walk(path, topdown=True):
            print('This is root: ', root)
            for file in files:
                zf = zipfile.ZipFile(
                    '{}.zip'.format(file[:-5]), 'w',
                    zipfile.ZIP_DEFLATED)
                zf.write(os.path.join(root, file))
                zf.close()


Solution 1:[1]

You should create the zip file with the root path joined so that the zip file will be created where the JSON file is, and when writing the JSON file into the zip file, use the writestr method instead of write so that you can name the file with the path name you want, which in this case is just the file name with no path name at all:

for root, dirs, files in os.walk(path, topdown=True):
    print('This is root: ', root)
    for file in files:
        zf = zipfile.ZipFile(os.path.join(root, '{}.zip'.format(file[:-5])), 'w', zipfile.ZIP_DEFLATED)
        zf.writestr(file, open(os.path.join(root, file)).read())
        zf.close()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 blhsing