Package: zipgen
zipgenZipgen is a simple and performant cross-platform zip archive generator for
Python 3.7 and later. It supports ZIP64, uncompressed and various compression
formats such as: Deflated, Bzip and LZMA.Zipgen supports synchronous asynchronous generation. Zipgen can zip archives
from stream objects such as FileIO, BytesIO, generators and asynchronous
StreamReader.Zipgen also supports recursive creation of zip archives from existing folders.
Synchronously or asynchronously.Zip archives can be created using the ZipBuilder and ZipStreamWriter classes.
ZipBuilder provides methods that return byte generators.The ZipStreamWriter class can be used to write directly to streams and to
asynchronous streams, which provide a wait drain() method, such as
asyncio.StreamWriter. ZipStreamWriter uses ZipBuilder internally providing all
of the same methods.Installpython -m pip install zipgenCommandZipgen can also be used as a command:python -m zipgen dest.zip file1.txt file2.py ./folder/imagespython -m zipgen dest.zip . --comp 8 --comment "working directory deflate compressed"python -m zipgen - project/src --dest-stdout > src.zipThe command supports adding several files or folders at once recursively with
various or compressions or without any compression. It also supports verbose
logging that can be disabled.Command argsdestDestination file. Always first argument.--dest-stdoutSets dest output to stdout. The first argument dest will be ignored.--pathInternal dest folder in zip.--no-ipfDo not include parent folder for directories.--commentComment of the zip file.--bufRead buffer size.--compCompression format. 0 = STORED, 8 = DEFLATED, 12 = BZIP2 and 14 = LZMA.-qSets verbose mode off.Comparsion to other zip commandsZipgen:7z:Zip:Results:Sync ZipStreamWriter Exampleimportioimportzipgendefcreate_sync()->None:# ZipStreamWriter provides more practical interface using ZipBuilder# And it has has all the methods from ZipBuilder.# Do not call ZipStreamWriter.end() if with clause is usedwith(open("stream_sync.zip","wb+")asf,zipgen.ZipStreamWriter(f)aszsw,):# Add folders, library corrects path to correct formatzsw.add_folder("hello/world")zsw.add_folder("hello/from/stream")zsw.add_folder("//hello\\from//path/correcting")# => hello/from/path/correcting# Add three buffers, default compression is COMPRESSION_STOREDzsw.add_buf("buf/buf1.txt",b"hello from buf1!")zsw.add_buf("buf/buf2.txt",bytearray(b"hello from buf2!"))zsw.add_buf("buf/buf3.txt",memoryview(b"hello from buf3!"))# Add selfzsw.add_io("self.py",open(__file__,"rb"),compression=zipgen.COMPRESSION_DEFLATED)# Add BytesIOzsw.add_io("BytesIO.txt",io.BytesIO(b"hello from BytesIO!"),compression=zipgen.COMPRESSION_BZIP2)# Add generatordefdata_gen():foriinrange(1,100):yieldf"hello from line{i}\n".encode()zsw.add_gen("generator.txt",data_gen(),compression=zipgen.COMPRESSION_LZMA)# Walk fileszsw.walk("../src","zipgen/src",compression=zipgen.COMPRESSION_DEFLATED)# Set commentzsw.set_comment("created by stream_sync.py")if__name__=='__main__':create_sync()Async ZipStreamWriter Exampleimportasyncioimportzipgenasyncdefcreate_async()->None:# Async methods end with suffix _async# ZipStreamWriter supports regular Streams and asyncio.StreamWriter# If stream provides awaitable .drain() method such as asyncio.StreamWriter, it will be awaited after each write.# Do not call ZipStreamWriter.end() if with clause is usedwith(open("stream_async.zip","wb+")asf,zipgen.ZipStreamWriter(f)aszsw,):# Add folders, library corrects path to correct formatawaitzsw.add_folder_async("hello/world")awaitzsw.add_folder_async("hello/from/stream")awaitzsw.add_folder_async("//hello\\from//path/correcting")# => hello/from/path/correcting# Add selfawaitzsw.add_io_async("self.py",open(__file__,"rb"),compression=zipgen.COMPRESSION_DEFLATED)# Add async generatorasyncdefdata_gen():foriinrange(1,100):awaitasyncio.sleep(0)yieldf"hello from line{i}\n".encode()awaitzsw.add_gen_async("generator.txt",data_gen(),compression=zipgen.COMPRESSION_LZMA)# Walk filesawaitzsw.walk_async("../src","zipgen/src",compression=zipgen.COMPRESSION_DEFLATED)# Pipe process stdoutproc=awaitasyncio.subprocess.create_subprocess_exec("echo","hello from subprocess",stdout=asyncio.subprocess.PIPE,)ifproc.stdoutisnotNone:awaitzsw.add_stream_async("echo.txt",proc.stdout)# Set commentzsw.set_comment("created by stream_async.py")if__name__=='__main__':asyncio.run(create_async())Sync ZipBuilder Exampleimportioimportzipgendefcreate_sync()->None:# Creates builder_sync.zip synchronously using ZipBuilder.# For asynchronous methods use methods with "_async" suffix.b=zipgen.ZipBuilder()withopen("builder_sync.zip","wb+")asfile:# Add folders, library corrects path to correct formatfile.write(b.add_folder("hello/world"))file.write(b.add_folder("hello/from/stream"))file.write(b.add_folder("//hello\\from//path/correcting"))# => hello/from/path/correcting# Add three buffers, default compression is COMPRESSION_STOREDforbufinb.add_buf("buf/buf1.txt",b"hello from buf1!"):file.write(buf)forbufinb.add_buf("buf/buf2.txt",bytearray(b"hello from buf2!")):file.write(buf)forbufinb.add_buf("buf/buf3.txt",memoryview(b"hello from buf3!")):file.write(buf)# Add selfforbufinb.add_io("self.py",open(__file__,"rb"),compression=zipgen.COMPRESSION_DEFLATED):file.write(buf)# Add BytesIOforbufinb.add_io("BytesIO.txt",io.BytesIO(b"hello from BytesIO!"),compression=zipgen.COMPRESSION_BZIP2):file.write(buf)# Add generatordefdata_gen():foriinrange(1,100):yieldf"hello from line{i}\n".encode()forbufinb.add_gen("generator.txt",data_gen(),compression=zipgen.COMPRESSION_LZMA):file.write(buf)# Walk filesforbufinb.walk("../src","zipgen/src",compression=zipgen.COMPRESSION_DEFLATED):file.write(buf)# Set commentfile.write(b.end("created by builder_sync.py"))if__name__=="__main__":create_sync()Async ZipBuilder Exampleimportasyncioimportzipgenasyncdefcreate_async()->None:# Creates builder_sync.zip asynchronously using ZipBuilder.# For synchronous methods use methods withour "_async" suffix.b=zipgen.ZipBuilder()withopen("builder_async.zip","wb+")asfile:# Add selfasyncforbufinb.add_io_async("self.py",open(__file__,"rb"),compression=zipgen.COMPRESSION_DEFLATED):file.write(buf)# Add async generatorasyncdefdata_gen():foriinrange(1,100):awaitasyncio.sleep(0)yieldf"hello from line{i}\n".encode()asyncforbufinb.add_gen_async("generator.txt",data_gen(),compression=zipgen.COMPRESSION_LZMA):file.write(buf)# Walk filesasyncforbufinb.walk_async("../src","zipgen/src",compression=zipgen.COMPRESSION_DEFLATED):file.write(buf)# Pipe process stdoutproc=awaitasyncio.subprocess.create_subprocess_exec("echo","hello from subprocess",stdout=asyncio.subprocess.PIPE,)ifproc.stdoutisnotNone:asyncforbufinb.add_stream_async("echo.txt",proc.stdout):file.write(buf)# Set commentfile.write(b.end("created by builder_async.py"))if__name__=='__main__':asyncio.run(create_async())