Last active
August 18, 2025 14:44
-
-
Save scivision/ad241e9cf0474e267240e196d7545eca to your computer and use it in GitHub Desktop.
Extract a .zst file in Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env -S uv run --script | |
| # /// script | |
| # requires-python = ">=3.9" | |
| # dependencies = ["zstandard; python_version < '3.14'"] | |
| # /// | |
| """ | |
| https://docs.python.org/3.14/library/compression.zstd.html#compression.zstd.ZstdFile | |
| """ | |
| from pathlib import Path | |
| import tempfile | |
| import tarfile | |
| import sys | |
| import shutil | |
| if sys.version_info >= (3, 14): | |
| from compression.zstd import ZstdFile | |
| else: | |
| from zstandard import ZstdDecompressor | |
| def extract_zstd(archive: Path, out_path: Path): | |
| """extract Zstandard .zst file | |
| works on Windows, Linux, MacOS, etc. | |
| Parameters | |
| ---------- | |
| archive: pathlib.Path or str | |
| .zst file to extract | |
| out_path: pathlib.Path or str | |
| directory to extract files and directories to | |
| """ | |
| archive = Path(archive).expanduser() | |
| out_path = Path(out_path).expanduser().resolve() | |
| # need .resolve() in case intermediate relative dir doesn't exist | |
| # we don't use the simpler "decompress" to allow arbitrarily large archives | |
| if sys.version_info >= (3, 14): | |
| with ZstdFile(archive, "rb") as f_in: | |
| with out_path.open("wb") as f_out: | |
| shutil.copyfileobj(f_in, f_out) | |
| else: | |
| _legacy_decompress_zstd_stream(archive, out_path) | |
| def _legacy_decompress_zstd_stream(archive: Path, out_path: Path) -> None: | |
| with tempfile.TemporaryFile(suffix=".tar") as ofh: | |
| with archive.open("rb") as ifh: | |
| ZstdDecompressor().copy_stream(ifh, ofh) | |
| ofh.seek(0) | |
| with tarfile.open(fileobj=ofh) as z: | |
| z.extractall(out_path) | |
| if __name__ == "__main__": | |
| extract_zstd(Path(sys.argv[1]), Path(sys.argv[2])) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks